diff --git a/src/App.tsx b/src/App.tsx index bec03ea..94773a1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -27,7 +27,6 @@ import Categorias from "./pages/Categorias"; import AdminFAQ from "./pages/AdminFAQ"; import Assinatura from "./pages/Assinatura"; import AvisosContas from "./pages/AvisosContas"; -import Admin from "./pages/Admin"; const queryClient = new QueryClient(); @@ -76,7 +75,6 @@ function App() { } /> } /> } /> - } /> } /> } /> diff --git a/src/components/dashboard/DashboardSummaryCards.tsx b/src/components/dashboard/DashboardSummaryCards.tsx index 8f5ff72..7cdb44a 100644 --- a/src/components/dashboard/DashboardSummaryCards.tsx +++ b/src/components/dashboard/DashboardSummaryCards.tsx @@ -1,88 +1,175 @@ -import React from 'react'; +import React, { useState, useEffect } from 'react'; import { Card, CardContent } from "@/components/ui/card"; import { ArrowUpIcon, ArrowDownIcon, CreditCardIcon, Target } from "lucide-react"; import { ResumoFinanceiro } from "@/types/financialTypes"; import { useNavigateWithFilter } from "@/hooks/useNavigateWithFilter"; +import { getResumoFinanceiro } from "@/services/transacao"; +import { + Tooltip, + TooltipContent, + TooltipProvider, + TooltipTrigger, +} from '@/components/ui/tooltip'; interface DashboardSummaryCardsProps { resumo: ResumoFinanceiro | null; formatCurrency: (value: number) => string; + selectedMonth?: string; } -const DashboardSummaryCards: React.FC = ({ resumo, formatCurrency }) => { +const DashboardSummaryCards: React.FC = ({ + resumo, + formatCurrency, + selectedMonth +}) => { const { navigateToTransactions } = useNavigateWithFilter(); + const [resumoAnterior, setResumoAnterior] = useState(null); const saldo = resumo ? resumo.totalReceitas - resumo.totalDespesas - (resumo.totalCartoes || 0) : 0; const totalGastos = resumo ? resumo.totalDespesas + (resumo.totalCartoes || 0) : 0; // Calcular economia baseada nas transações do mês - // Se há receitas, calcular quanto foi economizado (receitas - gastos totais) - // Se não há receitas, mostrar 0% de economia const economiaValor = resumo?.totalReceitas ? saldo : 0; const economiaPercentual = resumo?.totalReceitas && resumo.totalReceitas > 0 ? ((economiaValor / resumo.totalReceitas) * 100) : 0; + // Carregar dados do mês anterior para comparação + useEffect(() => { + const loadPreviousMonthData = async () => { + if (!selectedMonth) return; + + try { + const [year, month] = selectedMonth.split('-').map(Number); + const previousMonth = month === 1 ? 12 : month - 1; + const previousYear = month === 1 ? year - 1 : year; + const previousMonthFilter = `${previousYear}-${String(previousMonth).padStart(2, '0')}`; + + const data = await getResumoFinanceiro(previousMonthFilter); + setResumoAnterior(data); + } catch (error) { + console.error("Erro ao carregar dados do mês anterior:", error); + setResumoAnterior(null); + } + }; + + loadPreviousMonthData(); + }, [selectedMonth]); + + // Calcular variações percentuais + const calcularVariacao = (atual: number, anterior: number) => { + if (anterior === 0) return atual > 0 ? 100 : 0; + return ((atual - anterior) / anterior) * 100; + }; + + const variacaoReceitas = resumoAnterior + ? calcularVariacao(resumo?.totalReceitas || 0, resumoAnterior.totalReceitas) + : 0; + + const variacaoDespesas = resumoAnterior + ? calcularVariacao(resumo?.totalDespesas || 0, resumoAnterior.totalDespesas) + : 0; + return (
{/* Card Receitas - Clicável */} - navigateToTransactions('receita')} - > -
- -
-
- -
-
- +5% -
-
-
-

Receitas

-

- {resumo ? formatCurrency(resumo.totalReceitas) : 'R$ 0,00'} + + + + navigateToTransactions('receita')} + > +

