diff --git a/src/components/importacao/PreviewTransacoes.tsx b/src/components/importacao/PreviewTransacoes.tsx index f296c1f..cd6fb98 100644 --- a/src/components/importacao/PreviewTransacoes.tsx +++ b/src/components/importacao/PreviewTransacoes.tsx @@ -3,12 +3,17 @@ import { Card } from '@/components/ui/card'; import { Badge } from '@/components/ui/badge'; import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; +import { Checkbox } from '@/components/ui/checkbox'; +import { Button } from '@/components/ui/button'; import { AlertCircle, TrendingUp, TrendingDown, Copy } from 'lucide-react'; import { Alert, AlertDescription } from '@/components/ui/alert'; interface PreviewTransacoesProps { transacoes: TransacaoImportada[]; onCategoriaChange: (hash: string, categoria: string) => void; + onSelectionChange: (hash: string, selected: boolean) => void; + onSelectAll: () => void; + onDeselectAll: () => void; } const categorias = [ @@ -26,11 +31,19 @@ const categorias = [ 'Outros' ]; -export const PreviewTransacoes = ({ transacoes, onCategoriaChange }: PreviewTransacoesProps) => { +export const PreviewTransacoes = ({ + transacoes, + onCategoriaChange, + onSelectionChange, + onSelectAll, + onDeselectAll +}: PreviewTransacoesProps) => { const novas = transacoes.filter(t => !t.isDuplicada); const duplicadas = transacoes.filter(t => t.isDuplicada); - const totalEntradas = novas.filter(t => t.tipo === 'entrada').reduce((sum, t) => sum + t.valor, 0); - const totalSaidas = novas.filter(t => t.tipo === 'saida').reduce((sum, t) => sum + t.valor, 0); + const selecionadas = novas.filter(t => t.selecionada); + const totalEntradas = selecionadas.filter(t => t.tipo === 'entrada').reduce((sum, t) => sum + t.valor, 0); + const totalSaidas = selecionadas.filter(t => t.tipo === 'saida').reduce((sum, t) => sum + t.valor, 0); + const todasSelecionadas = novas.length > 0 && novas.every(t => t.selecionada); const formatCurrency = (value: number) => { return new Intl.NumberFormat('pt-BR', { @@ -99,11 +112,38 @@ export const PreviewTransacoes = ({ transacoes, onCategoriaChange }: PreviewTran {/* Tabela de transações */} -

Transações para Importar

+
+

Transações para Importar

+
+ + +
+
+ + { + if (checked) onSelectAll(); + else onDeselectAll(); + }} + /> + Data Descrição Categoria @@ -118,6 +158,15 @@ export const PreviewTransacoes = ({ transacoes, onCategoriaChange }: PreviewTran key={transacao.hash_unico} className={transacao.isDuplicada ? 'opacity-50' : ''} > + + + onSelectionChange(transacao.hash_unico, checked as boolean) + } + /> + {formatDate(transacao.data)} diff --git a/src/hooks/useImportacaoExtrato.ts b/src/hooks/useImportacaoExtrato.ts index 9e5e3c3..5104e7f 100644 --- a/src/hooks/useImportacaoExtrato.ts +++ b/src/hooks/useImportacaoExtrato.ts @@ -49,7 +49,14 @@ export const useImportacaoExtrato = () => { // Verificar duplicatas const transacoesComDuplicatas = await verificarDuplicatas(transacoesParseadas); - setTransacoes(transacoesComDuplicatas); + + // Marcar todas as não duplicadas como selecionadas por padrão + const transacoesComSelecao = transacoesComDuplicatas.map(t => ({ + ...t, + selecionada: !t.isDuplicada + })); + + setTransacoes(transacoesComSelecao); const duplicadas = transacoesComDuplicatas.filter(t => t.isDuplicada).length; const novas = transacoesComDuplicatas.length - duplicadas; @@ -117,6 +124,24 @@ export const useImportacaoExtrato = () => { )); }; + const atualizarSelecao = (hash: string, selecionada: boolean) => { + setTransacoes(transacoes.map(t => + t.hash_unico === hash ? { ...t, selecionada } : t + )); + }; + + const selecionarTodas = () => { + setTransacoes(transacoes.map(t => + t.isDuplicada ? t : { ...t, selecionada: true } + )); + }; + + const desselecionarTodas = () => { + setTransacoes(transacoes.map(t => + t.isDuplicada ? t : { ...t, selecionada: false } + )); + }; + return { transacoes, isProcessing, @@ -124,6 +149,9 @@ export const useImportacaoExtrato = () => { processarArquivo, importar, limpar, - atualizarCategoria + atualizarCategoria, + atualizarSelecao, + selecionarTodas, + desselecionarTodas }; }; diff --git a/src/pages/ImportarExtrato.tsx b/src/pages/ImportarExtrato.tsx index 8077bd9..1481903 100644 --- a/src/pages/ImportarExtrato.tsx +++ b/src/pages/ImportarExtrato.tsx @@ -22,7 +22,18 @@ const ImportarExtrato = () => { const [resultadoDialog, setResultadoDialog] = useState(false); const [logImportacao, setLogImportacao] = useState(null); - const { transacoes, isProcessing, isImporting, processarArquivo, importar, limpar, atualizarCategoria } = useImportacaoExtrato(); + const { + transacoes, + isProcessing, + isImporting, + processarArquivo, + importar, + limpar, + atualizarCategoria, + atualizarSelecao, + selecionarTodas, + desselecionarTodas + } = useImportacaoExtrato(); const { contas, isLoading, criar, recarregar } = useContasBancarias(); const handleFileSelect = async (file: File) => { @@ -55,8 +66,15 @@ const ImportarExtrato = () => { const tipoArquivo = detectarTipoArquivo(arquivo.name); if (!tipoArquivo) return; + // Filtrar apenas transações selecionadas + const transacoesSelecionadas = transacoes.filter(t => t.selecionada && !t.isDuplicada); + + if (transacoesSelecionadas.length === 0) { + return; + } + try { - const log = await importar(transacoes, contaSelecionada, arquivo.name, tipoArquivo); + const log = await importar(transacoesSelecionadas, contaSelecionada, arquivo.name, tipoArquivo); setLogImportacao(log); setResultadoDialog(true); @@ -80,6 +98,7 @@ const ImportarExtrato = () => { }; const novasTransacoes = transacoes.filter(t => !t.isDuplicada); + const transacoesSelecionadas = transacoes.filter(t => t.selecionada && !t.isDuplicada); return (
@@ -154,6 +173,9 @@ const ImportarExtrato = () => { @@ -163,11 +185,11 @@ const ImportarExtrato = () => {
diff --git a/src/types/importacaoTypes.ts b/src/types/importacaoTypes.ts index a4d4963..f786b94 100644 --- a/src/types/importacaoTypes.ts +++ b/src/types/importacaoTypes.ts @@ -19,6 +19,7 @@ export interface TransacaoImportada { categoria?: string; hash_unico: string; isDuplicada?: boolean; + selecionada?: boolean; } export interface LogImportacao {