From 2ab2a1d8bd801aabefab8379bd15e92d5744acde Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Tue, 22 Jul 2025 14:39:49 +0530 Subject: [PATCH 1/2] made new hook for make action on give employee --- src/components/Expenses/ExpenseList.jsx | 2 +- src/components/Expenses/ExpenseSchema.js | 5 +++ src/hooks/useExpense.js | 43 ++++++++++-------------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/src/components/Expenses/ExpenseList.jsx b/src/components/Expenses/ExpenseList.jsx index 32463732..4476dbad 100644 --- a/src/components/Expenses/ExpenseList.jsx +++ b/src/components/Expenses/ExpenseList.jsx @@ -168,7 +168,7 @@ const ExpenseList = () => { - {expense.amount} + {expense.amount} { } }); }; + +export const ActionSchema = z.object({ + comment : z.string().min(1,{message:"Please leave comment"}), + selectedStatus: z.string().min(1, { message: "Please select a status" }), +}) \ No newline at end of file diff --git a/src/hooks/useExpense.js b/src/hooks/useExpense.js index edaa1a95..bc0396c3 100644 --- a/src/hooks/useExpense.js +++ b/src/hooks/useExpense.js @@ -24,8 +24,6 @@ export const useExpense =(ExpenseId)=>{ } - - // ---------------------------Mutation--------------------------------------------- export const useCreateExpnse =(onSuccessCallBack)=>{ @@ -40,29 +38,24 @@ export const useCreateExpnse =(onSuccessCallBack)=>{ if (onSuccessCallBack) onSuccessCallBack(); }, onError:(error)=>{ - showToast(error.message || "Something went wrong please try again !","success") + showToast(error.message || "Something went wrong please try again !","error") + } + }) +} + +export const useActionOnExpense=(onSuccessCallBack)=>{ + const queryClient = useQueryClient() + return useMutation({ + mutationFn: async(payload)=>{ + await ExpenseRepository.ActionOnExpense(payload) + }, + onSuccess:(data,variables)=>{ + console.log(data) + showToast("Expense Created Successfully","success") + if (onSuccessCallBack) onSuccessCallBack(); + }, + onError:(error)=>{ + showToast(error.message || "Something went wrong please try again !","error") } }) } -const demoExpense = { - projectId: "proj_123", - expensesTypeId: "1", // corresponds to Travel - paymentModeId: "pm_456", - paidById: "emp_789", - transactionDate: "2025-07-21", - transactionId: "TXN-001234", - description: "Taxi fare from airport to hotel", - location: "New York", - supplerName: "City Taxi Service", - amount: 45.50, - noOfPersons: 2, - billAttachments: [ - { - fileName: "receipt.pdf", - base64Data: "JVBERi0xLjQKJcfs...", // truncated base64 example string - contentType: "application/pdf", - fileSize: 450000, // less than 5MB - description: "Taxi receipt", - }, - ], -}; -- 2.43.0 From 280715d62f5a6bdd0aaed31e93de21d31361be0d Mon Sep 17 00:00:00 2001 From: pramod mahajan Date: Tue, 22 Jul 2025 17:20:08 +0530 Subject: [PATCH 2/2] Added taking action on expense, like Review, Approve ... --- src/components/Expenses/CreateExpense.jsx | 5 + src/components/Expenses/ExpenseList.jsx | 39 +++++-- src/hooks/useExpense.js | 124 +++++++++++++--------- 3 files changed, 109 insertions(+), 59 deletions(-) diff --git a/src/components/Expenses/CreateExpense.jsx b/src/components/Expenses/CreateExpense.jsx index 0ed1b119..cddc79dd 100644 --- a/src/components/Expenses/CreateExpense.jsx +++ b/src/components/Expenses/CreateExpense.jsx @@ -254,6 +254,11 @@ const CreateExpense = ({closeModal}) => { )) )} + {errors.paidById && ( + + {errors.paidById.message} + + )} diff --git a/src/components/Expenses/ExpenseList.jsx b/src/components/Expenses/ExpenseList.jsx index 4476dbad..2ac606e5 100644 --- a/src/components/Expenses/ExpenseList.jsx +++ b/src/components/Expenses/ExpenseList.jsx @@ -19,9 +19,10 @@ const ExpenseList = () => { startDate: null, endDate: null, }; + - const { data, isLoading, isError } = useExpenseList(ITEMS_PER_PAGE, currentPage, filter); - if (isLoading) return
Loading...
; + const { data, isLoading, isError,isInitialLoading } = useExpenseList(2, currentPage, filter); + if (isInitialLoading) return
Loading...
; const items = data.data ?? []; const totalPages = data?.totalPages ?? 1; const hasMore = currentPage < totalPages; @@ -37,12 +38,13 @@ const ExpenseList = () => {
@@ -131,7 +133,7 @@ const ExpenseList = () => { )} - {!isLoading && items.length === 0 && ( + {!isInitialLoading && items.length === 0 && ( )} - {!isLoading && + {!isInitialLoading && items.map((expense) => ( - ))}
No expenses found. @@ -139,12 +141,12 @@ const ExpenseList = () => {
- {formatUTCToLocalTime(expense.createdAt)} + {formatUTCToLocalTime(expense.transactionDate)}
@@ -183,22 +185,37 @@ const ExpenseList = () => { {expense.status?.name || "Unknown"} - +
+ setViewExpense({ expenseId: expense, view: true }) } > - + + + + + + + + +
- {!isLoading && items.length > 0 && ( + {!isInitialLoading && items.length > 0 && ( { - -return useQuery({ +export const useExpenseList = (pageSize, pageNumber, filter) => { + return useQuery({ queryKey: ["expenses", pageNumber, pageSize, filter], - queryFn: async() => - await ExpenseRepository.GetExpenseList( pageSize, pageNumber, filter ).then((res) => res.data), + queryFn: async () => + await ExpenseRepository.GetExpenseList(pageSize, pageNumber, filter).then( + (res) => res.data + ), keepPreviousData: true, }); -} - -export const useExpense =(ExpenseId)=>{ - return useQuery({ - queryKey:["Expense",ExpenseId], - queryFn:async()=>await ExpenseRepository.GetExpenseDetails(ExpenseId) - }) -} +}; +export const useExpense = (ExpenseId) => { + return useQuery({ + queryKey: ["Expense", ExpenseId], + queryFn: async () => await ExpenseRepository.GetExpenseDetails(ExpenseId), + }); +}; // ---------------------------Mutation--------------------------------------------- -export const useCreateExpnse =(onSuccessCallBack)=>{ - const queryClient = useQueryClient() - return useMutation({ - mutationFn: async(payload)=>{ - await ExpenseRepository.CreateExpense(payload) - }, - onSuccess:(_,variables)=>{ - showToast("Expense Created Successfully","success") - queryClient.invalidateQueries({queryKey:["expenses"]}) - if (onSuccessCallBack) onSuccessCallBack(); - }, - onError:(error)=>{ - showToast(error.message || "Something went wrong please try again !","error") - } - }) -} +export const useCreateExpnse = (onSuccessCallBack) => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: async (payload) => { + await ExpenseRepository.CreateExpense(payload); + }, + onSuccess: (_, variables) => { + showToast("Expense Created Successfully", "success"); + queryClient.invalidateQueries({ queryKey: ["expenses"] }); + if (onSuccessCallBack) onSuccessCallBack(); + }, + onError: (error) => { + showToast( + error.message || "Something went wrong please try again !", + "error" + ); + }, + }); +}; -export const useActionOnExpense=(onSuccessCallBack)=>{ - const queryClient = useQueryClient() - return useMutation({ - mutationFn: async(payload)=>{ - await ExpenseRepository.ActionOnExpense(payload) +export const useActionOnExpense = (onSuccessCallBack) => { + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async (payload) => { + const response = await ExpenseRepository.ActionOnExpense(payload); + return response.data; + }, + onSuccess: (updatedExpense, variables) => { + showToast("Expense updated successfully", "success"); + + queryClient.setQueriesData( + { + queryKey: ["expenses"], + exact: false, }, - onSuccess:(data,variables)=>{ - console.log(data) - showToast("Expense Created Successfully","success") - if (onSuccessCallBack) onSuccessCallBack(); - }, - onError:(error)=>{ - showToast(error.message || "Something went wrong please try again !","error") + (oldData) => { + if (!oldData) return oldData; + return { + ...oldData, + data: oldData.data.map((item) => + item.id === updatedExpense.id + ? { + ...item, + nextStatus: updatedExpense.nextStatus, + status: updatedExpense.status, + } + : item + ), + }; } - }) -} + ); + + if (onSuccessCallBack) onSuccessCallBack(); + }, + onError: (error) => { + showToast( + error.message || "Something went wrong, please try again!", + "error" + ); + }, + }); +}; -- 2.43.0