Changes
This commit is contained in:
parent
7b919272b5
commit
681cf5aa26
@ -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 */}
|
||||
<Card className="p-6">
|
||||
<h3 className="text-lg font-semibold mb-4">Transações para Importar</h3>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<h3 className="text-lg font-semibold">Transações para Importar</h3>
|
||||
<div className="flex gap-2">
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={onSelectAll}
|
||||
>
|
||||
Selecionar Todas
|
||||
</Button>
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={onDeselectAll}
|
||||
>
|
||||
Desmarcar Todas
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="max-h-96 overflow-y-auto">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow>
|
||||
<TableHead className="w-12">
|
||||
<Checkbox
|
||||
checked={todasSelecionadas}
|
||||
onCheckedChange={(checked) => {
|
||||
if (checked) onSelectAll();
|
||||
else onDeselectAll();
|
||||
}}
|
||||
/>
|
||||
</TableHead>
|
||||
<TableHead>Data</TableHead>
|
||||
<TableHead>Descrição</TableHead>
|
||||
<TableHead>Categoria</TableHead>
|
||||
@ -118,6 +158,15 @@ export const PreviewTransacoes = ({ transacoes, onCategoriaChange }: PreviewTran
|
||||
key={transacao.hash_unico}
|
||||
className={transacao.isDuplicada ? 'opacity-50' : ''}
|
||||
>
|
||||
<TableCell>
|
||||
<Checkbox
|
||||
checked={transacao.selecionada ?? false}
|
||||
disabled={transacao.isDuplicada}
|
||||
onCheckedChange={(checked) =>
|
||||
onSelectionChange(transacao.hash_unico, checked as boolean)
|
||||
}
|
||||
/>
|
||||
</TableCell>
|
||||
<TableCell className="whitespace-nowrap">
|
||||
{formatDate(transacao.data)}
|
||||
</TableCell>
|
||||
|
||||
@ -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
|
||||
};
|
||||
};
|
||||
|
||||
@ -22,7 +22,18 @@ const ImportarExtrato = () => {
|
||||
const [resultadoDialog, setResultadoDialog] = useState(false);
|
||||
const [logImportacao, setLogImportacao] = useState<LogImportacao | null>(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 (
|
||||
<div className="min-h-screen bg-gradient-to-br from-background via-background to-muted/20 p-6">
|
||||
@ -154,6 +173,9 @@ const ImportarExtrato = () => {
|
||||
<PreviewTransacoes
|
||||
transacoes={transacoes}
|
||||
onCategoriaChange={atualizarCategoria}
|
||||
onSelectionChange={atualizarSelecao}
|
||||
onSelectAll={selecionarTodas}
|
||||
onDeselectAll={desselecionarTodas}
|
||||
/>
|
||||
|
||||
<Card className="p-6">
|
||||
@ -163,11 +185,11 @@ const ImportarExtrato = () => {
|
||||
</Button>
|
||||
<Button
|
||||
onClick={handleImportar}
|
||||
disabled={isImporting || novasTransacoes.length === 0}
|
||||
disabled={isImporting || transacoesSelecionadas.length === 0}
|
||||
size="lg"
|
||||
>
|
||||
<FileCheck className="w-5 h-5 mr-2" />
|
||||
{isImporting ? 'Importando...' : `Importar ${novasTransacoes.length} Transações`}
|
||||
{isImporting ? 'Importando...' : `Importar ${transacoesSelecionadas.length} Transações`}
|
||||
</Button>
|
||||
</div>
|
||||
</Card>
|
||||
|
||||
@ -19,6 +19,7 @@ export interface TransacaoImportada {
|
||||
categoria?: string;
|
||||
hash_unico: string;
|
||||
isDuplicada?: boolean;
|
||||
selecionada?: boolean;
|
||||
}
|
||||
|
||||
export interface LogImportacao {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user