feat(expenses): add import functionality for expenses and total pending calculation

This commit is contained in:
Jose Selesan
2026-05-29 14:30:10 -03:00
parent 4b17940134
commit b1968cece9
11 changed files with 600 additions and 19 deletions

View File

@@ -9,6 +9,9 @@ import {
useCreateNonPeriodicExpense,
usePayExpense,
useMonthlyTotals,
useTotalPending,
useImportPeriodicExpenses,
useImportExpenses,
} from "@/lib/queries";
import type {
PeriodicExpense,
@@ -18,6 +21,9 @@ import type {
PayExpenseInput,
PaginatedResponse,
MonthlyTotals,
MonthlyExpensesTotal,
ImportResult,
ImportExpensesResult,
} from "@/lib/api";
interface ExpensesContextValue {
@@ -34,6 +40,8 @@ interface ExpensesContextValue {
monthlyTotals: MonthlyTotals | undefined;
isLoadingTotals: boolean;
totalPending: MonthlyExpensesTotal | undefined;
isLoadingTotalPending: boolean;
createPeriodicExpense: (data: CreatePeriodicExpenseInput) => Promise<PeriodicExpense>;
updatePeriodicExpense: (id: number, data: CreatePeriodicExpenseInput) => Promise<void>;
@@ -41,6 +49,8 @@ interface ExpensesContextValue {
generateMonthlyExpense: (id: number) => Promise<Expense>;
createNonPeriodicExpense: (data: CreateNonPeriodicExpenseInput) => Promise<void>;
payExpense: (id: number, data: PayExpenseInput) => Promise<void>;
importPeriodicExpenses: (file: File) => Promise<ImportResult>;
importExpenses: (file: File) => Promise<ImportExpensesResult>;
}
const ExpensesContext = createContext<ExpensesContextValue | null>(null);
@@ -56,6 +66,7 @@ export function ExpensesProvider({ children }: { children: ReactNode }) {
const now = new Date();
const { data: monthlyTotals, isLoading: isLoadingTotals } = useMonthlyTotals(now.getFullYear(), now.getMonth() + 1);
const { data: totalPending, isLoading: isLoadingTotalPending } = useTotalPending();
const createPeriodicMutation = useCreatePeriodicExpense();
const updatePeriodicMutation = useUpdatePeriodicExpense();
@@ -63,6 +74,22 @@ export function ExpensesProvider({ children }: { children: ReactNode }) {
const generateMonthlyMutation = useGenerateMonthlyExpense();
const createExpenseMutation = useCreateNonPeriodicExpense();
const payExpenseMutation = usePayExpense();
const importPeriodicMutation = useImportPeriodicExpenses();
const importExpensesMutation = useImportExpenses();
const importPeriodicExpensesFn = useCallback(
async (file: File): Promise<ImportResult> => {
return importPeriodicMutation.mutateAsync(file);
},
[importPeriodicMutation],
);
const importExpensesFn = useCallback(
async (file: File): Promise<ImportExpensesResult> => {
return importExpensesMutation.mutateAsync(file);
},
[importExpensesMutation],
);
const createPeriodicExpense = useCallback(
async (data: CreatePeriodicExpenseInput): Promise<PeriodicExpense> => {
@@ -120,12 +147,16 @@ export function ExpensesProvider({ children }: { children: ReactNode }) {
pageSize,
monthlyTotals,
isLoadingTotals,
totalPending,
isLoadingTotalPending,
createPeriodicExpense,
updatePeriodicExpense: updatePeriodicExpenseFn,
deletePeriodicExpense: deletePeriodicExpenseFn,
generateMonthlyExpense: generateMonthlyExpenseFn,
createNonPeriodicExpense: createNonPeriodicExpenseFn,
payExpense: payExpenseFn,
importPeriodicExpenses: importPeriodicExpensesFn,
importExpenses: importExpensesFn,
}}
>
{children}