feat(expenses): implement responsive dialog for expense management and create expense provider
- Added ResponsiveDialog component for handling responsive dialogs in the UI. - Created ExpensesProvider to manage state and API interactions for expenses. - Developed ExpensesTabContent to display expenses with filtering options and dialogs for new and pay expense actions. - Implemented ExpensesTable for rendering expense data in a tabular format with actions. - Added dialogs for creating new expenses and paying existing ones with form validation. - Introduced PeriodicExpenseForm for managing periodic expenses with month selection. - Created PeriodicExpensesTabContent to manage and display periodic expenses with create/edit functionality. - Added GenerateCurrentMonthDialog for confirming monthly expense generation. - Implemented PeriodicExpensesTable for displaying periodic expenses with edit and delete actions.
This commit is contained in:
@@ -46,6 +46,18 @@ async function fetcher<T>(url: string): Promise<T> {
|
||||
return res.json();
|
||||
}
|
||||
|
||||
async function mutator<T>(url: string, method: string, body?: unknown): Promise<T> {
|
||||
const res = await fetch(url, {
|
||||
method,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
});
|
||||
if (!res.ok) {
|
||||
throw new Error(`API error: ${res.status} ${res.statusText}`);
|
||||
}
|
||||
return res.json();
|
||||
}
|
||||
|
||||
export function getQuotes(): Promise<Quote[]> {
|
||||
return fetcher<Quote[]>("/api/quotes");
|
||||
}
|
||||
@@ -80,3 +92,81 @@ export function getDailyQuotes(
|
||||
const params = new URLSearchParams({ startDate, endDate });
|
||||
return fetcher<DailyQuote[]>(`/api/quotes/${type}/daily?${params}`);
|
||||
}
|
||||
|
||||
// Expenses
|
||||
|
||||
export type PeriodicExpense = {
|
||||
id: number;
|
||||
description: string;
|
||||
defaultDueDay: number;
|
||||
defaultAmount: string;
|
||||
periods: number[];
|
||||
isDeleted: boolean;
|
||||
createdAt: string;
|
||||
currentMonthApplicable?: boolean;
|
||||
};
|
||||
|
||||
export type Expense = {
|
||||
id: number;
|
||||
description: string;
|
||||
periodicExpenseId: number | null;
|
||||
year: number;
|
||||
month: number;
|
||||
amount: string;
|
||||
amountPayed: string | null;
|
||||
status: "PENDING" | "PAYED";
|
||||
dueDate: string;
|
||||
paymentDate: string | null;
|
||||
periodicExpense?: PeriodicExpense | null;
|
||||
};
|
||||
|
||||
export type CreatePeriodicExpenseInput = {
|
||||
description: string;
|
||||
defaultDueDay: number;
|
||||
defaultAmount: number;
|
||||
periods: number[];
|
||||
};
|
||||
|
||||
export type CreateNonPeriodicExpenseInput = {
|
||||
description: string;
|
||||
amount: number;
|
||||
dueDate: string;
|
||||
};
|
||||
|
||||
export type PayExpenseInput = {
|
||||
amountPayed: number;
|
||||
paymentDate?: string;
|
||||
};
|
||||
|
||||
export function getPeriodicExpenses(): Promise<PeriodicExpense[]> {
|
||||
return fetcher<PeriodicExpense[]>("/api/periodic-expenses");
|
||||
}
|
||||
|
||||
export function createPeriodicExpense(data: CreatePeriodicExpenseInput): Promise<PeriodicExpense> {
|
||||
return mutator<PeriodicExpense>("/api/periodic-expenses", "POST", data);
|
||||
}
|
||||
|
||||
export function updatePeriodicExpense(id: number, data: CreatePeriodicExpenseInput): Promise<PeriodicExpense> {
|
||||
return mutator<PeriodicExpense>(`/api/periodic-expenses/${id}`, "PUT", data);
|
||||
}
|
||||
|
||||
export function deletePeriodicExpense(id: number): Promise<void> {
|
||||
return mutator<void>(`/api/periodic-expenses/${id}`, "DELETE");
|
||||
}
|
||||
|
||||
export function generateMonthlyExpense(id: number): Promise<Expense> {
|
||||
return mutator<Expense>(`/api/periodic-expenses/${id}/generate-month`, "POST");
|
||||
}
|
||||
|
||||
export function getExpenses(status?: string): Promise<Expense[]> {
|
||||
const params = status ? `?status=${status}` : "";
|
||||
return fetcher<Expense[]>(`/api/expenses${params}`);
|
||||
}
|
||||
|
||||
export function createNonPeriodicExpense(data: CreateNonPeriodicExpenseInput): Promise<Expense> {
|
||||
return mutator<Expense>("/api/expenses", "POST", data);
|
||||
}
|
||||
|
||||
export function payExpense(id: number, data: PayExpenseInput): Promise<Expense> {
|
||||
return mutator<Expense>(`/api/expenses/${id}/pay`, "PUT", data);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user