diff --git a/src/pages/Calendario.tsx b/src/pages/Calendario.tsx index 1f7838f..d3dc4f7 100644 --- a/src/pages/Calendario.tsx +++ b/src/pages/Calendario.tsx @@ -1,6 +1,5 @@ import { useState, useEffect } from 'react'; -import Layout from '@/components/layout/Layout'; import { Card, CardContent } from '@/components/ui/card'; import { Calendar } from "@/components/ui/calendar"; import { getTransacoes } from '@/services/transacaoService'; @@ -66,85 +65,83 @@ const CalendarioPage = () => { }; return ( - -
-
-

Calendário de Transações

-
- -
- - - hasDayTransaction(date), - }} - modifiersStyles={{ - hasTransaction: { - fontWeight: "bold", - textDecoration: "underline", - backgroundColor: "rgba(16, 185, 129, 0.1)" - } - }} - /> -
- Dias com transações estão destacados -
-
-
- - - -

- {selectedDate ? format(selectedDate, "dd 'de' MMMM 'de' yyyy", { locale: ptBR }) : "Selecione uma data"} -

- - {isLoading ? ( -
- {[1, 2, 3].map((i) => ( -
-
-
-
- ))} -
- ) : filteredTransactions.length === 0 ? ( -
- Nenhuma transação nesta data -
- ) : ( -
- {filteredTransactions.map((transaction) => ( -
-
-
{transaction.estabelecimento}
- - {transaction.tipo.toLowerCase() === 'receita' || transaction.tipo.toLowerCase() === 'entrada' ? 'Receita' : 'Despesa'} - -
-
{transaction.detalhes}
-
- {transaction.categoria} - - {transaction.tipo.toLowerCase() === 'receita' || transaction.tipo.toLowerCase() === 'entrada' - ? formatCurrency(Math.abs(transaction.valor)) - : `-${formatCurrency(Math.abs(transaction.valor))}`} - -
-
- ))} -
- )} -
-
-
+
+
+

Calendário de Transações

- + +
+ + + hasDayTransaction(date), + }} + modifiersStyles={{ + hasTransaction: { + fontWeight: "bold", + textDecoration: "underline", + backgroundColor: "rgba(16, 185, 129, 0.1)" + } + }} + /> +
+ Dias com transações estão destacados +
+
+
+ + + +

+ {selectedDate ? format(selectedDate, "dd 'de' MMMM 'de' yyyy", { locale: ptBR }) : "Selecione uma data"} +

