From 82e1d7a8843a4a63b8ee9b8da9b1032da6d1fde8 Mon Sep 17 00:00:00 2001 From: marcoitaloesp-ai Date: Mon, 15 Dec 2025 12:18:34 +0000 Subject: [PATCH] =?UTF-8?q?v1.34.1:=20UI/UX=20melhorada=20do=20resumo=20de?= =?UTF-8?q?=20relat=C3=B3rios?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Improved: - Cards KPI redesenhados com ícones e melhor hierarquia - Badges de variação com contraste aprimorado - Métricas de média mensal adicionadas - Card de Taxa de Poupança com barra de progresso - Feedback inteligente (Excelente/Boa/Pode melhorar) - Gráfico comparativo com tooltips e bordas arredondadas - Tradução completa (pt-BR, en, es) --- CHANGELOG.md | 16 ++ VERSION | 2 +- frontend/src/i18n/locales/en.json | 7 + frontend/src/i18n/locales/es.json | 8 + frontend/src/i18n/locales/pt-BR.json | 7 + frontend/src/pages/Reports.jsx | 210 +++++++++++++++++++++------ 6 files changed, 205 insertions(+), 45 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd7710e..0bd9d24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,22 @@ O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/). Este projeto adota [Versionamento Semântico](https://semver.org/pt-BR/). +## [1.34.1] - 2025-12-15 + +### Improved +- **UI/UX do Resumo de Relatórios** - Interface redesenhada com visual mais profissional + - Cards KPI com ícones grandes e hierarquia visual clara + - Badges de variação com fundo branco para melhor contraste + - Adicionadas métricas de média mensal em todos os cards + - Novo card dedicado para Taxa de Poupança com barra de progresso + - Feedback visual inteligente baseado na taxa de poupança: + * 🎯 ≥20%: "Excelente poupança!" + * 👍 ≥10%: "Boa poupança" + * 💡 <10%: "Pode melhorar" + - Gráfico comparativo melhorado com bordas arredondadas e tooltips aprimorados + - Header do resumo com ícone e seletor de ano redesenhado + - Tradução completa: pt-BR, en, es + ## [1.34.0] - 2025-12-14 ### Fixed diff --git a/VERSION b/VERSION index 2b17ffd..a95a46d 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.34.0 +1.34.1 diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index b005fdf..c88c3dd 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -1834,7 +1834,14 @@ "topExpenses": "Top Expenses", "vsAverage": "vs Average", "vsLastPeriod": "vs Last Period", + "vsLastYear": "vs last year", "yearComparison": "Year Comparison", + "annualSummary": "Annual Summary", + "monthlyAverage": "Monthly Average", + "excellentSavings": "Excellent savings!", + "goodSavings": "Good savings", + "canImprove": "Can improve", + "total": "Total", "expenseDistribution": "Expense Distribution", "categoryDetail": "Category Detail", "category": "Category", diff --git a/frontend/src/i18n/locales/es.json b/frontend/src/i18n/locales/es.json index 5eee580..4aedbeb 100644 --- a/frontend/src/i18n/locales/es.json +++ b/frontend/src/i18n/locales/es.json @@ -1801,6 +1801,14 @@ "avgIncome": "Ingreso promedio", "avgExpense": "Gasto promedio", "vsLastPeriod": "vs período anterior", + "vsLastYear": "vs año anterior", + "yearComparison": "Comparación Anual", + "annualSummary": "Resumen Anual", + "monthlyAverage": "Promedio Mensual", + "excellentSavings": "¡Excelente ahorro!", + "goodSavings": "Buen ahorro", + "canImprove": "Puede mejorar", + "total": "Total", "dayOfWeek": { "sunday": "Domingo", "monday": "Lunes", diff --git a/frontend/src/i18n/locales/pt-BR.json b/frontend/src/i18n/locales/pt-BR.json index 1fd0427..08bc63e 100644 --- a/frontend/src/i18n/locales/pt-BR.json +++ b/frontend/src/i18n/locales/pt-BR.json @@ -1836,7 +1836,14 @@ "topExpenses": "Maiores Despesas", "vsAverage": "vs Média", "vsLastPeriod": "vs Período Anterior", + "vsLastYear": "vs ano anterior", "yearComparison": "Comparativo Anual", + "annualSummary": "Resumo Anual", + "monthlyAverage": "Média Mensal", + "excellentSavings": "Excelente poupança!", + "goodSavings": "Boa poupança", + "canImprove": "Pode melhorar", + "total": "Total", "expenseDistribution": "Distribuição de Despesas", "categoryDetail": "Detalhes por Categoria", "category": "Categoria", diff --git a/frontend/src/pages/Reports.jsx b/frontend/src/pages/Reports.jsx index 46027d1..cb9712c 100644 --- a/frontend/src/pages/Reports.jsx +++ b/frontend/src/pages/Reports.jsx @@ -169,64 +169,152 @@ const Reports = () => { const renderSummary = () => { if (!summary) return null; + const savingsRate = summary.current.income > 0 + ? ((summary.current.balance / summary.current.income) * 100).toFixed(1) + : 0; + + const monthlyAvgIncome = (summary.current.income / 12).toFixed(2); + const monthlyAvgExpense = (summary.current.expense / 12).toFixed(2); + const monthlyAvgBalance = (summary.current.balance / 12).toFixed(2); + return (
{/* Year Selector */}
-
- {[2024, 2025].map(y => ( - - ))} +
+
+ + {t('reports.annualSummary')} +
+
+ {[2024, 2025].map(y => ( + + ))} +
- {/* Summary Cards */} -
+ {/* Main KPI Cards */} +
-
{t('reports.income')} {year}
-

{currency(summary.current.income, summary.currency)}

+
+
+
{t('reports.income')}
+

{currency(summary.current.income, summary.currency)}

+
+
+ +
+
{summary.variation.income !== 0 && ( - = 0 ? 'bg-success' : 'bg-danger'}`}> - = 0 ? 'up' : 'down'} me-1`}> - {Math.abs(summary.variation.income)}% {t('reports.vsLastPeriod')} - +
+ = 0 ? 'bg-white text-success' : 'bg-white text-danger'} px-2 py-1`}> + = 0 ? 'up' : 'down'} me-1`}> + {Math.abs(summary.variation.income).toFixed(1)}% + + {t('reports.vsLastYear')} +
)} +
+
+ {t('reports.monthlyAverage')}: + {currency(monthlyAvgIncome, summary.currency)} +
-
+
-
{t('reports.expenses')} {year}
-

