- 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>
101 lines
2.7 KiB
TypeScript
101 lines
2.7 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
RiCheckboxCircleLine,
|
|
RiHourglass2Line,
|
|
RiWallet3Line,
|
|
} from "@remixicon/react";
|
|
import MoneyValues from "@/components/money-values";
|
|
import { CardContent } from "@/components/ui/card";
|
|
import { WidgetEmptyState } from "@/components/widget-empty-state";
|
|
import type { PaymentStatusData } from "@/lib/dashboard/payments/payment-status";
|
|
import { Progress } from "../ui/progress";
|
|
|
|
type PaymentStatusWidgetProps = {
|
|
data: PaymentStatusData;
|
|
};
|
|
|
|
type CategorySectionProps = {
|
|
title: string;
|
|
total: number;
|
|
confirmed: number;
|
|
pending: number;
|
|
};
|
|
|
|
function CategorySection({
|
|
title,
|
|
total,
|
|
confirmed,
|
|
pending,
|
|
}: CategorySectionProps) {
|
|
// Usa valores absolutos para calcular percentual corretamente
|
|
const absTotal = Math.abs(total);
|
|
const absConfirmed = Math.abs(confirmed);
|
|
const confirmedPercentage =
|
|
absTotal > 0 ? (absConfirmed / absTotal) * 100 : 0;
|
|
|
|
return (
|
|
<div className="space-y-2">
|
|
<div className="flex items-center justify-between">
|
|
<span className="text-sm font-medium text-foreground">{title}</span>
|
|
<MoneyValues amount={total} />
|
|
</div>
|
|
|
|
{/* Barra de progresso */}
|
|
<Progress value={confirmedPercentage} className="h-2" />
|
|
|
|
{/* Status de confirmados e pendentes */}
|
|
<div className="flex items-center justify-between gap-4 text-sm">
|
|
<div className="flex items-center gap-1.5 ">
|
|
<RiCheckboxCircleLine className="size-3 text-success" />
|
|
<MoneyValues amount={confirmed} />
|
|
<span className="text-xs text-muted-foreground">confirmados</span>
|
|
</div>
|
|
|
|
<div className="flex items-center gap-1.5 ">
|
|
<RiHourglass2Line className="size-3 text-warning" />
|
|
<MoneyValues amount={pending} />
|
|
<span className="text-xs text-muted-foreground">pendentes</span>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function PaymentStatusWidget({ data }: PaymentStatusWidgetProps) {
|
|
const isEmpty = data.income.total === 0 && data.expenses.total === 0;
|
|
|
|
if (isEmpty) {
|
|
return (
|
|
<CardContent className="px-0">
|
|
<WidgetEmptyState
|
|
icon={<RiWallet3Line className="size-6 text-muted-foreground" />}
|
|
title="Nenhum valor a receber ou pagar no período"
|
|
description="Registre lançamentos para visualizar os valores confirmados e pendentes."
|
|
/>
|
|
</CardContent>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<CardContent className="space-y-6 px-0">
|
|
<CategorySection
|
|
title="A Receber"
|
|
total={data.income.total}
|
|
confirmed={data.income.confirmed}
|
|
pending={data.income.pending}
|
|
/>
|
|
|
|
{/* Linha divisória pontilhada */}
|
|
<div className="border-t border-dashed" />
|
|
|
|
<CategorySection
|
|
title="A Pagar"
|
|
total={data.expenses.total}
|
|
confirmed={data.expenses.confirmed}
|
|
pending={data.expenses.pending}
|
|
/>
|
|
</CardContent>
|
|
);
|
|
}
|