+ + {isLoading ? ( +
+ {[1, 2, 3].map((i) => ( +
+
+
+
+ ))} +
+ ) : filteredTransactions.length === 0 ? ( +
+ Nenhuma transação nesta data +
+ ) : ( +
+ {filteredTransactions.map((transaction) => ( +
+
+
{transaction.estabelecimento}
+ + {transaction.tipo.toLowerCase() === 'receita' || transaction.tipo.toLowerCase() === 'entrada' ? 'Receita' : 'Despesa'} + +
+
{transaction.detalhes}
+
+ {transaction.categoria} + + {transaction.tipo.toLowerCase() === 'receita' || transaction.tipo.toLowerCase() === 'entrada' + ? formatCurrency(Math.abs(transaction.valor)) + : `-${formatCurrency(Math.abs(transaction.valor))}`} + +
+
+ ))} +
+ )} +
+
+
+
); }; diff --git a/src/pages/CartoesCredito.tsx b/src/pages/CartoesCredito.tsx index e13bb30..2340153 100644 --- a/src/pages/CartoesCredito.tsx +++ b/src/pages/CartoesCredito.tsx @@ -1,6 +1,5 @@ import { useState, useEffect } from 'react'; -import Layout from '@/components/layout/Layout'; import { CartaoCredito, DespesaCartao } from '@/types/cartaoTypes'; import { getCartoes, getDespesasCartao, getTotalDespesasCartao } from '@/services/cartaoCreditoService'; import { useToast } from "@/components/ui/use-toast"; @@ -107,32 +106,30 @@ const CartoesCreditoPage = () => { }, []); return ( - -
- + + + {!detalheCartaoAberto ? ( + + ) : cartaoSelecionado && ( + - - {!detalheCartaoAberto ? ( - - ) : cartaoSelecionado && ( - - )} -
-
+ )} +
); }; diff --git a/src/pages/Categorias.tsx b/src/pages/Categorias.tsx index 7545a39..dd575d9 100644 --- a/src/pages/Categorias.tsx +++ b/src/pages/Categorias.tsx @@ -1,6 +1,6 @@ + import { useState, useEffect } from 'react'; -import Layout from '@/components/layout/Layout'; -import { CardSpotlight } from '@/components/ui/card-spotlight'; +import { Card, CardContent } from '@/components/ui/card'; import { getCategorySummary } from '@/services/transacao'; import { CategorySummary } from '@/types/financialTypes'; import { useToast } from "@/components/ui/use-toast"; @@ -98,102 +98,110 @@ const CategoriasPage = () => { {isLoading ? (
{[1, 2, 3, 4, 5, 6].map((i) => ( - -
-
-
-
-
-
-
-
+ + +
+
+
+
+
+
+
+
+
))}
) : categories.length === 0 ? ( - -
-

Nenhuma categoria encontrada

-

- {tipoFiltro === 'despesa' - ? 'Verifique se existem transações do tipo "despesa" cadastradas' - : tipoFiltro === 'receita' - ? 'Verifique se existem transações do tipo "receita" cadastradas' - : 'Verifique se existem transações cadastradas'} -

-
-
+ + +
+

Nenhuma categoria encontrada

+

+ {tipoFiltro === 'despesa' + ? 'Verifique se existem transações do tipo "despesa" cadastradas' + : tipoFiltro === 'receita' + ? 'Verifique se existem transações do tipo "receita" cadastradas' + : 'Verifique se existem transações cadastradas'} +

+
+
+
) : ( <>
{categories.map((category) => ( - -
-
- - {category.categoria} -
-
-
-
- {formatCurrency(category.valor)} -
-
- -
- {(category.percentage * 100).toFixed(1)}% do total + + +
+
+ + {category.categoria}
-
- +
+
+ {formatCurrency(category.valor)} +
+
+ +
+ {(category.percentage * 100).toFixed(1)}% do total +
+
+
+ + ))}
- -
-

Resumo de Categorias {tipoFiltro !== 'all' ? (tipoFiltro === 'despesa' ? '(Despesas)' : '(Receitas)') : ''}

-
-
- - - - Categoria - Valor - Percentual - - - - {categories.map((category) => ( - - - - {category.categoria} - - {formatCurrency(category.valor)} - {(category.percentage * 100).toFixed(1)}% + + +
+

Resumo de Categorias {tipoFiltro !== 'all' ? (tipoFiltro === 'despesa' ? '(Despesas)' : '(Receitas)') : ''}

+
+
+
+ + + Categoria + Valor + Percentual - ))} - - Total - {formatCurrency(totalGastos)} - 100% - - -
-
-
+ + + {categories.map((category) => ( + + + + {category.categoria} + + {formatCurrency(category.valor)} + {(category.percentage * 100).toFixed(1)}% + + ))} + + Total + {formatCurrency(totalGastos)} + 100% + + + +
+ + )}
diff --git a/src/pages/GruposWhatsApp.tsx b/src/pages/GruposWhatsApp.tsx index 5c464d1..f314446 100644 --- a/src/pages/GruposWhatsApp.tsx +++ b/src/pages/GruposWhatsApp.tsx @@ -1,6 +1,5 @@ import { useState, useEffect } from 'react'; -import Layout from '@/components/layout/Layout'; import { Button } from '@/components/ui/button'; import { RefreshCw } from 'lucide-react'; import { listarGruposWhatsApp } from '@/services/gruposWhatsAppService'; @@ -65,31 +64,29 @@ const GruposWhatsApp = () => { }, []); return ( - -
-
-

Grupos do WhatsApp

-
- -
+
+
+

Grupos do WhatsApp

+
+
- - -
- + + + +
); }; diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 2f7a738..f0450c0 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -1,228 +1,178 @@ import { useState, useEffect } from 'react'; -import Layout from '@/components/layout/Layout'; -import SummaryCard from '@/components/dashboard/SummaryCard'; -import TransactionsTable from '@/components/dashboard/TransactionsTable'; -import CategoryChart from '@/components/dashboard/CategoryChart'; -import MonthlyChart from '@/components/dashboard/MonthlyChart'; -import { MonthFilter } from '@/components/filters/MonthFilter'; -import { OnboardingTour, useOnboardingTour } from '@/components/onboarding'; -import { Wallet, ArrowUp, ArrowDown, PiggyBank } from 'lucide-react'; -import { Transaction, CategorySummary, MonthlyData } from '@/types/financialTypes'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { useToast } from "@/components/ui/use-toast"; -import { - getTransacoes, - getTransactionSummary, - getCategorySummary, - getMonthlyData -} from '@/services/transacao'; -import { getCartoes } from '@/services/cartaoCreditoService'; +import { ArrowUpIcon, ArrowDownIcon, CreditCardIcon, Target } from "lucide-react"; +import { getResumoFinanceiro } from "@/services/transacao"; +import { ResumoFinanceiro } from "@/types/financialTypes"; +import TransactionsTable from "@/components/dashboard/TransactionsTable"; +import { useTransactions } from "@/hooks/useTransactions"; +import CategoryChart from "@/components/dashboard/CategoryChart"; const Dashboard = () => { + const [resumo, setResumo] = useState(null); const [isLoading, setIsLoading] = useState(true); - const [transactions, setTransactions] = useState([]); - const [categories, setCategories] = useState([]); - const [monthlyData, setMonthlyData] = useState([]); - const [totals, setTotals] = useState({ receitas: 0, despesas: 0, saldo: 0, cartoes: 0 }); const { toast } = useToast(); - // Hook do tour de onboarding - const { - isOpen: tourIsOpen, - currentStep: tourCurrentStep, - nextStep: tourNextStep, - skipTour, - closeTour - } = useOnboardingTour(); - - // Função para obter o mês atual no formato YYYY-MM const getCurrentMonth = () => { const now = new Date(); return `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}`; }; - const [selectedMonth, setSelectedMonth] = useState(getCurrentMonth()); + const { + transactions, + isLoading: transactionsLoading, + formatCurrency + } = useTransactions({ monthFilter: getCurrentMonth() }); - // Load data when component mounts or month changes useEffect(() => { - async function loadData() { - try { - setIsLoading(true); - console.log("🚀 [Dashboard] Iniciando carregamento de dados para o mês:", selectedMonth); - - // Verificar se existe email no localStorage - const userEmail = localStorage.getItem('userEmail'); - console.log("📧 [Dashboard] Email no localStorage:", userEmail); - - if (!userEmail) { - console.error("❌ [Dashboard] Email não encontrado no localStorage!"); - toast({ - title: "Erro de autenticação", - description: "Email do usuário não encontrado. Faça login novamente.", - variant: "destructive" - }); - return; - } - - // Buscar todos os dados necessários com filtro de mês - console.log("📊 [Dashboard] Buscando dados do Supabase..."); - const [transacoesData, totalsData, categoriesData, monthlyDataResult, cartoesData] = await Promise.all([ - getTransacoes(selectedMonth), - getTransactionSummary(selectedMonth), - getCategorySummary('despesa', selectedMonth), - getMonthlyData(), // Monthly data não precisa de filtro pois já mostra todos os meses - getCartoes() - ]); - - // Calcular total dos cartões - const totalCartoes = cartoesData.reduce((sum, cartao) => sum + (cartao.total_despesas || 0), 0); - - console.log("✅ [Dashboard] Dados obtidos com sucesso:", { - transacoes: transacoesData.length, - totals: totalsData, - categories: categoriesData.length, - monthlyData: monthlyDataResult.length, - cartoes: cartoesData.length, - totalCartoes: totalCartoes, - mesEscolhido: selectedMonth - }); - - setTransactions(transacoesData); - setTotals({ - ...totalsData, - cartoes: totalCartoes, - // Atualiza o saldo incluindo despesas de cartão - saldo: totalsData.receitas - totalsData.despesas - totalCartoes - }); - setCategories(categoriesData); - setMonthlyData(monthlyDataResult); - - if (transacoesData.length > 0 || categoriesData.length > 0 || monthlyDataResult.length > 0) { - toast({ - title: "Dados carregados com sucesso", - description: `${transacoesData.length} transações encontradas para ${selectedMonth}` - }); - } else { - toast({ - title: "Nenhum dado encontrado", - description: `Não foram encontradas transações para ${selectedMonth}`, - variant: "destructive" - }); - } - } catch (error) { - console.error("💥 [Dashboard] Erro ao carregar dados:", error); - toast({ - title: "Erro ao carregar dados", - description: "Verifique a conexão com o Supabase", - variant: "destructive" - }); - } finally { - setIsLoading(false); - } - } + const storedUserId = localStorage.getItem('userId'); + const finDashUser = localStorage.getItem('finDashUser'); - loadData(); - }, [selectedMonth, toast]); + if (!storedUserId && finDashUser) { + localStorage.setItem('userId', finDashUser); + } else if (!storedUserId && !finDashUser) { + const defaultId = '9f267008-9128-4a2f-b730-de0a0b5602a9'; + localStorage.setItem('userId', defaultId); + } + }, []); - const formatCurrency = (value: number) => { - return new Intl.NumberFormat('pt-BR', { - style: 'currency', - currency: 'BRL', - }).format(value); + const loadResumo = async () => { + try { + setIsLoading(true); + console.log("Carregando resumo financeiro..."); + const data = await getResumoFinanceiro(); + console.log("Resumo carregado:", data); + setResumo(data); + } catch (error) { + console.error("Erro ao carregar resumo:", error); + toast({ + title: "Erro ao carregar resumo", + description: "Não foi possível obter os dados do Supabase", + variant: "destructive" + }); + } finally { + setIsLoading(false); + } }; - // Calculate total of all expenses (regular + credit cards) - const totalDespesasGeral = totals.despesas + totals.cartoes; + useEffect(() => { + loadResumo(); + }, [toast]); - // Função para formatar o mês para exibição - const formatMonthDisplay = (month: string) => { - const [year, monthNum] = month.split('-'); - const months = [ - 'Janeiro', 'Fevereiro', 'Março', 'Abril', 'Maio', 'Junho', - 'Julho', 'Agosto', 'Setembro', 'Outubro', 'Novembro', 'Dezembro' - ]; - return `${months[parseInt(monthNum) - 1]} ${year}`; - }; - - return ( - + if (isLoading) { + return (
-
-
-

Dashboard Financeiro

-

- Dados de: {formatMonthDisplay(selectedMonth)} -

-
-
- -
-
- - {/* Resumo em cards */} -
- } - trend={5} - iconClass="bg-green-100" - valueClass="text-green-700" - className="border-green-200 shadow-lg" - /> - } - trend={-2} - iconClass="bg-red-100" - valueClass="text-red-700" - className="border-red-200 shadow-lg" - /> - } - iconClass="bg-blue-100" - valueClass="text-blue-700" - className="border-blue-200 shadow-lg" - /> - 0 ? ((totals.saldo / totals.receitas) * 100).toFixed(1) : 0}%`} - secondaryValue={formatCurrency(totals.saldo)} - icon={} - iconClass="bg-purple-100" - valueClass="text-purple-700" - className="border-purple-200 shadow-lg" - /> -
- - {/* ---- GRÁFICOS EM COLUNA ---- */} -
- - -
- -
-

Transações Recentes

- +
+ {[1, 2, 3, 4].map((i) => ( + + +
+
+
+ +
+
+
+
+ ))}
+ ); + } - {/* Tour de Onboarding */} - - + return ( +
+
+

Dashboard

+
+ +
+ + + Total Receitas + + + +
+ {resumo ? formatCurrency(resumo.totalReceitas) : 'R$ 0,00'} +
+

Entradas do mês

+
+
+ + + + Total Despesas + + + +
+ {resumo ? formatCurrency(resumo.totalDespesas) : 'R$ 0,00'} +
+

Saídas do mês

+
+
+ + + + Cartões de Crédito + + + +
+ {resumo ? formatCurrency(resumo.totalCartoes || 0) : 'R$ 0,00'} +
+

Gastos nos cartões

+
+
+ + + + Saldo + + + +
= 0 + ? 'text-green-600' + : 'text-red-600' + }`}> + {resumo ? formatCurrency(resumo.totalReceitas - resumo.totalDespesas - (resumo.totalCartoes || 0)) : 'R$ 0,00'} +
+

