"use client"; import { useCallback, useMemo, useState, useTransition } from "react"; import { toast } from "sonner"; import { createLancamentoAction } from "@/app/(dashboard)/lancamentos/actions"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog"; import { Label } from "@/components/ui/label"; import { Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { groupAndSortCategorias } from "@/lib/lancamentos/categoria-helpers"; import { CategoriaSelectContent, ContaCartaoSelectContent, PagadorSelectContent, } from "../select-items"; import type { LancamentoItem, SelectOption } from "../types"; interface BulkImportDialogProps { open: boolean; onOpenChange: (open: boolean) => void; items: LancamentoItem[]; pagadorOptions: SelectOption[]; contaOptions: SelectOption[]; cartaoOptions: SelectOption[]; categoriaOptions: SelectOption[]; defaultPagadorId?: string | null; } export function BulkImportDialog({ open, onOpenChange, items, pagadorOptions, contaOptions, cartaoOptions, categoriaOptions, defaultPagadorId, }: BulkImportDialogProps) { const [pagadorId, setPagadorId] = useState( defaultPagadorId ?? undefined, ); const [categoriaId, setCategoriaId] = useState(undefined); const [contaId, setContaId] = useState(undefined); const [cartaoId, setCartaoId] = useState(undefined); const [isPending, startTransition] = useTransition(); // Reset form when dialog opens/closes const handleOpenChange = useCallback( (newOpen: boolean) => { if (!newOpen) { setPagadorId(defaultPagadorId ?? undefined); setCategoriaId(undefined); setContaId(undefined); setCartaoId(undefined); } onOpenChange(newOpen); }, [onOpenChange, defaultPagadorId], ); const categoriaGroups = useMemo(() => { // Get unique transaction types from items const transactionTypes = new Set(items.map((item) => item.transactionType)); // Filter categories based on transaction types const filtered = categoriaOptions.filter((option) => { if (!option.group) return false; return Array.from(transactionTypes).some( (type) => option.group?.toLowerCase() === type.toLowerCase(), ); }); return groupAndSortCategorias(filtered); }, [categoriaOptions, items]); const handleSubmit = useCallback( async (event: React.FormEvent) => { event.preventDefault(); if (!pagadorId) { toast.error("Selecione o pagador."); return; } if (!categoriaId) { toast.error("Selecione a categoria."); return; } startTransition(async () => { let successCount = 0; let errorCount = 0; for (const item of items) { const sanitizedAmount = Math.abs(item.amount); // Determine payment method based on original item const isCredit = item.paymentMethod === "Cartão de crédito"; // Validate payment method fields if (isCredit && !cartaoId) { toast.error("Selecione um cartão de crédito."); return; } if (!isCredit && !contaId) { toast.error("Selecione uma conta."); return; } const payload = { purchaseDate: item.purchaseDate, period: item.period, name: item.name, transactionType: item.transactionType as | "Despesa" | "Receita" | "Transferência", amount: sanitizedAmount, condition: item.condition as "À vista" | "Parcelado" | "Recorrente", paymentMethod: item.paymentMethod as | "Cartão de crédito" | "Cartão de débito" | "Pix" | "Dinheiro" | "Boleto" | "Pré-Pago | VR/VA" | "Transferência bancária", pagadorId, secondaryPagadorId: undefined, isSplit: false, contaId: isCredit ? undefined : contaId, cartaoId: isCredit ? cartaoId : undefined, categoriaId, note: item.note || undefined, isSettled: isCredit ? null : Boolean(item.isSettled), installmentCount: item.condition === "Parcelado" && item.installmentCount ? Number(item.installmentCount) : undefined, recurrenceCount: item.condition === "Recorrente" && item.recurrenceCount ? Number(item.recurrenceCount) : undefined, dueDate: item.paymentMethod === "Boleto" && item.dueDate ? item.dueDate : undefined, }; const result = await createLancamentoAction(payload); if (result.success) { successCount++; } else { errorCount++; console.error(`Failed to import ${item.name}:`, result.error); } } if (errorCount === 0) { toast.success( `${successCount} ${ successCount === 1 ? "lançamento importado" : "lançamentos importados" } com sucesso!`, ); handleOpenChange(false); } else if (successCount > 0) { toast.warning( `${successCount} importados, ${errorCount} falharam. Verifique o console para detalhes.`, ); } else { toast.error("Falha ao importar lançamentos. Verifique o console."); } }); }, [items, pagadorId, categoriaId, contaId, cartaoId, handleOpenChange], ); const itemCount = items.length; const hasCredit = items.some( (item) => item.paymentMethod === "Cartão de crédito", ); const hasNonCredit = items.some( (item) => item.paymentMethod !== "Cartão de crédito", ); return ( Importar Lançamentos Importando {itemCount}{" "} {itemCount === 1 ? "lançamento" : "lançamentos"}. Selecione o pagador, categoria e forma de pagamento para aplicar a todos.
{hasNonCredit && (
)} {hasCredit && (
)}
); }