diff --git a/src/components/Expenses/ManageExpense.jsx b/src/components/Expenses/ManageExpense.jsx index 8963fdc4..11ea0999 100644 --- a/src/components/Expenses/ManageExpense.jsx +++ b/src/components/Expenses/ManageExpense.jsx @@ -165,7 +165,7 @@ const ManageExpense = ({ closeModal, expenseToEdit = null }) => { amount: data.amount || "", noOfPersons: data.noOfPersons || "", gstNumber: data.gstNumber || "", - currencyId: data.currencyId || DEFAULT_CURRENCY, + currencyId: data.currency.id || DEFAULT_CURRENCY, billAttachments: data.documents ? data.documents.map((doc) => ({ fileName: doc.fileName, diff --git a/src/components/RecurringExpense/RecurringExpenseList.jsx b/src/components/RecurringExpense/RecurringExpenseList.jsx index 2b966b6a..aa039448 100644 --- a/src/components/RecurringExpense/RecurringExpenseList.jsx +++ b/src/components/RecurringExpense/RecurringExpenseList.jsx @@ -16,11 +16,13 @@ import Error from "../common/Error"; import { useRecurringExpenseContext } from "../../pages/RecurringExpense/RecurringExpensePage"; import { useRecurringExpenseList } from "../../hooks/useExpense"; import Pagination from "../common/Pagination"; +import { SpinnerLoader } from "../common/Loader"; const RecurringExpenseList = ({ search, filterStatuses }) => { - const { setManageRequest, setVieRequest, setViewRecurring } = useRecurringExpenseContext(); + const { setManageRequest, setVieRequest, setViewRecurring } = + useRecurringExpenseContext(); const navigate = useNavigate(); - const [IsDeleteModalOpen, setIsDeleteModalOpen,] = useState(false); + const [IsDeleteModalOpen, setIsDeleteModalOpen] = useState(false); const [deletingId, setDeletingId] = useState(null); const SelfId = useSelector( @@ -28,10 +30,10 @@ const RecurringExpenseList = ({ search, filterStatuses }) => { ); const statusColorMap = { - "da462422-13b2-45cc-a175-910a225f6fc8": "primary", // Active - "306856fb-5655-42eb-bf8b-808bb5e84725": "success", // Completed - "3ec864d2-8bf5-42fb-ba70-5090301dd816": "danger", // De-Activated - "8bfc9346-e092-4a80-acbf-515ae1ef6868": "warning", // Paused + "da462422-13b2-45cc-a175-910a225f6fc8": "primary", // Active + "306856fb-5655-42eb-bf8b-808bb5e84725": "success", // Completed + "3ec864d2-8bf5-42fb-ba70-5090301dd816": "danger", // De-Activated + "8bfc9346-e092-4a80-acbf-515ae1ef6868": "warning", // Paused }; const recurringExpenseColumns = [ @@ -68,7 +70,9 @@ const RecurringExpenseList = ({ search, filterStatuses }) => { align: "text-end", getValue: (e) => e?.amount - ? `${e?.currency?.symbol ? e.currency.symbol + " " : ""}${e.amount.toLocaleString()}` + ? `${ + e?.currency?.symbol ? e.currency.symbol + " " : "" + }${e.amount.toLocaleString()}` : "N/A", }, { @@ -108,7 +112,6 @@ const RecurringExpenseList = ({ search, filterStatuses }) => { debouncedSearch ); - const paginate = (page) => { if (page >= 1 && page <= (data?.totalPages ?? 1)) { setCurrentPage(page); @@ -178,108 +181,116 @@ const RecurringExpenseList = ({ search, filterStatuses }) => { /> )} -
+
- - - - {recurringExpenseColumns.map((col) => ( - - ))} - - - - - - {filteredData?.length > 0 ? ( - filteredData?.map((recurringExpense) => ( - - {recurringExpenseColumns.map((col) => ( - - ))} - - - )) - ) : ( + {Array.isArray(filteredData) && filteredData.length > 0 && ( +
- {col.label} - Action
- {col?.customRender - ? col?.customRender(recurringExpense) - : col?.getValue(recurringExpense)} - -
- - setViewRecurring({ - recurringId: recurringExpense?.id, - view: true, - }) - } - > - -
- -
    -
  • - setManageRequest({ - IsOpen: true, - RecurringId: recurringExpense?.id, - }) - } - > - - - Modify - -
  • - -
  • { - setIsDeleteModalOpen(true); - setDeletingId(recurringExpense.id); - }} - > - - - Delete - -
  • -
-
-
-
+ - + {recurringExpenseColumns.map((col) => ( + + ))} + - )} - -
-

No Recurring Expense Found

-
+ {col.label} + Action
+ + + + {filteredData?.length > 0 ? ( + filteredData?.map((recurringExpense) => ( + + {recurringExpenseColumns.map((col) => ( + + {col?.customRender + ? col?.customRender(recurringExpense) + : col?.getValue(recurringExpense)} + + ))} + +
+ + setViewRecurring({ + recurringId: recurringExpense?.id, + view: true, + }) + } + > + +
+ +
    +
  • + setManageRequest({ + IsOpen: true, + RecurringId: recurringExpense?.id, + }) + } + > + + + Modify + +
  • + +
  • { + setIsDeleteModalOpen(true); + setDeletingId(recurringExpense.id); + }} + > + + + Delete + +
  • +
+
+
+ + + )) + ) : ( + + + + )} + + + )} + {!filteredData || + filteredData.length === 0 + && ( +
+ {isError ? (

{error.message}

):(

No Recurring Expense Found

)} +
+ )}
{/* Pagination */}
diff --git a/src/hooks/useAuth.jsx b/src/hooks/useAuth.jsx index a5f0731d..e88f3e47 100644 --- a/src/hooks/useAuth.jsx +++ b/src/hooks/useAuth.jsx @@ -147,32 +147,36 @@ export const useAuthModal = () => { export const useLogout = () => { const queryClient = useQueryClient(); - const naviget = useNavigate(); + const navigate = useNavigate(); const dispatch = useDispatch(); return useMutation({ mutationFn: async () => { - let payload = { - refreshToken: - localStorage.getItem("refreshToken") || - sessionStorage.getItem("refreshToken"), - }; - return await AuthRepository.logout(payload); + const refreshToken = + localStorage.getItem("refreshToken") || + sessionStorage.getItem("refreshToken"); + + if (!refreshToken) return; // no call if already removed + + return await AuthRepository.logout({ refreshToken }); }, - onSuccess: (data) => { + onMutate: async () => { + // Cancel all ongoing queries + await queryClient.cancelQueries(); + }, + + onSuccess: () => { queryClient.clear(); removeSession(); dispatch(cacheProfileData(null)); - - // window.location.href = "/auth/login"; - naviget("/auth/login", { replace: true }); - if (onSuccessCallBack) onSuccessCallBack(); + navigate("/auth/login", { replace: true }); }, - onError: (error) => { - showToast(error.message || "Error while creating project", "error"); + onError: () => { removeSession(); + queryClient.clear(); + navigate("/auth/login", { replace: true }); }, }); }; diff --git a/src/pages/RecurringExpense/RecurringExpensePage.jsx b/src/pages/RecurringExpense/RecurringExpensePage.jsx index cffccaec..f7b36dd6 100644 --- a/src/pages/RecurringExpense/RecurringExpensePage.jsx +++ b/src/pages/RecurringExpense/RecurringExpensePage.jsx @@ -10,156 +10,159 @@ import ViewRecurringExpense from "../../components/RecurringExpense/ViewRecurrin export const RecurringExpenseContext = createContext(); export const useRecurringExpenseContext = () => { - const context = useContext(RecurringExpenseContext); - if (!context) { - throw new Error("useRecurringExpenseContext must be used within an ExpenseProvider"); - } - return context; + const context = useContext(RecurringExpenseContext); + if (!context) { + throw new Error( + "useRecurringExpenseContext must be used within an ExpenseProvider" + ); + } + return context; }; const RecurringExpensePage = () => { - const [ManageRequest, setManageRequest] = useState({ - IsOpen: null, - RecurringId: null, - }); - const [viewRecurring, setViewRecurring] = useState({ view: false, recurringId: null }) + const [ManageRequest, setManageRequest] = useState({ + IsOpen: null, + RecurringId: null, + }); + const [viewRecurring, setViewRecurring] = useState({ + view: false, + recurringId: null, + }); - const [selectedStatuses, setSelectedStatuses] = useState( - PAYEE_RECURRING_EXPENSE.map((s) => s.id) + const [selectedStatuses, setSelectedStatuses] = useState( + PAYEE_RECURRING_EXPENSE.map((s) => s.id) + ); + + const [search, setSearch] = useState(""); + + const contextValue = { + setManageRequest, + setViewRecurring, + }; + + const handleStatusChange = (id) => { + setSelectedStatuses((prev) => + prev.includes(id) ? prev.filter((s) => s !== id) : [...prev, id] ); + }; + return ( + +
+ {/* Breadcrumb */} + - const [search, setSearch] = useState(""); + {/* Top Bar */} +
+
+
+ {/* Left Column: Search + Filter */} +
+
+ setSearch(e.target.value)} + /> - const contextValue = { - setManageRequest, - setViewRecurring - }; - - const handleStatusChange = (id) => { - setSelectedStatuses((prev) => - prev.includes(id) - ? prev.filter((s) => s !== id) - : [...prev, id] - ); - }; - return ( - -
- {/* Breadcrumb */} - - - {/* Top Bar */} -
-
-
- {/* Left Column: Search + Filter */} -
-
- setSearch(e.target.value)} - /> - -
- -
    - {PAYEE_RECURRING_EXPENSE.map(({ id, label }) => ( -
  • -
    - handleStatusChange(id)} - /> - -
    -
  • - ))} -
-
-
-
- - {/* Right Column: Add Button */} -
- -
-
- -
+
+ +
    + {PAYEE_RECURRING_EXPENSE.map(({ id, label }) => ( +
  • +
    + handleStatusChange(id)} + /> + +
    +
  • + ))} +
+
+
- + {/* Right Column: Add Button */} +
+ +
+
+
+
- {ManageRequest.IsOpen && ( - - setManageRequest({ IsOpen: null, expenseId: null }) - } - > - - setManageRequest({ IsOpen: null, RecurringId: null }) - } - requestToEdit={ManageRequest.RecurringId} - /> - - )} - {viewRecurring.view && ( - - setViewRecurring({ IsOpen: null, recurringId: null }) - } - > - {/* + + {ManageRequest.IsOpen && ( + + setManageRequest({ IsOpen: null, expenseId: null }) + } + > + + setManageRequest({ IsOpen: null, RecurringId: null }) + } + requestToEdit={ManageRequest.RecurringId} + /> + + )} + {viewRecurring.view && ( + + setViewRecurring({ IsOpen: null, recurringId: null }) + } + > + {/* setViewRecurring({ IsOpen: null, recurringId: null }) } RecurringId={viewRecurring.recurringId} /> */} - - - )} - - -
- - ); + + + )} +
+ + ); }; export default RecurringExpensePage;