From df6ee93e0104f5dd2efe5101a430d762b66cddfd Mon Sep 17 00:00:00 2001 From: "gpt-engineer-app[bot]" <159125892+gpt-engineer-app[bot]@users.noreply.github.com> Date: Wed, 21 May 2025 00:54:15 +0000 Subject: [PATCH] Refactor: Split CartoesCredito.tsx into components Refactors the CartoesCreditoPage into smaller, reusable components to improve code organization and maintainability. --- src/components/credito/CartaoActions.tsx | 107 +++++++++++++ src/components/credito/CartaoDetalhes.tsx | 23 +++ src/components/credito/CartaoListView.tsx | 19 +++ src/components/credito/CartaoSummaryCard.tsx | 29 ++++ src/pages/CartoesCredito.tsx | 149 +++---------------- src/services/cartao/cartoesService.ts | 26 +--- src/services/cartao/despesasService.ts | 15 +- 7 files changed, 213 insertions(+), 155 deletions(-) create mode 100644 src/components/credito/CartaoActions.tsx create mode 100644 src/components/credito/CartaoDetalhes.tsx create mode 100644 src/components/credito/CartaoListView.tsx create mode 100644 src/components/credito/CartaoSummaryCard.tsx diff --git a/src/components/credito/CartaoActions.tsx b/src/components/credito/CartaoActions.tsx new file mode 100644 index 0000000..464ed40 --- /dev/null +++ b/src/components/credito/CartaoActions.tsx @@ -0,0 +1,107 @@ + +import { Button } from "@/components/ui/button"; +import { PlusCircle, ArrowLeft } from "lucide-react"; +import { useState } from "react"; +import { CartaoCredito } from "@/types/cartaoTypes"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; +import { CartaoCreditoForm } from "@/components/credito/CartaoCreditoForm"; +import { DespesaCartaoForm } from "@/components/credito/DespesaCartaoForm"; + +interface CartaoActionsProps { + isDetalhes: boolean; + cartaoSelecionado: CartaoCredito | null; + onVoltarParaLista: () => void; + onCartaoSuccess: () => void; + onDespesaSuccess: () => void; +} + +export function CartaoActions({ + isDetalhes, + cartaoSelecionado, + onVoltarParaLista, + onCartaoSuccess, + onDespesaSuccess +}: CartaoActionsProps) { + const [isDialogNovoCartaoOpen, setIsDialogNovoCartaoOpen] = useState(false); + const [isDialogNovaDespesaOpen, setIsDialogNovaDespesaOpen] = useState(false); + + return ( + <> +
+ {isDetalhes ? ( +
+ +

+ {cartaoSelecionado?.nome} +

+
+ ) : ( +

Cartões de Crédito

+ )} + + +
+ + {/* Dialog para adicionar novo cartão */} + + + + Novo Cartão de Crédito + + Preencha as informações para cadastrar um novo cartão de crédito. + + + { + setIsDialogNovoCartaoOpen(false); + onCartaoSuccess(); + }} + onCancel={() => setIsDialogNovoCartaoOpen(false)} + /> + + + + {/* Dialog para adicionar nova despesa */} + + + + Nova Despesa do Cartão + + Preencha as informações para registrar uma nova despesa. + + + {cartaoSelecionado && ( + { + setIsDialogNovaDespesaOpen(false); + onDespesaSuccess(); + }} + onCancel={() => setIsDialogNovaDespesaOpen(false)} + /> + )} + + + + ); +} diff --git a/src/components/credito/CartaoDetalhes.tsx b/src/components/credito/CartaoDetalhes.tsx new file mode 100644 index 0000000..831f621 --- /dev/null +++ b/src/components/credito/CartaoDetalhes.tsx @@ -0,0 +1,23 @@ + +import { CartaoCredito, DespesaCartao } from "@/types/cartaoTypes"; +import { CartaoSummaryCard } from "./CartaoSummaryCard"; +import { DespesasList } from "./DespesasList"; + +interface CartaoDetalhesProps { + cartao: CartaoCredito; + despesas: DespesaCartao[]; + isLoading: boolean; +} + +export function CartaoDetalhes({ cartao, despesas, isLoading }: CartaoDetalhesProps) { + return ( +
+ + +
+

Despesas do Cartão

+ +
+
+ ); +} diff --git a/src/components/credito/CartaoListView.tsx b/src/components/credito/CartaoListView.tsx new file mode 100644 index 0000000..40dc998 --- /dev/null +++ b/src/components/credito/CartaoListView.tsx @@ -0,0 +1,19 @@ + +import { CartaoCredito } from "@/types/cartaoTypes"; +import { CartaoCreditoList } from "./CartaoCreditoList"; + +interface CartaoListViewProps { + cartoes: CartaoCredito[]; + isLoading: boolean; + onCartaoClick: (cartao: CartaoCredito) => void; +} + +export function CartaoListView({ cartoes, isLoading, onCartaoClick }: CartaoListViewProps) { + return ( + + ); +} diff --git a/src/components/credito/CartaoSummaryCard.tsx b/src/components/credito/CartaoSummaryCard.tsx new file mode 100644 index 0000000..e205b88 --- /dev/null +++ b/src/components/credito/CartaoSummaryCard.tsx @@ -0,0 +1,29 @@ + +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; + +interface CartaoSummaryCardProps { + totalDespesas: number; +} + +export function CartaoSummaryCard({ totalDespesas }: CartaoSummaryCardProps) { + const formatCurrency = (value: number = 0) => { + return new Intl.NumberFormat('pt-BR', { + style: 'currency', + currency: 'BRL', + }).format(value); + }; + + return ( + + + Resumo + Total de despesas do cartão + + +

+ {formatCurrency(totalDespesas)} +

+
+
+ ); +} diff --git a/src/pages/CartoesCredito.tsx b/src/pages/CartoesCredito.tsx index 53e55c3..4723ab0 100644 --- a/src/pages/CartoesCredito.tsx +++ b/src/pages/CartoesCredito.tsx @@ -1,37 +1,18 @@ import { useState, useEffect } from 'react'; import Layout from '@/components/layout/Layout'; -import { CartaoCreditoForm } from '@/components/credito/CartaoCreditoForm'; -import { DespesaCartaoForm } from '@/components/credito/DespesaCartaoForm'; -import { CartaoCreditoList } from '@/components/credito/CartaoCreditoList'; -import { DespesasList } from '@/components/credito/DespesasList'; import { CartaoCredito, DespesaCartao } from '@/types/cartaoTypes'; import { getCartoes, getDespesasCartao } from '@/services/cartaoCreditoService'; -import { Button } from '@/components/ui/button'; import { useToast } from "@/components/ui/use-toast"; -import { PlusCircle, ArrowLeft } from 'lucide-react'; -import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, -} from "@/components/ui/dialog"; -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle, -} from "@/components/ui/card"; +import { CartaoActions } from '@/components/credito/CartaoActions'; +import { CartaoDetalhes } from '@/components/credito/CartaoDetalhes'; +import { CartaoListView } from '@/components/credito/CartaoListView'; const CartoesCreditoPage = () => { const [cartoes, setCartoes] = useState([]); const [cartaoSelecionado, setCartaoSelecionado] = useState(null); const [despesas, setDespesas] = useState([]); const [isLoading, setIsLoading] = useState(true); - const [isDialogNovoCartaoOpen, setIsDialogNovoCartaoOpen] = useState(false); - const [isDialogNovaDespesaOpen, setIsDialogNovaDespesaOpen] = useState(false); const [detalheCartaoAberto, setDetalheCartaoAberto] = useState(false); const { toast } = useToast(); @@ -74,7 +55,6 @@ const CartoesCreditoPage = () => { }; const handleCartaoSuccess = () => { - setIsDialogNovoCartaoOpen(false); loadCartoes(); toast({ title: "Cartão adicionado", @@ -83,7 +63,6 @@ const CartoesCreditoPage = () => { }; const handleDespesaSuccess = () => { - setIsDialogNovaDespesaOpen(false); // Recarregar detalhes do cartão após adicionar despesa if (cartaoSelecionado) { loadDespesasCartao(cartaoSelecionado.id); @@ -108,114 +87,30 @@ const CartoesCreditoPage = () => { setDespesas([]); }; - const formatCurrency = (value: number = 0) => { - return new Intl.NumberFormat('pt-BR', { - style: 'currency', - currency: 'BRL', - }).format(value); - }; - return (
+ + {!detalheCartaoAberto ? ( - // Tela de listagem de cartões - <> -
-

Cartões de Crédito

- -
- - - - ) : ( - // Tela de detalhes de um cartão específico - <> -
-
- -

- {cartaoSelecionado?.nome} -

-
- -
- - - - Resumo - Total de despesas do cartão - - -

- {formatCurrency(cartaoSelecionado?.total_despesas)} -

-
-
- -
-

Despesas do Cartão

- -
- + + ) : cartaoSelecionado && ( + )} - - {/* Dialog para adicionar novo cartão */} - - - - Novo Cartão de Crédito - - Preencha as informações para cadastrar um novo cartão de crédito. - - - setIsDialogNovoCartaoOpen(false)} - /> - - - - {/* Dialog para adicionar nova despesa */} - - - - Nova Despesa do Cartão - - Preencha as informações para registrar uma nova despesa. - - - {cartaoSelecionado && ( - setIsDialogNovaDespesaOpen(false)} - /> - )} - -
); diff --git a/src/services/cartao/cartoesService.ts b/src/services/cartao/cartoesService.ts index dc05b9c..05fd95c 100644 --- a/src/services/cartao/cartoesService.ts +++ b/src/services/cartao/cartoesService.ts @@ -1,4 +1,3 @@ - import { supabase } from "@/integrations/supabase/client"; import { CartaoCredito } from "@/types/cartaoTypes"; import { gerarCartaoCodigo } from "./cartaoCodigoUtils"; @@ -33,28 +32,19 @@ export async function getCartoes(): Promise { // Garantir que todos os dados têm os campos necessários da interface CartaoCredito const cartoesCompletos = data.map(cartao => { - const cartaoCompleto = { ...cartao } as CartaoCredito; - - // Se não tiver cartao_codigo, gerar um código temporário baseado no id - if (!cartaoCompleto.cartao_codigo) { - cartaoCompleto.cartao_codigo = `cartao_${cartaoCompleto.id.substring(0, 8)}`; - } - - // Se não tiver bandeira ou banco, adicionar valores padrão - if (!cartaoCompleto.bandeira) { - cartaoCompleto.bandeira = 'Não especificada'; - } - - if (!cartaoCompleto.banco) { - cartaoCompleto.banco = 'Não especificado'; - } + const cartaoCompleto = { + ...cartao, + bandeira: cartao.bandeira || 'Não especificada', + banco: cartao.banco || 'Não especificado', + cartao_codigo: cartao.cartao_codigo || `cartao_${cartao.id.substring(0, 8)}` + } as CartaoCredito; return cartaoCompleto; }); - // Buscar o total de despesas para cada cartão + // Buscar o total de despesas para cada cartão - Promise.all já tipa corretamente o retorno const cartoesComTotal = await Promise.all( - cartoesCompletos.map(async (cartao: CartaoCredito) => { + cartoesCompletos.map(async (cartao) => { const total = await getTotalDespesasCartao(cartao.cartao_codigo); return { ...cartao, total_despesas: total }; }) diff --git a/src/services/cartao/despesasService.ts b/src/services/cartao/despesasService.ts index a4cb84a..3132b8e 100644 --- a/src/services/cartao/despesasService.ts +++ b/src/services/cartao/despesasService.ts @@ -1,4 +1,3 @@ - import { supabase } from "@/integrations/supabase/client"; import { DespesaCartao } from "@/types/cartaoTypes"; import { getCartao } from "./cartoesService"; @@ -41,13 +40,10 @@ export async function getDespesasCartao(cartaoId: string): Promise { - const despesaCompleta = { ...despesa } as DespesaCartao; - if (!despesaCompleta.cartao_codigo) { - despesaCompleta.cartao_codigo = cartao.cartao_codigo; - } - return despesaCompleta; - }); + const despesasCompletas = data.map(despesa => ({ + ...despesa, + cartao_codigo: despesa.cartao_codigo || cartao.cartao_codigo + })) as DespesaCartao[]; return despesasCompletas; } catch (error) { @@ -132,8 +128,7 @@ export async function getTotalDespesasCartao(cartaoCodigo: string): Promise