"use client"; import Image from "next/image"; import { type ComponentType, type CSSProperties, useEffect, useState, } from "react"; import { currencyFormatter, formatCondition, formatPeriod, } from "@/features/transactions/lib/formatting-helpers"; import { EstablishmentLogo } from "@/shared/components/entity-avatar"; import { TransactionTypeBadge } from "@/shared/components/transaction-type-badge"; import { Avatar, AvatarFallback, AvatarImage, } from "@/shared/components/ui/avatar"; import { Badge } from "@/shared/components/ui/badge"; import { Button } from "@/shared/components/ui/button"; import { Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/shared/components/ui/dialog"; import { Separator } from "@/shared/components/ui/separator"; import { resolveLogoSrc } from "@/shared/lib/logo"; import { getAvatarSrc } from "@/shared/lib/payers/utils"; import { getCategoryColorFromName } from "@/shared/utils/category-colors"; import { formatDate, parseLocalDateString } from "@/shared/utils/date"; import { getIconComponent, getPaymentMethodIcon } from "@/shared/utils/icons"; import { AttachmentSection } from "../attachments/attachment-section"; import { InstallmentTimeline } from "../shared/installment-timeline"; import type { TransactionItem } from "../types"; interface TransactionDetailsDialogProps { open: boolean; onOpenChange: (open: boolean) => void; transaction: TransactionItem | null; onEdit?: (transaction: TransactionItem) => void; } export function TransactionDetailsDialog({ open, onOpenChange, transaction, onEdit, }: TransactionDetailsDialogProps) { const [attachmentCount, setAttachmentCount] = useState(null); useEffect(() => { setAttachmentCount(null); }, []); if (!transaction) return null; const isInstallment = transaction.condition?.toLowerCase() === "parcelado" && transaction.currentInstallment && transaction.installmentCount; const valorParcela = Math.abs(transaction.amount); const totalParcelas = transaction.installmentCount ?? 1; const parcelaAtual = transaction.currentInstallment ?? 1; const valorTotal = isInstallment ? valorParcela * totalParcelas : valorParcela; const valorRestante = isInstallment ? valorParcela * (totalParcelas - parcelaAtual) : 0; const isBoleto = transaction.paymentMethod === "Boleto"; const handleEdit = () => { onOpenChange(false); onEdit?.(transaction); }; return (
{transaction.name} {formatDate(transaction.purchaseDate)}

Total

{currencyFormatter.format(valorTotal)}

{transaction.isSettled ? "Pago" : "Em aberto"}
{formatCondition(transaction.condition)}

Detalhes

  • Forma de Pagamento {getPaymentMethodIcon(transaction.paymentMethod)} {transaction.paymentMethod}
  • {transaction.cartaoName ? "Cartão" : "Conta"} {(() => { const accountLabel = transaction.cartaoName ?? transaction.contaName; if (!accountLabel) { return ; } const logoSrc = resolveLogoSrc( transaction.cartaoLogo ?? transaction.contaLogo, ); return ( {logoSrc && ( {`Logo )} {accountLabel} ); })()}
  • Categoria {(() => { if (!transaction.categoriaName) { return ; } const IconComponent = transaction.categoriaIcon ? (getIconComponent( transaction.categoriaIcon, ) as ComponentType<{ className?: string; style?: CSSProperties; }> | null) : null; const color = getCategoryColorFromName( transaction.categoriaName, ); return ( {IconComponent ? ( ) : null} {transaction.categoriaName} ); })()}
  • Responsável {(() => { const label = transaction.pagadorName?.trim() || "—"; if (label === "—") { return ; } const displayName = label.split(/\s+/)[0] ?? label; const avatarSrc = getAvatarSrc(transaction.pagadorAvatar); const initial = displayName.charAt(0).toUpperCase() || "?"; return ( {initial} {label} ); })()}
  • {isBoleto && transaction.dueDate && ( )} {transaction.isDivided && (
  • Divisão Dividido
  • )}

Valores

    {isInstallment && (
  • )} {isInstallment && ( )} {transaction.recurrenceCount && ( )}
{transaction.note ? (

Notas

{transaction.note}
) : null} {attachmentCount !== 0 && (

Anexos

)}
{onEdit && !transaction.readonly && ( )}
); } interface DetailRowProps { label: string; value: string; valueClassName?: string; } function DetailRow({ label, value, valueClassName }: DetailRowProps) { return (
  • {label} {value}
  • ); }