Resultado do mês

+
+
+
+ +
+ + + Despesas por Categoria + Distribuição dos seus gastos + + + + + + + + + Últimas Transações + Suas transações mais recentes + + + {}} + onDelete={() => {}} + /> + + +
+
); }; diff --git a/src/pages/Metas.tsx b/src/pages/Metas.tsx index 922c28d..caa1c9d 100644 --- a/src/pages/Metas.tsx +++ b/src/pages/Metas.tsx @@ -1,78 +1,31 @@ import { useState, useEffect } from 'react'; -import { format } from 'date-fns'; -import { ptBR } from 'date-fns/locale'; -import Layout from '@/components/layout/Layout'; -import { MetasForm } from '@/components/dashboard/MetasForm'; -import { MetaProgressCard } from '@/components/dashboard/MetaProgressCard'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'; import { Button } from '@/components/ui/button'; -import { Card } from '@/components/ui/card'; -import { ResultadoMeta } from '@/types/financialTypes'; -import { useToast } from '@/components/ui/use-toast'; -import { calcularResultadosMetas, getMeta, deletarMeta } from '@/services/metasService'; -import { PlusCircle } from 'lucide-react'; -import { - Dialog, - DialogContent, - DialogDescription, - DialogHeader, - DialogTitle, -} from '@/components/ui/dialog'; -import { - AlertDialog, - AlertDialogAction, - AlertDialogCancel, - AlertDialogContent, - AlertDialogDescription, - AlertDialogFooter, - AlertDialogHeader, - AlertDialogTitle, -} from '@/components/ui/alert-dialog'; +import { Plus } from 'lucide-react'; +import { MetaFinanceira } from '@/types/financialTypes'; +import { getMetas } from '@/services/metasService'; +import { useToast } from '@/hooks/use-toast'; +import MetaForm from '@/components/metas/MetaForm'; +import MetaCard from '@/components/metas/MetaCard'; const MetasPage = () => { - const { toast } = useToast(); - const [userId, setUserId] = useState(''); - const [resultados, setResultados] = useState([]); + const [metas, setMetas] = useState([]); const [isLoading, setIsLoading] = useState(true); - const [isDialogOpen, setIsDialogOpen] = useState(false); - const [isDeleteDialogOpen, setIsDeleteDialogOpen] = useState(false); - const [metaParaEditar, setMetaParaEditar] = useState<{ mes: number, ano: number, id?: string } | null>(null); - const [metaParaDeletar, setMetaParaDeletar] = useState<{ mes: number, ano: number, id: string } | null>(null); - const [valorMetaAtual, setValorMetaAtual] = useState(0); - const [isDeletingMeta, setIsDeletingMeta] = useState(false); + const [showForm, setShowForm] = useState(false); + const [editingMeta, setEditingMeta] = useState(null); + const { toast } = useToast(); - useEffect(() => { - // Obter userId armazenado no localStorage - const storedUserId = localStorage.getItem('userId'); - if (storedUserId) { - setUserId(storedUserId); - loadData(storedUserId); - } else { - // Tentar usar finDashUser como fallback - const finDashUser = localStorage.getItem('finDashUser'); - if (finDashUser) { - setUserId(finDashUser); - loadData(finDashUser); - } else { - // Caso não encontre nenhum ID de usuário, usar um ID padrão temporário - const defaultId = '9f267008-9128-4a2f-b730-de0a0b5602a9'; - localStorage.setItem('userId', defaultId); - setUserId(defaultId); - loadData(defaultId); - } - } - }, []); - - const loadData = async (user: string) => { + const loadMetas = async () => { try { setIsLoading(true); - const resultado = await calcularResultadosMetas(user); - setResultados(resultado); + const data = await getMetas(); + setMetas(data); } catch (error) { console.error('Erro ao carregar metas:', error); toast({ - title: 'Erro ao carregar metas', - description: 'Não foi possível obter os dados de metas', + title: 'Erro', + description: 'Não foi possível carregar suas metas', variant: 'destructive', }); } finally { @@ -80,207 +33,107 @@ const MetasPage = () => { } }; - const handleEditarMeta = async (mes: number, ano: number) => { - try { - const meta = await getMeta(userId, mes, ano); - if (meta) { - setValorMetaAtual(meta.valor_meta); - setMetaParaEditar({ mes, ano, id: meta.id }); - setIsDialogOpen(true); - } - } catch (error) { - console.error('Erro ao buscar meta para edição:', error); - } + useEffect(() => { + loadMetas(); + }, []); + + const handleMetaSuccess = () => { + loadMetas(); + setShowForm(false); + setEditingMeta(null); + toast({ + title: 'Sucesso', + description: editingMeta ? 'Meta atualizada com sucesso' : 'Meta criada com sucesso', + }); }; - const handleDeletarMeta = (mes: number, ano: number, id: string) => { - setMetaParaDeletar({ mes, ano, id }); - setIsDeleteDialogOpen(true); + const handleEditMeta = (meta: MetaFinanceira) => { + setEditingMeta(meta); + setShowForm(true); }; - const confirmarDeletarMeta = async () => { - if (!metaParaDeletar?.id) return; - - try { - setIsDeletingMeta(true); - await deletarMeta(metaParaDeletar.id); - - // Atualizar lista de metas após deleção - await loadData(userId); - - toast({ - title: 'Meta excluída', - description: `A meta de ${format(new Date(metaParaDeletar.ano, metaParaDeletar.mes - 1, 1), 'MMMM', { locale: ptBR })} ${metaParaDeletar.ano} foi excluída com sucesso.`, - }); - } catch (error) { - console.error('Erro ao deletar meta:', error); - toast({ - title: 'Erro ao deletar meta', - description: 'Não foi possível excluir a meta', - variant: 'destructive', - }); - } finally { - setIsDeletingMeta(false); - setIsDeleteDialogOpen(false); - setMetaParaDeletar(null); - } + const handleDeleteSuccess = () => { + loadMetas(); + toast({ + title: 'Sucesso', + description: 'Meta excluída com sucesso', + }); }; - const handleNovaMeta = () => { - setMetaParaEditar(null); - setValorMetaAtual(0); - setIsDialogOpen(true); - }; - - const handleSuccess = () => { - setIsDialogOpen(false); - loadData(userId); - }; - - const getMesAtual = () => { - const now = new Date(); - return { - mes: now.getMonth() + 1, - ano: now.getFullYear(), - nome: format(now, 'MMMM', { locale: ptBR }), - }; - }; - - const mesAtual = getMesAtual(); - - // Agrupar por ano (objeto com chave = ano e valor = array de metas daquele ano) - const resultadosPorAno = resultados.reduce((acc, meta) => { - if (!acc[meta.ano]) { - acc[meta.ano] = []; - } - acc[meta.ano].push(meta); - return acc; - }, {} as Record); - - // Ordenar os anos de forma decrescente - const anosOrdenados = Object.keys(resultadosPorAno) - .map(Number) - .sort((a, b) => b - a); - return ( - -
-
-

