From 5f3bf18b9985fb9de7c19afea4d46a68cadf13d6 Mon Sep 17 00:00:00 2001 From: marcoitaloesp-ai Date: Tue, 16 Dec 2025 12:48:08 +0000 Subject: [PATCH] =?UTF-8?q?v1.43.4=20-=20Padroniza=C3=A7=C3=A3o=20de=20bad?= =?UTF-8?q?ges=20e=20bot=C3=B5es=20em=20todo=20o=20sistema?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Badges: Estilo translúcido uniforme (bg-opacity-25 + text-color) via CSS global - Afetados: RecurringTransactions, Accounts, Categories, TransactionsByWeek - Widgets: UpcomingWidget, OverdueWidget, CalendarWidget, OverpaymentsAnalysis - Botões: Estilo outline padronizado (btn-outline-*) em RecurringTransactions - Simplificação: Remover classes redundantes dos JSX --- CHANGELOG.md | 16 ++ VERSION | 2 +- .../components/dashboard/CalendarWidget.jsx | 2 +- .../dashboard/OverpaymentsAnalysis.jsx | 6 +- .../components/dashboard/UpcomingWidget.jsx | 2 +- frontend/src/index.css | 8 + frontend/src/pages/Accounts.jsx | 20 +- frontend/src/pages/Categories.jsx | 6 +- frontend/src/pages/CostCenters.jsx | 4 +- frontend/src/pages/FinancialHealth.jsx | 2 +- frontend/src/pages/RecurringTransactions.jsx | 178 +++++++++++++++++- frontend/src/pages/TransactionsByWeek.jsx | 4 +- 12 files changed, 224 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6f9f35..bb7022d 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.43.4] - 2025-12-16 + +### Improved +- **Badges Padronizados** - Estilo translúcido consistente em todo o sistema + - Padrão global via CSS: `bg-{color}` → estilo `bg-opacity-25 text-{color}` automático + - Aparência moderna e uniforme: background translúcido + texto colorido + - Afetados: RecurringTransactions, Accounts, Categories, TransactionsByWeek, FinancialHealth, CostCenters + - Widgets: UpcomingWidget, OverdueWidget, CalendarWidget, OverpaymentsAnalysis + - Simplificação: remover classes redundantes dos JSX, CSS aplica estilo + +- **Botões de Ação Padronizados** - RecurringTransactions + - Estilo outline consistente: `btn-outline-{color}` em todas as abas + - Templates e Instâncias usam mesmo padrão visual + - Info (visualizar), Primary (executar), Success (editar), Warning (adiar), Danger (excluir) + + ## [1.43.3] - 2025-12-16 ### Improved diff --git a/VERSION b/VERSION index 6564ab3..4aec498 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.43.3 +1.43.4 diff --git a/frontend/src/components/dashboard/CalendarWidget.jsx b/frontend/src/components/dashboard/CalendarWidget.jsx index c9875da..01ac736 100644 --- a/frontend/src/components/dashboard/CalendarWidget.jsx +++ b/frontend/src/components/dashboard/CalendarWidget.jsx @@ -606,7 +606,7 @@ const CalendarWidget = () => { {item.description} {item.type === 'recurring' && ( - + #{item.occurrence_number} )} diff --git a/frontend/src/components/dashboard/OverpaymentsAnalysis.jsx b/frontend/src/components/dashboard/OverpaymentsAnalysis.jsx index 440957f..4cc3adf 100644 --- a/frontend/src/components/dashboard/OverpaymentsAnalysis.jsx +++ b/frontend/src/components/dashboard/OverpaymentsAnalysis.jsx @@ -226,7 +226,7 @@ const OverpaymentsAnalysis = ({ data, loading, onTransactionClick }) => { )} {(!isMobile || isExpanded) && ( - + Total: {currency(totalOverpayment, 'BRL')} @@ -322,7 +322,7 @@ const OverpaymentsAnalysis = ({ data, loading, onTransactionClick }) => { {tx.description.length > 25 ? tx.description.substring(0, 25) + '...' : tx.description} - + +{currency(tx.variance, 'BRL')} @@ -404,7 +404,7 @@ const OverpaymentsAnalysis = ({ data, loading, onTransactionClick }) => { {currency(tx.actual_amount, 'BRL')} - + +{currency(tx.variance, 'BRL')} diff --git a/frontend/src/components/dashboard/UpcomingWidget.jsx b/frontend/src/components/dashboard/UpcomingWidget.jsx index 8f7e88d..096b85a 100644 --- a/frontend/src/components/dashboard/UpcomingWidget.jsx +++ b/frontend/src/components/dashboard/UpcomingWidget.jsx @@ -206,7 +206,7 @@ const UpcomingWidget = () => { {item.account?.name || '-'} {item.type === 'recurring' && ( - + #{item.occurrence_number} )} diff --git a/frontend/src/index.css b/frontend/src/index.css index 29bf2f4..9cbddb8 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -2878,3 +2878,11 @@ a, .category-dropdown-scroll::-webkit-scrollbar-thumb:hover { background: rgba(100, 116, 139, 0.7); } + +/* Badges padronizados - estilo outline */ +.badge.bg-primary { background-color: rgba(59, 130, 246, 0.25) !important; color: #3b82f6 !important; } +.badge.bg-success { background-color: rgba(34, 197, 94, 0.25) !important; color: #22c55e !important; } +.badge.bg-danger { background-color: rgba(239, 68, 68, 0.25) !important; color: #ef4444 !important; } +.badge.bg-warning { background-color: rgba(234, 179, 8, 0.25) !important; color: #eab308 !important; } +.badge.bg-info { background-color: rgba(14, 165, 233, 0.25) !important; color: #0ea5e9 !important; } +.badge.bg-secondary { background-color: rgba(148, 163, 184, 0.25) !important; color: #94a3b8 !important; } diff --git a/frontend/src/pages/Accounts.jsx b/frontend/src/pages/Accounts.jsx index 39d2152..ad89142 100644 --- a/frontend/src/pages/Accounts.jsx +++ b/frontend/src/pages/Accounts.jsx @@ -508,9 +508,9 @@ const Accounts = () => { {accountTypes[account.type] || account.type} {account.is_active ? ( - {t('common.active')} + {t('common.active')} ) : ( - {t('common.inactive')} + {t('common.inactive')} )}
= 0 ? 'text-success' : 'text-danger'}`} style={{ fontSize: '0.95rem' }}> @@ -575,9 +575,9 @@ const Accounts = () => { {account.is_active ? ( - {t('common.active')} + {t('common.active')} ) : ( - {t('common.inactive')} + {t('common.inactive')} )} @@ -664,15 +664,15 @@ const Accounts = () => {
{liability.status === 'active' ? ( - + {t('common.active')} ) : liability.status === 'paid_off' ? ( - + {t('liabilities.paid')} ) : ( - + {liability.status} )} @@ -783,11 +783,11 @@ const Accounts = () => { {liability.status === 'active' ? ( - {t('common.active')} + {t('common.active')} ) : liability.status === 'paid_off' ? ( - {t('liabilities.paid')} + {t('liabilities.paid')} ) : ( - {liability.status} + {liability.status} )} diff --git a/frontend/src/pages/Categories.jsx b/frontend/src/pages/Categories.jsx index 4d48367..966d329 100644 --- a/frontend/src/pages/Categories.jsx +++ b/frontend/src/pages/Categories.jsx @@ -306,9 +306,9 @@ const Categories = () => { {/* Status */}
{category.is_active ? ( - {t('common.active')} + {t('common.active')} ) : ( - {t('common.inactive')} + {t('common.inactive')} )}
@@ -759,7 +759,7 @@ const Categories = () => { {item.description} - {item.matched_keyword} + {item.matched_keyword} {item.category_name} diff --git a/frontend/src/pages/CostCenters.jsx b/frontend/src/pages/CostCenters.jsx index a49ba3a..8dfa8d1 100644 --- a/frontend/src/pages/CostCenters.jsx +++ b/frontend/src/pages/CostCenters.jsx @@ -345,9 +345,9 @@ const CostCenters = () => { {/* Status */}
{item.is_active ? ( - {t('common.active')} + {t('common.active')} ) : ( - {t('common.inactive')} + {t('common.inactive')} )}
diff --git a/frontend/src/pages/FinancialHealth.jsx b/frontend/src/pages/FinancialHealth.jsx index f90a8ff..c41e321 100644 --- a/frontend/src/pages/FinancialHealth.jsx +++ b/frontend/src/pages/FinancialHealth.jsx @@ -847,7 +847,7 @@ const FinancialHealth = () => { {t(`financialHealth.trend.${data.trends?.income_trend?.direction}`)} - + {data.trends?.income_trend?.strength}% diff --git a/frontend/src/pages/RecurringTransactions.jsx b/frontend/src/pages/RecurringTransactions.jsx index 420d6d8..f60ac21 100644 --- a/frontend/src/pages/RecurringTransactions.jsx +++ b/frontend/src/pages/RecurringTransactions.jsx @@ -7,6 +7,9 @@ import { recurringService, accountService, categoryService } from '../services/a const RecurringTransactions = () => { const { t } = useTranslation(); + // Mobile detection + const [isMobile, setIsMobile] = useState(window.innerWidth < 768); + // State const [templates, setTemplates] = useState([]); const [pendingInstances, setPendingInstances] = useState([]); @@ -80,6 +83,13 @@ const RecurringTransactions = () => { loadData(); }, [loadData]); + // Mobile resize detection + useEffect(() => { + const handleResize = () => setIsMobile(window.innerWidth < 768); + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + // Toast helper const showToast = (message, type = 'success') => { setToast({ show: true, message, type }); @@ -314,7 +324,7 @@ const RecurringTransactions = () => { > {t('recurring.pendingInstances')} - {pendingInstances.length} + {pendingInstances.length} @@ -379,7 +389,88 @@ const RecurringTransactions = () => {

{t('recurring.noTemplates')}

+ ) : isMobile ? ( + // Mobile: Cards Layout +
+ {templates.map((template) => ( +
+
+ {/* Header: Nome + Status */} +
+
+
+ {template.name} +
+ {template.transaction_description && ( +
+ {template.transaction_description} +
+ )} +
+ + {template.is_active ? t('common.active') : t('common.inactive')} + +
+ + {/* Frequência + Tipo */} +
+ + + {t(`recurring.frequencies.${template.frequency}`, template.frequency)} + {template.frequency_interval > 1 && ` (x${template.frequency_interval})`} + + + {t(`transactions.${template.type}`)} + + {(template.pending_instances_count || 0) > 0 && ( + + {template.pending_instances_count} {t('recurring.pendingInstances')} + + )} +
+ + {/* Valor + Ações */} +
+
+ {formatCurrency(template.planned_amount)} +
+
+ + + + +
+
+
+
+ ))} +
) : ( + // Desktop: Table Layout
@@ -417,7 +508,7 @@ const RecurringTransactions = () => { {formatCurrency(template.planned_amount)} @@ -479,7 +570,90 @@ const RecurringTransactions = () => {

{t('recurring.noPendingInstances')}

+ ) : isMobile ? ( + // Mobile: Cards Layout +
+ {pendingInstances.map((instance) => { + const days = Math.ceil((new Date(instance.due_date) - new Date()) / (1000 * 60 * 60 * 24)); + const isOverdue = days < 0; + const isDueToday = days === 0; + + return ( +
+
+ {/* Header: Template + Status */} +
+
+
+ {instance.template?.name} +
+
+ {instance.template?.account?.name} • #{instance.occurrence_number} +
+
+ + {t(`recurring.status.${instance.status}`)} + +
+ + {/* Data de vencimento */} +
+
+ + {formatDate(instance.due_date)} + {instance.status === 'pending' && ( + + {isOverdue && `(${Math.abs(days)} ${t('recurring.daysOverdue')})`} + {isDueToday && `(${t('recurring.dueToday')})`} + {!isOverdue && !isDueToday && `(${days} ${t('recurring.daysUntilDue')})`} + + )} +
+
+ + {/* Valor + Ações */} +
+
+ {formatCurrency(instance.planned_amount)} +
+
+ + + + +
+
+
+
+ ); + })} +
) : ( + // Desktop: Table Layout
- + {template.pending_instances_count || 0}
diff --git a/frontend/src/pages/TransactionsByWeek.jsx b/frontend/src/pages/TransactionsByWeek.jsx index e82f606..26fcdd8 100644 --- a/frontend/src/pages/TransactionsByWeek.jsx +++ b/frontend/src/pages/TransactionsByWeek.jsx @@ -1414,7 +1414,7 @@ export default function Transactions() { {/* Account + Category */}
- + {transaction.account?.name} @@ -2674,7 +2674,7 @@ export default function Transactions() {