diff --git a/src/components/dashboard/MonthlyChart.tsx b/src/components/dashboard/MonthlyChart.tsx index 59a501c..123c6a5 100644 --- a/src/components/dashboard/MonthlyChart.tsx +++ b/src/components/dashboard/MonthlyChart.tsx @@ -1,6 +1,5 @@ import React from 'react'; -import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { BarChart, Bar, @@ -48,6 +47,31 @@ const MonthlyChart: React.FC = ({ data, isLoading = false }) }).format(value); }; + // Criar dados para o ano completo (12 meses) + const generateFullYearData = () => { + const currentYear = new Date().getFullYear(); + const months = [ + 'Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', + 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez' + ]; + + const fullYearData = months.map((month, index) => { + const monthKey = `${currentYear}-${String(index + 1).padStart(2, '0')}`; + const existingData = data.find(d => d.month === monthKey); + + return { + month: month, + monthKey: monthKey, + receitas: existingData ? existingData.receitas : 0, + despesas: existingData ? existingData.despesas : 0 + }; + }); + + return fullYearData; + }; + + const fullYearData = generateFullYearData(); + const customTooltip = ({ active, payload, label }: any) => { if (active && payload && payload.length) { return ( @@ -64,7 +88,6 @@ const MonthlyChart: React.FC = ({ data, isLoading = false }) return null; }; - // Custom label component that only shows values above a threshold const CustomLabel = ({ x, y, width, value, dataKey }: any) => { if (!value || value < 100) return null; const isReceita = dataKey === 'receitas'; @@ -84,105 +107,94 @@ const MonthlyChart: React.FC = ({ data, isLoading = false }) }; return ( - - - - 📈 Receitas vs Despesas - - - - {isLoading ? ( -
-
-
- ) : data.length === 0 ? ( -
- Sem dados disponíveis -
- ) : ( -
- - + {isLoading ? ( +
+
+
+ ) : ( +
+ + + + + + + + } > - - - - - - } - > - {data.map((entry, index) => ( - - ))} - - } - > - {data.map((entry, index) => ( - - ))} - - - - - - - - - - - - - -
- )} - - + {fullYearData.map((entry, index) => ( + + ))} + + } + > + {fullYearData.map((entry, index) => ( + + ))} + + + + + + + + + + + + + +
+ )} +
); }; diff --git a/src/hooks/useNavigateWithFilter.ts b/src/hooks/useNavigateWithFilter.ts new file mode 100644 index 0000000..e4e6cf8 --- /dev/null +++ b/src/hooks/useNavigateWithFilter.ts @@ -0,0 +1,21 @@ + +import { useNavigate } from 'react-router-dom'; + +export const useNavigateWithFilter = () => { + const navigate = useNavigate(); + + const navigateToTransactions = (tipo?: 'receita' | 'despesa') => { + if (tipo) { + navigate('/transacoes', { + state: { + filter: tipo, + filterValue: tipo === 'receita' ? 'receita' : 'despesa' + } + }); + } else { + navigate('/transacoes'); + } + }; + + return { navigateToTransactions }; +}; diff --git a/src/pages/Index.tsx b/src/pages/Index.tsx index 817b7a4..43f1fd7 100644 --- a/src/pages/Index.tsx +++ b/src/pages/Index.tsx @@ -1,4 +1,3 @@ - import { useState, useEffect } from 'react'; import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"; import { useToast } from "@/hooks/use-toast"; @@ -10,6 +9,7 @@ import { useTransactions } from "@/hooks/useTransactions"; import CategoryChart from "@/components/dashboard/CategoryChart"; import MonthlyChart from "@/components/dashboard/MonthlyChart"; import { SimpleCard } from "@/components/ui/simple-card"; +import { useNavigateWithFilter } from "@/hooks/useNavigateWithFilter"; const Dashboard = () => { const [resumo, setResumo] = useState(null); @@ -17,6 +17,7 @@ const Dashboard = () => { const [monthlyData, setMonthlyData] = useState([]); const [isLoading, setIsLoading] = useState(true); const { toast } = useToast(); + const { navigateToTransactions } = useNavigateWithFilter(); const getCurrentMonth = () => { const now = new Date(); @@ -94,6 +95,7 @@ const Dashboard = () => { } const saldo = resumo ? resumo.totalReceitas - resumo.totalDespesas - (resumo.totalCartoes || 0) : 0; + const totalDespesasGeral = resumo ? resumo.totalDespesas + (resumo.totalCartoes || 0) : 0; return (
@@ -101,89 +103,113 @@ const Dashboard = () => {

Dashboard

-
- - - Receitas -
- +
+ {/* Card Receitas - Clicável */} + navigateToTransactions('receita')} + > +
+ +
+
+ +
+
+ +5% +
- - -
- {resumo ? formatCurrency(resumo.totalReceitas) : 'R$ 0,00'} -
-
- +5% +
+