+ +
+
+ +
+ {resumoAnterior && ( +
= 0 + ? 'bg-green-500 text-white' + : 'bg-red-500 text-white' + }`}> + {variacaoReceitas >= 0 ? '+' : ''}{variacaoReceitas.toFixed(1)}% +
+ )} +
+
+

Receitas

+

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

+

Clique para ver detalhes

+
+
+ + + +

+ {resumoAnterior + ? `Variação em relação ao mês anterior: ${variacaoReceitas >= 0 ? '+' : ''}${variacaoReceitas.toFixed(1)}%` + : 'Sem dados do mês anterior para comparação' + }

-

Clique para ver detalhes

-
- - + + + {/* Card Despesas - Clicável */} - navigateToTransactions('despesa')} - > -
- -
-
- -
-
- -2% -
-
-
-

Despesas

-

- {resumo ? formatCurrency(resumo.totalDespesas) : 'R$ 0,00'} + + + + navigateToTransactions('despesa')} + > +

+ +
+
+ +
+ {resumoAnterior && ( +
= 0 + ? 'bg-red-500 text-white' + : 'bg-green-500 text-white' + }`}> + {variacaoDespesas >= 0 ? '+' : ''}{variacaoDespesas.toFixed(1)}% +
+ )} +
+
+

Despesas

+

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

+ {resumo && resumo.totalCartoes && resumo.totalCartoes > 0 && ( +
+

+ Cartões: + {formatCurrency(resumo.totalCartoes)} +

+
+ )} +

Clique para ver detalhes

+
+
+ + + +

+ {resumoAnterior + ? `Variação em relação ao mês anterior: ${variacaoDespesas >= 0 ? '+' : ''}${variacaoDespesas.toFixed(1)}%` + : 'Sem dados do mês anterior para comparação' + }

- {resumo && resumo.totalCartoes && resumo.totalCartoes > 0 && ( -
-

- Cartões: - {formatCurrency(resumo.totalCartoes)} -

-
- )} -

Clique para ver detalhes

-
- - + + + {/* Card Saldo */} @@ -105,27 +192,36 @@ const DashboardSummaryCards: React.FC = ({ resumo, f {/* Card Economia */} - -
- -
-
- -
-
-
-

Economia

-

= 0 ? 'text-purple-600' : 'text-red-600' - }`}> - {economiaPercentual.toFixed(1)}% -

-

- {formatCurrency(Math.abs(economiaValor))} -

-
-
- + + + + +
+ +
+
+ +
+
+
+

Economia

+

= 0 ? 'text-purple-600' : 'text-red-600' + }`}> + {economiaPercentual.toFixed(1)}% +

+

+ {formatCurrency(Math.abs(economiaValor))} +

+
+
+ + + +

Percentual de economia: receitas que sobraram após todas as despesas

+
+ +
); }; diff --git a/src/components/layout/NewModernLayout.tsx b/src/components/layout/NewModernLayout.tsx index 51029fc..af15af6 100644 --- a/src/components/layout/NewModernLayout.tsx +++ b/src/components/layout/NewModernLayout.tsx @@ -15,6 +15,7 @@ import { SidebarFooter, SidebarTrigger, SidebarInset, + useSidebar, } from "@/components/ui/sidebar"; import { Home, @@ -24,17 +25,14 @@ import { Target, Calendar, Crown, - MessageSquareText, Users, Settings, - Bell, - Shield + Bell } from 'lucide-react'; import OnboardingTour from '@/components/onboarding/OnboardingTour'; import HelpIcon from '@/components/help/HelpIcon'; import UserProfileButton from '@/components/dashboard/UserProfileButton'; import { useOnboardingTour } from '@/hooks/useOnboardingTour'; -import { useAdminSettings } from '@/hooks/useAdminSettings'; import { Tooltip, TooltipContent, @@ -63,7 +61,7 @@ const Logo = () => { export default function NewModernLayout({ children }: NewModernLayoutProps) { const location = useLocation(); - const { isAdmin, hideWhatsAppButton } = useAdminSettings(); + const { toggleSidebar } = useSidebar(); const { isOpen: tourOpen, @@ -117,11 +115,6 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) { ]; const whatsappItems = [ - ...(hideWhatsAppButton ? [] : [{ - title: "Conectar WhatsApp", - url: "/whatsapp", - icon: MessageSquareText, - }]), { title: "Grupos", url: "/grupos-whatsapp", @@ -138,14 +131,6 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) { } ]; - const adminItems = isAdmin ? [ - { - title: "Admin", - url: "/admin", - icon: Shield, - } - ] : []; - return (
@@ -198,30 +183,6 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) { - - {adminItems.length > 0 && ( - - Administração - - - {adminItems.map((item) => ( - - - - - {item.title} - - - - ))} - - - - )} @@ -259,7 +220,12 @@ export default function NewModernLayout({ children }: NewModernLayoutProps) { - Menu + + Menu +
diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 3e339f3..e938f86 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -94,7 +94,8 @@ const Dashboard = () => {