"use client"; import { RiEditLine } from "@remixicon/react"; import Image from "next/image"; import { useRouter } from "next/navigation"; import type { ReactNode } from "react"; import { useEffect, useState, useTransition } from "react"; import { toast } from "sonner"; import { updateInvoicePaymentStatusAction, updatePaymentDateAction, } from "@/features/invoices/actions"; import MoneyValues from "@/shared/components/money-values"; import StatusDot from "@/shared/components/status-dot"; import { Badge } from "@/shared/components/ui/badge"; import { Button } from "@/shared/components/ui/button"; import { Card, CardContent } from "@/shared/components/ui/card"; import { resolveCardBrandAsset } from "@/shared/lib/cards/brand-assets"; import { INVOICE_PAYMENT_STATUS, INVOICE_STATUS_BADGE_VARIANT, INVOICE_STATUS_DESCRIPTION, INVOICE_STATUS_LABEL, type InvoicePaymentStatus, } from "@/shared/lib/invoices"; import { resolveLogoSrc } from "@/shared/lib/logo"; import { formatCurrency } from "@/shared/utils/currency"; import { formatDateOnly } from "@/shared/utils/date"; import { cn } from "@/shared/utils/ui"; import { EditPaymentDateDialog } from "./edit-payment-date-dialog"; type InvoiceSummaryCardProps = { cardId: string; period: string; cardName: string; cardBrand: string | null; cardStatus: string | null; closingDay: string; dueDay: string; periodLabel: string; totalAmount: number; limitAmount: number | null; invoiceStatus: InvoicePaymentStatus; paymentDate: Date | null; logo?: string | null; actions?: React.ReactNode; }; const actionLabelByStatus: Record = { [INVOICE_PAYMENT_STATUS.PENDING]: "Marcar como paga", [INVOICE_PAYMENT_STATUS.PAID]: "Desfazer pagamento", }; const actionVariantByStatus: Record< InvoicePaymentStatus, "default" | "outline" > = { [INVOICE_PAYMENT_STATUS.PENDING]: "default", [INVOICE_PAYMENT_STATUS.PAID]: "outline", }; const formatDay = (value: string) => value.padStart(2, "0"); const getCardStatusDotColor = (status: string | null) => { if (!status) return "bg-gray-400"; const s = status.toLowerCase(); return s === "ativo" || s === "active" ? "bg-success" : "bg-gray-400"; }; const formatPaymentDate = (value: Date | null) => formatDateOnly(value, { day: "2-digit", month: "short", year: "numeric", }) ?? "data não informada"; export function InvoiceSummaryCard({ cardId, period, cardName, cardBrand, cardStatus, closingDay, dueDay, periodLabel, totalAmount, limitAmount, invoiceStatus, paymentDate: initialPaymentDate, logo, actions, }: InvoiceSummaryCardProps) { const router = useRouter(); const [isPending, startTransition] = useTransition(); const [paymentDate, setPaymentDate] = useState( initialPaymentDate ?? new Date(), ); useEffect(() => { setPaymentDate(initialPaymentDate ?? new Date()); }, [initialPaymentDate]); const logoPath = resolveLogoSrc(logo); const brandAsset = resolveCardBrandAsset(cardBrand); const isPaid = invoiceStatus === INVOICE_PAYMENT_STATUS.PAID; const paymentDateLabel = isPaid ? formatPaymentDate(paymentDate) : null; const actionDescription = isPaid ? `Pagamento registrado em ${paymentDateLabel}.` : INVOICE_STATUS_DESCRIPTION[invoiceStatus]; const targetStatus = isPaid ? INVOICE_PAYMENT_STATUS.PENDING : INVOICE_PAYMENT_STATUS.PAID; const handleAction = () => { startTransition(async () => { const result = await updateInvoicePaymentStatusAction({ cardId, period, status: targetStatus, paymentDate: targetStatus === INVOICE_PAYMENT_STATUS.PAID ? paymentDate.toISOString().split("T")[0] : undefined, }); if (result.success) { toast.success(result.message); router.refresh(); return; } toast.error(result.error); }); }; const handleDateChange = (newDate: Date) => { setPaymentDate(newDate); startTransition(async () => { const result = await updatePaymentDateAction({ cardId, period, paymentDate: newDate.toISOString().split("T")[0] ?? "", }); if (result.success) { toast.success(result.message); router.refresh(); return; } toast.error(result.error); }); }; return (
{/* Linha 1 — identidade */}
{logoPath ? (
{`Logo
) : cardBrand ? ( {cardBrand.slice(0, 2).toUpperCase()} ) : null}

{cardName}

Fatura de {periodLabel}

{actions ?
{actions}
: null}
{/* Linha 2 — valor da fatura (hero) */}

Valor da fatura

{INVOICE_STATUS_LABEL[invoiceStatus]} {cardStatus ? (
{cardStatus}
) : null}
{/* Linha 3 — metadados do cartão */}
Dia {formatDay(dueDay)} Dia {formatDay(closingDay)} {typeof limitAmount === "number" ? ( {formatCurrency(limitAmount)} ) : null} {cardBrand ? (
{brandAsset ? ( {cardBrand} ) : null} {cardBrand}
) : null}
{/* Linha 4 — ação */}

{actionDescription}

{isPaid ? ( } currentDate={paymentDate} onDateChange={handleDateChange} /> ) : null}
); } function MetaItem({ label, children }: { label: string; children: ReactNode }) { return (
{label}
{children}
); }