Metas de Economia

- +
+
+
+

Metas Financeiras

+

Defina e acompanhe seus objetivos financeiros

- - {isLoading ? ( -
-
-
-

Carregando suas metas...

-
-
- ) : resultados.length === 0 ? ( - -

Nenhuma meta definida

-

- Defina sua primeira meta de economia para {mesAtual.nome} {mesAtual.ano} -

- -
- ) : ( - <> - {anosOrdenados.map(ano => ( -
-

{ano}

-
- {resultadosPorAno[ano] - .sort((a, b) => b.mes - a.mes) - .map(meta => ( - handleEditarMeta(meta.mes, meta.ano)} - onDeleteClick={() => { - // Aqui precisamos buscar o ID primeiro pois resultadoMeta não tem o ID - // Vamos usar o metaParaEditar.id que já foi carregado se o usuário clicou em editar antes - if (metaParaEditar && metaParaEditar.mes === meta.mes && metaParaEditar.ano === meta.ano && metaParaEditar.id) { - handleDeletarMeta(meta.mes, meta.ano, metaParaEditar.id); - } else { - // Buscar o ID antes de deletar - getMeta(userId, meta.mes, meta.ano).then(metaCompleta => { - if (metaCompleta && metaCompleta.id) { - handleDeletarMeta(meta.mes, meta.ano, metaCompleta.id); - } - }); - } - }} - /> - ))} -
-
- ))} - - )} - - - - - - {metaParaEditar ? 'Editar Meta' : 'Nova Meta'} - - - {metaParaEditar - ? 'Atualize os valores da sua meta de economia.' - : 'Defina uma nova meta de economia mensal.'} - - - setIsDialogOpen(false)} - userId={userId} - valorInicial={metaParaEditar ? valorMetaAtual : 0} - mesInicial={metaParaEditar?.mes} - anoInicial={metaParaEditar?.ano} - /> - - - - setShowForm(true)} + className="bg-blue-600 hover:bg-blue-700 text-white" > - - - - Confirmar exclusão - - - {metaParaDeletar && ( - `Tem certeza que deseja excluir a meta de ${format(new Date(metaParaDeletar.ano, metaParaDeletar.mes - 1, 1), 'MMMM', { locale: ptBR })} de ${metaParaDeletar.ano}? Esta ação não pode ser desfeita.` - )} - - - - Cancelar - - {isDeletingMeta ? 'Deletando...' : 'Deletar Meta'} - - - - + + Nova Meta +
- + + {showForm && ( + { + setShowForm(false); + setEditingMeta(null); + }} + /> + )} + + {isLoading ? ( +
+ {[1, 2, 3].map((i) => ( + + +
+
+
+ +
+
+
+
+
+
+ ))} +
+ ) : metas.length === 0 ? ( + + +
+ +
+

Nenhuma meta cadastrada

+

Comece criando sua primeira meta financeira

+ +
+
+ ) : ( +
+ {metas.map((meta) => ( + + ))} +
+ )} +
); }; diff --git a/src/pages/Transacoes.tsx b/src/pages/Transacoes.tsx index f092c77..efcad2d 100644 --- a/src/pages/Transacoes.tsx +++ b/src/pages/Transacoes.tsx @@ -1,6 +1,5 @@ import React, { useState } from 'react'; -import Layout from '@/components/layout/Layout'; import TransactionsTable from '@/components/dashboard/TransactionsTable'; import { useTransactions } from '@/hooks/useTransactions'; import { TransactionHeader } from '@/components/transacoes/TransactionHeader'; @@ -54,82 +53,80 @@ const TransacoesPage = () => { }; return ( - -
-
-
-

Transações

-

- Dados de: {formatMonthDisplay(selectedMonth)} -

- {/* Exibe mensagem para trial OU para admin-liberou */} - {!access.loading && access.podeAdicionarTransacao && ( - access.adminLiberou ? ( -
- {access.motivo} -
- ) : (access.diasRestantesTrial > 0 && ( -
- {`Você está em período gratuito. ${access.diasRestantesTrial} dia(s) restante(s) de teste.`} -
- )) - )} -
- +
+
+
+

Transações

+

+ Dados de: {formatMonthDisplay(selectedMonth)} +

+ {/* Exibe mensagem para trial OU para admin-liberou */} + {!access.loading && access.podeAdicionarTransacao && ( + access.adminLiberou ? ( +
+ {access.motivo} +
+ ) : (access.diasRestantesTrial > 0 && ( +
+ {`Você está em período gratuito. ${access.diasRestantesTrial} dia(s) restante(s) de teste.`} +
+ )) + )}
- - {/* Mensagem de bloqueio */} - {!access.loading && !access.podeAdicionarTransacao && ( -
- Atenção: {access.motivo} -
- )} - - {/* Só passa as funções de adicionar se permitido */} - {}} - onOpenCartaoCreditoDialog={access.podeAdicionarTransacao ? handleOpenCartaoCreditoDialog : () => {}} - disableAdicionar={!access.podeAdicionarTransacao} - /> - - {/* Resumo em Cards */} - - - {/* Tabela completa de transações */} -
-

