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 */}
+
+
+ {/* Dialog para adicionar nova despesa */}
+
+ >
+ );
+}
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 */}
-
-
- {/* Dialog para adicionar nova despesa */}
-
);
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