"use client"; import { RiBankCard2Line, RiBillLine, RiExchangeDollarLine, RiMailLine, RiMailSendLine, RiUser3Line, RiVerifiedBadgeFill, } from "@remixicon/react"; import Image from "next/image"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { type ReactNode, useMemo, useState, useTransition } from "react"; import { toast } from "sonner"; import { sendPagadorSummaryAction } from "@/app/(dashboard)/pagadores/[pagadorId]/actions"; import { Badge } from "@/components/ui/badge"; import { Button } from "@/components/ui/button"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { PAGADOR_ROLE_ADMIN } from "@/lib/pagadores/constants"; import { getAvatarSrc } from "@/lib/pagadores/utils"; import { cn } from "@/lib/utils/ui"; type PagadorInfo = { id: string; name: string; email: string | null; avatarUrl: string | null; status: string; note: string | null; role: string | null; isAutoSend: boolean; createdAt: string; lastMailAt: string | null; shareCode: string | null; canEdit: boolean; }; type PagadorSummaryPreview = { periodLabel: string; totalExpenses: number; paymentSplits: { card: number; boleto: number; instant: number; }; cardUsage: { name: string; amount: number }[]; boletoStats: { totalAmount: number; paidAmount: number; pendingAmount: number; paidCount: number; pendingCount: number; }; lancamentoCount: number; }; type PagadorInfoCardProps = { pagador: PagadorInfo; selectedPeriod: string; summary: PagadorSummaryPreview; }; export function PagadorInfoCard({ pagador, selectedPeriod, summary, }: PagadorInfoCardProps) { const router = useRouter(); const [isSending, startTransition] = useTransition(); const [confirmOpen, setConfirmOpen] = useState(false); const avatarSrc = getAvatarSrc(pagador.avatarUrl); const createdAtLabel = formatDate(pagador.createdAt); const isAdmin = pagador.role === PAGADOR_ROLE_ADMIN; const lastMailLabel = useMemo(() => { if (!pagador.lastMailAt) { return "Nunca enviado"; } const date = new Date(pagador.lastMailAt); if (Number.isNaN(date.getTime())) { return "Nunca enviado"; } return date.toLocaleString("pt-BR", { dateStyle: "short", timeStyle: "short", }); }, [pagador.lastMailAt]); const disableSend = isSending || !pagador.email || !pagador.canEdit; const openConfirmDialog = () => { if (!pagador.email) { toast.error("Cadastre um e-mail para este pagador antes de enviar."); return; } setConfirmOpen(true); }; const handleSendSummary = () => { if (!pagador.email) { toast.error("Cadastre um e-mail para este pagador antes de enviar."); return; } startTransition(async () => { const result = await sendPagadorSummaryAction({ pagadorId: pagador.id, period: selectedPeriod, }); if (!result.success) { toast.error(result.error); return; } toast.success(result.message); setConfirmOpen(false); router.refresh(); }); }; const getStatusBadgeVariant = (status: string): "success" | "secondary" => { const normalizedStatus = status.toLowerCase(); if (normalizedStatus === "ativo") { return "success"; } return "outline"; }; return (
{`Avatar
{pagador.name} {isAdmin ? ( ) : null} {pagador.isAutoSend ? ( ) : null}
Criado em {createdAtLabel}
{pagador.canEdit ? ( <> Último envio: {lastMailLabel} ) : ( Acesso somente leitura )}
{pagador.email} ) : ( "Sem e-mail cadastrado" ) } /> {pagador.status} } /> {resolveRoleLabel(pagador.role)} } /> {!pagador.email ? ( Cadastre um e-mail para permitir o envio automático. } className="sm:col-span-2" /> ) : null} {pagador.note} ) : ( "Sem observações" ) } className="sm:col-span-2" /> {pagador.canEdit ? ( { if (isSending) return; setConfirmOpen(open); }} > Confirmar envio do resumo Resumo de{" "} {summary.periodLabel} {" "} para{" "} {pagador.email}
{/* Total Geral */}

Total de Despesas

{formatCurrency(summary.totalExpenses)}

{summary.lancamentoCount} lançamentos

{/* Grid de Formas de Pagamento */}
{/* Cartões */}
Cartões

{formatCurrency(summary.paymentSplits.card)}

{/* Boletos */}
Boletos

{formatCurrency(summary.paymentSplits.boleto)}

{/* Instantâneo */}
Pix/Débito

{formatCurrency(summary.paymentSplits.instant)}

{/* Detalhes Adicionais */}
{/* Cartões Utilizados */} {summary.cardUsage.length > 0 && (
Cartões Utilizados
{summary.cardUsage.map((card, index) => (
{card.name} {formatCurrency(card.amount)}
))}
)} {/* Status de Boletos */} {(summary.boletoStats.paidCount > 0 || summary.boletoStats.pendingCount > 0) && (
Status de Boletos

Pagos

{formatCurrency(summary.boletoStats.paidAmount)}{" "} ({summary.boletoStats.paidCount})

Pendentes

{formatCurrency(summary.boletoStats.pendingAmount)}{" "} ({summary.boletoStats.pendingCount})

)}
) : null}
); } const formatDate = (value: string) => { const date = new Date(value); if (Number.isNaN(date.getTime())) return "—"; return date.toLocaleDateString("pt-BR", { day: "2-digit", month: "long", year: "numeric", }); }; const resolveRoleLabel = (role: string | null) => { if (role === PAGADOR_ROLE_ADMIN) return "Administrador"; return "Pagador"; }; const formatCurrency = (value: number) => value.toLocaleString("pt-BR", { style: "currency", currency: "BRL", maximumFractionDigits: 2, }); type InfoItemProps = { label: string; value: ReactNode; className?: string; }; function InfoItem({ label, value, className }: InfoItemProps) { return (
{label}
{value}
); }