Todas as Transações

- -
- - {/* Diálogos */} -
- + + {/* Mensagem de bloqueio */} + {!access.loading && !access.podeAdicionarTransacao && ( +
+ Atenção: {access.motivo} +
+ )} + + {/* Só passa as funções de adicionar se permitido */} + {}} + onOpenCartaoCreditoDialog={access.podeAdicionarTransacao ? handleOpenCartaoCreditoDialog : () => {}} + disableAdicionar={!access.podeAdicionarTransacao} + /> + + {/* Resumo em Cards */} + + + {/* Tabela completa de transações */} +
+

Todas as Transações

+ +
+ + {/* Diálogos */} + +
); }; diff --git a/src/pages/WhatsApp.tsx b/src/pages/WhatsApp.tsx index 002a9a1..baac31f 100644 --- a/src/pages/WhatsApp.tsx +++ b/src/pages/WhatsApp.tsx @@ -1,6 +1,5 @@ import { WhatsAppInstance } from '@/types/whatsAppTypes'; -import Layout from '@/components/layout/Layout'; import LoadingState from '@/components/whatsapp/LoadingState'; import WhatsAppHeader from '@/components/whatsapp/WhatsAppHeader'; import WhatsAppManager from '@/components/whatsapp/WhatsAppManager'; @@ -85,41 +84,37 @@ const WhatsApp = () => { if (checkingExistingInstance || isLoading) { return ( - - - + ); } return ( - -
- - - -
-
+
+ + + +
); };