- Install @biomejs/biome as devDependency at root - Configure biome.json with 2-space indent, double quotes, Tailwind CSS support - Add lint/lint:fix/format/format:fix scripts to root and app package.json - Fix noNonNullAssertion: env vars extracted to variables with suppression, <div role=button> replaced with <button> - Fix noUnusedVariables: remove unused destructured vars - Fix useIterableCallbackReturn: arrow functions with block body - Fix noExplicitAny: recharts Tooltip formatters - Fix noLabelWithoutControl: add htmlFor+id or use <span> for non-input labels - Fix noStaticElementInteractions/useKeyWithClickEvents: role+keyboard events for overlays - Fix noArrayIndexKey: use error string as key - Fix CSS parse: enable tailwindDirectives parser - Normalize formatting across 80 files with biome check --write
52 lines
1.6 KiB
TypeScript
52 lines
1.6 KiB
TypeScript
import { useState } from "react";
|
|
import { Route } from "@/routes/_authenticated/expenses";
|
|
import { ExpensesTabContent } from "./components/ExpensesTabContent";
|
|
import { PeriodicExpensesTabContent } from "./components/PeriodicExpensesTabContent";
|
|
import { ExpensesProvider } from "./ExpensesProvider";
|
|
|
|
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 text-balance">Gastos</h1>
|
|
|
|
<div className="scrollbar-none flex gap-1 overflow-x-auto border-b">
|
|
{tabs.map((tab) => (
|
|
<button
|
|
key={tab.id}
|
|
type="button"
|
|
onClick={() => setActiveTab(tab.id)}
|
|
className={
|
|
activeTab === tab.id
|
|
? "-mb-px shrink-0 border-b-2 border-primary px-3 pb-2 text-sm font-medium text-foreground"
|
|
: "shrink-0 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() {
|
|
const { periodicExpenseId } = Route.useSearch();
|
|
return (
|
|
<ExpensesProvider initialPeriodicExpenseId={periodicExpenseId}>
|
|
<ExpensesPageInner />
|
|
</ExpensesProvider>
|
|
);
|
|
}
|