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:
Jose Selesan
2026-05-29 10:29:20 -03:00
parent bd5e29236b
commit e1786f7384
39 changed files with 4338 additions and 6435 deletions

View File

@@ -1,8 +1,49 @@
export function ExpensesPage() {
import { useState } from "react";
import { ExpensesProvider } from "./ExpensesProvider";
import { ExpensesTabContent } from "./components/ExpensesTabContent";
import { PeriodicExpensesTabContent } from "./components/PeriodicExpensesTabContent";
const tabs = [
{ id: "expenses", label: "Gastos" },
{ id: "periodic", label: "Gastos Periódicos" },
] as const;
type TabId = (typeof tabs)[number]["id"];
function ExpensesPageInner() {
const [activeTab, setActiveTab] = useState<TabId>("expenses");
return (
<div className="space-y-4">
<h1 className="text-2xl font-semibold">Gastos</h1>
<p className="text-muted-foreground">Administrá tus gastos acá.</p>
<div className="flex gap-1 border-b">
{tabs.map((tab) => (
<button
key={tab.id}
type="button"
onClick={() => setActiveTab(tab.id)}
className={
activeTab === tab.id
? "-mb-px border-b-2 border-primary px-3 pb-2 text-sm font-medium text-foreground"
: "px-3 pb-2 text-sm font-medium text-muted-foreground transition-colors hover:text-foreground"
}
>
{tab.label}
</button>
))}
</div>
{activeTab === "expenses" && <ExpensesTabContent />}
{activeTab === "periodic" && <PeriodicExpensesTabContent />}
</div>
);
}
export function ExpensesPage() {
return (
<ExpensesProvider>
<ExpensesPageInner />
</ExpensesProvider>
);
}