refactor: migrate from ESLint to Biome and extract SQL queries to data.ts

- Replace ESLint with Biome for linting and formatting
- Configure Biome with tabs, double quotes, and organized imports
- Move all SQL/Drizzle queries from page.tsx files to data.ts files
- Create new data.ts files for: ajustes, dashboard, relatorios/categorias
- Update existing data.ts files: extrato, fatura (add lancamentos queries)
- Remove all drizzle-orm imports from page.tsx files
- Update README.md with new tooling info

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Felipe Coutinho
2026-01-27 13:15:37 +00:00
parent 8ffe61c59b
commit a7f63fb77a
442 changed files with 66141 additions and 69292 deletions

View File

@@ -1,78 +1,78 @@
"use client";
import { Card, CardContent } from "@/components/ui/card";
import MoneyValues from "@/components/money-values";
import type { TopEstabelecimentosData } from "@/lib/top-estabelecimentos/fetch-data";
import {
RiStore2Line,
RiExchangeLine,
RiMoneyDollarCircleLine,
RiRepeatLine,
RiExchangeLine,
RiMoneyDollarCircleLine,
RiRepeatLine,
RiStore2Line,
} from "@remixicon/react";
import MoneyValues from "@/components/money-values";
import { Card, CardContent } from "@/components/ui/card";
import type { TopEstabelecimentosData } from "@/lib/top-estabelecimentos/fetch-data";
type SummaryCardsProps = {
summary: TopEstabelecimentosData["summary"];
summary: TopEstabelecimentosData["summary"];
};
export function SummaryCards({ summary }: SummaryCardsProps) {
const cards = [
{
title: "Estabelecimentos",
value: summary.totalEstablishments,
isMoney: false,
icon: RiStore2Line,
description: "Locais diferentes",
},
{
title: "Transações",
value: summary.totalTransactions,
isMoney: false,
icon: RiExchangeLine,
description: "Compras no período",
},
{
title: "Total Gasto",
value: summary.totalSpent,
isMoney: true,
icon: RiMoneyDollarCircleLine,
description: "Soma de todas as compras",
},
{
title: "Ticket Médio",
value: summary.avgPerTransaction,
isMoney: true,
icon: RiRepeatLine,
description: "Média por transação",
},
];
const cards = [
{
title: "Estabelecimentos",
value: summary.totalEstablishments,
isMoney: false,
icon: RiStore2Line,
description: "Locais diferentes",
},
{
title: "Transações",
value: summary.totalTransactions,
isMoney: false,
icon: RiExchangeLine,
description: "Compras no período",
},
{
title: "Total Gasto",
value: summary.totalSpent,
isMoney: true,
icon: RiMoneyDollarCircleLine,
description: "Soma de todas as compras",
},
{
title: "Ticket Médio",
value: summary.avgPerTransaction,
isMoney: true,
icon: RiRepeatLine,
description: "Média por transação",
},
];
return (
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
{cards.map((card) => (
<Card key={card.title}>
<CardContent className="p-4">
<div className="flex items-start justify-between gap-3">
<div className="space-y-1">
<p className="text-xs font-medium text-muted-foreground">
{card.title}
</p>
{card.isMoney ? (
<MoneyValues
className="text-xl font-semibold"
amount={card.value}
/>
) : (
<p className="text-xl font-semibold">{card.value}</p>
)}
<p className="text-xs text-muted-foreground">
{card.description}
</p>
</div>
<card.icon className="size-5 text-muted-foreground shrink-0" />
</div>
</CardContent>
</Card>
))}
</div>
);
return (
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
{cards.map((card) => (
<Card key={card.title}>
<CardContent className="p-4">
<div className="flex items-start justify-between gap-3">
<div className="space-y-1">
<p className="text-xs font-medium text-muted-foreground">
{card.title}
</p>
{card.isMoney ? (
<MoneyValues
className="text-xl font-semibold"
amount={card.value}
/>
) : (
<p className="text-xl font-semibold">{card.value}</p>
)}
<p className="text-xs text-muted-foreground">
{card.description}
</p>
</div>
<card.icon className="size-5 text-muted-foreground shrink-0" />
</div>
</CardContent>
</Card>
))}
</div>
);
}