Files
openmonetis/components/relatorios/cartoes/card-invoice-status.tsx
Felipe Coutinho f50261208a feat(v1.4.0): design system semântico, correções de revalidação e melhorias de UX
- Adicionar tokens semânticos de estado (success, warning, info) no globals.css
- Migrar ~60+ componentes de cores hardcoded do Tailwind para tokens semânticos
- Unificar 3 arrays duplicados de cores de categorias em importação única
- Corrigir widgets de boleto/fatura que não atualizavam após pagamento
  (actions de fatura e antecipação não invalidavam cache do dashboard)
- Corrigir scroll em listas Popover+Command (modal prop)
- Adicionar link "detalhes" no card de orçamento para página da categoria
- Adicionar indicadores de tendência coloridos nos cards de métricas
- Estender cores de chart de 6 para 10
- Normalizar dark mode e remover tokens não utilizados

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-07 15:14:59 +00:00

114 lines
2.5 KiB
TypeScript

"use client";
import { RiCalendarCheckLine } from "@remixicon/react";
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import type { CardDetailData } from "@/lib/relatorios/cartoes-report";
import { cn } from "@/lib/utils";
type CardInvoiceStatusProps = {
data: CardDetailData["invoiceStatus"];
};
const monthLabels = [
"Jan",
"Fev",
"Mar",
"Abr",
"Mai",
"Jun",
"Jul",
"Ago",
"Set",
"Out",
"Nov",
"Dez",
];
export function CardInvoiceStatus({ data }: CardInvoiceStatusProps) {
const formatCurrency = (value: number) => {
return new Intl.NumberFormat("pt-BR", {
style: "currency",
currency: "BRL",
minimumFractionDigits: 0,
maximumFractionDigits: 0,
}).format(value);
};
const getStatusColor = (status: string | null) => {
switch (status) {
case "pago":
return "bg-success";
case "pendente":
return "bg-warning";
case "atrasado":
return "bg-destructive";
default:
return "bg-muted";
}
};
const getStatusLabel = (status: string | null) => {
switch (status) {
case "pago":
return "Pago";
case "pendente":
return "Pendente";
case "atrasado":
return "Atrasado";
default:
return "—";
}
};
const formatPeriodShort = (period: string) => {
const [, month] = period.split("-");
return monthLabels[parseInt(month, 10) - 1];
};
return (
<Card>
<CardHeader className="pb-2">
<CardTitle className="flex items-center gap-1.5 text-base">
<RiCalendarCheckLine className="size-4 text-primary" />
Faturas
</CardTitle>
</CardHeader>
<CardContent>
<TooltipProvider>
<div className="flex items-center gap-1">
{data.map((invoice) => (
<Tooltip key={invoice.period}>
<TooltipTrigger asChild>
<div className="flex-1 flex flex-col items-center gap-2 cursor-default">
<div
className={cn(
"w-full h-2.5 rounded",
getStatusColor(invoice.status),
)}
/>
<span className="text-xs text-muted-foreground">
{formatPeriodShort(invoice.period)}
</span>
</div>
</TooltipTrigger>
<TooltipContent side="top">
<p className="font-medium">
{formatCurrency(invoice.amount)}
</p>
<p className="text-xs ">{getStatusLabel(invoice.status)}</p>
</TooltipContent>
</Tooltip>
))}
</div>
</TooltipProvider>
</CardContent>
</Card>
);
}