{currency(summary.current.expense, summary.currency)}

+
+
+
{t('reports.expenses')}
+

{currency(summary.current.expense, summary.currency)}

+
+
+ +
+
{summary.variation.expense !== 0 && ( - - = 0 ? 'up' : 'down'} me-1`}> - {Math.abs(summary.variation.expense)}% {t('reports.vsLastPeriod')} - +
+ + = 0 ? 'up' : 'down'} me-1`}> + {Math.abs(summary.variation.expense).toFixed(1)}% + + {t('reports.vsLastYear')} +
)} +
+
+ {t('reports.monthlyAverage')}: + {currency(monthlyAvgExpense, summary.currency)} +
-
+
-
{t('reports.balance')} {year}
-

{currency(summary.current.balance, summary.currency)}

- - {t('reports.savingsRate')}: {summary.current.income > 0 - ? ((summary.current.balance / summary.current.income) * 100).toFixed(1) - : 0}% - +
+
+
{t('reports.balance')}
+

{currency(summary.current.balance, summary.currency)}

+
+
+ +
+
+ {summary.variation.balance !== 0 && ( +
+ = 0 ? 'bg-white text-success' : 'bg-white text-danger'} px-2 py-1`}> + = 0 ? 'up' : 'down'} me-1`}> + {Math.abs(summary.variation.balance).toFixed(1)}% + + {t('reports.vsLastYear')} +
+ )} +
+
+ {t('reports.monthlyAverage')}: + {currency(monthlyAvgBalance, summary.currency)} +
+
+
+
+ +
+
+
+
+
+
{t('reports.savingsRate')}
+

{savingsRate}%

+
+
+ +
+
+
+
+
+ + {savingsRate >= 20 ? '🎯 ' + t('reports.excellentSavings') : + savingsRate >= 10 ? '👍 ' + t('reports.goodSavings') : + '💡 ' + t('reports.canImprove')} +
@@ -235,12 +323,17 @@ const Reports = () => {
-
- - {t('reports.yearComparison')} -
+
+
+ + {t('reports.yearComparison')} - {year-1} vs {year} +
+ + {t('reports.total')}: {currency(summary.current.balance, summary.currency)} + +
-
+
{ { label: String(year - 1), data: [summary.previous.income, summary.previous.expense, summary.previous.balance], - backgroundColor: 'rgba(148, 163, 184, 0.5)', - borderColor: '#94a3b8', - borderWidth: 1, + backgroundColor: 'rgba(100, 116, 139, 0.6)', + borderColor: '#64748b', + borderWidth: 2, + borderRadius: 6, }, { label: String(year), data: [summary.current.income, summary.current.expense, summary.current.balance], - backgroundColor: ['rgba(16, 185, 129, 0.7)', 'rgba(239, 68, 68, 0.7)', 'rgba(59, 130, 246, 0.7)'], + backgroundColor: ['rgba(16, 185, 129, 0.8)', 'rgba(239, 68, 68, 0.8)', 'rgba(59, 130, 246, 0.8)'], borderColor: ['#10b981', '#ef4444', '#3b82f6'], - borderWidth: 1, + borderWidth: 2, + borderRadius: 6, }, ], }} - options={chartOptions} + options={{ + ...chartOptions, + plugins: { + ...chartOptions.plugins, + legend: { + position: 'top', + labels: { + color: '#94a3b8', + padding: 15, + font: { size: 12, weight: 'bold' } + } + }, + tooltip: { + backgroundColor: 'rgba(15, 23, 42, 0.95)', + titleColor: '#fff', + bodyColor: '#94a3b8', + borderColor: '#334155', + borderWidth: 1, + padding: 12, + displayColors: true, + callbacks: { + label: function(context) { + return `${context.dataset.label}: ${currency(context.parsed.y, summary.currency)}`; + } + } + } + } + }} />