Receitas

+

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

+

Clique para ver detalhes

- - - Despesas -
- + {/* Card Despesas - Clicável */} + navigateToTransactions('despesa')} + > +
+ +
+
+ +
+
+ -2% +
- - -
- {resumo ? formatCurrency(resumo.totalDespesas + (resumo.totalCartoes || 0)) : 'R$ 0,00'} -
-
- -2% -
- {resumo && resumo.totalCartoes > 0 && ( -

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

- )} -
- - - - - Saldo -
- -
-
- -
= 0 ? 'text-blue-600' : 'text-red-600' - }`}> - {resumo ? formatCurrency(saldo) : 'R$ 0,00'} +
+

Despesas

+

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

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

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

+ )} +

Clique para ver detalhes

- - - Economia -
- + {/* Card Saldo */} + +
+ +
+
+ +
- - -
- -22.2% +
+

Saldo

+

= 0 ? 'text-blue-600' : 'text-red-600' + }`}> + {resumo ? formatCurrency(saldo) : 'R$ 0,00'} +

+
+ + + + {/* Card Economia */} + +
+ +
+
+ +
+
+
+

Economia

+

+ -22.2% +

+

{resumo ? formatCurrency(Math.abs(saldo)) : 'R$ 0,00'}

-

{resumo ? formatCurrency(Math.abs(saldo)) : 'R$ 0,00'}

{/* 1. Receitas vs Despesas Chart */} - + {/* 2. Gastos por Categoria */} - + {/* 3. Últimas Transações */} - + { + const location = useLocation(); const { transactions, isLoading, @@ -30,6 +33,25 @@ const Transacoes = () => { loadTransactions } = useTransactions(); + // Aplicar filtro inicial se vier do dashboard + useEffect(() => { + if (location.state?.filter) { + // Aqui você pode implementar lógica adicional para filtrar automaticamente + // Por exemplo, definir um filtro inicial na tabela + console.log('Filtro aplicado:', location.state.filter); + } + }, [location.state]); + + // Filtrar transações baseado no filtro vindo do dashboard + const getFilteredTransactions = () => { + if (location.state?.filter) { + return transactions.filter(t => t.tipo === location.state.filter); + } + return transactions; + }; + + const filteredTransactions = getFilteredTransactions(); + return (
{ formatCurrency={formatCurrency} /> - + ({ categoria, @@ -202,11 +205,11 @@ export async function getCategorySummary(tipo: string = 'despesa'): Promise { - console.log("📈 [getMonthlyData] Obtendo dados mensais..."); + console.log("📈 [getMonthlyData] Obtendo dados mensais do ano completo..."); const normalizedEmail = getUserEmail(); @@ -227,10 +230,10 @@ export async function getMonthlyData(): Promise { query = query.eq('login', normalizedEmail); } - // Get last 12 months - const endDate = new Date(); - const startDate = new Date(); - startDate.setMonth(startDate.getMonth() - 11); + // Get full current year + const currentYear = new Date().getFullYear(); + const startDate = new Date(currentYear, 0, 1); // January 1st + const endDate = new Date(currentYear, 11, 31); // December 31st query = query .gte('quando', startDate.toISOString().split('T')[0])