diff --git a/CHANGELOG.md b/CHANGELOG.md index 8166d4a..b02b061 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,52 @@ O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/). Este projeto adota [Versionamento Semântico](https://semver.org/pt-BR/). +## [1.43.0] - 2025-12-16 + +### Added +- **Widget Projeção de Saldo Mobile** - Comportamento colapsável implementado + - Inicia colapsado em mobile, expande automaticamente se houver dados + - Botão toggle chevron up/down no header + - Botões de período (1, 2, 3, 6, 12 meses) otimizados: + - Desktop: btn-group horizontal + - Mobile: layout flex-wrap em 3 colunas (33.333% cada) + - Altura do gráfico ajustada: 300px (mobile) vs 350px (desktop) + - Cards de estatísticas otimizados para mobile: + - Padding reduzido: p-2 (mobile) vs p-3 (desktop) + - Gap menor: g-2 vs g-3 + - Fontes menores: labels 0.7rem, valores 0.9rem + - Percentual de variação oculto em mobile + +- **Widget Análise de Sobrepagamentos Mobile** - UX completamente redesenhada + - Comportamento colapsável com auto-expansão quando há dados + - Header otimizado: texto menor, badge compacto, "(12 meses)" oculto + - Gráfico responsivo: 180px (mobile) vs 220px (desktop) + - Cards de resumo compactos: padding p-1, fontes 0.65-0.85rem + - **Layout de transações revolucionário**: + - Mobile: Cards verticais ao invés de tabela horizontal + - Cada card mostra: descrição, valor (+), categoria, data, percentual + - Fontes otimizadas: 0.6-0.75rem + - Border amarelo sutil para destaque + - Altura máxima: 200px com scroll + - Desktop: Tabela completa mantida com todas as colunas + +### Fixed +- **React Hooks Error #310** - Corrigida violação das regras de hooks + - Problema: `useEffect` sendo chamado após returns condicionais + - Solução: Movido cálculo de `monthsData` para antes dos returns + - Adicionado `useEffect` na importação: `import { useEffect }` + - Todos os hooks agora executam na ordem correta + - Dependências corretas em useEffect: `[isMobile, monthsData.length, isExpanded]` + +### Improved +- **Consistência Mobile Global** - Todos os widgets principais otimizados: + - ✅ Calendário: navegação entre semanas + colapso + - ✅ Próximos 7 Dias: colapso + sync altura desktop + - ✅ Transações em Atraso: colapso + auto-expansão + - ✅ Projeção de Saldo: colapso + botões otimizados + cards compactos + - ✅ Análise Sobrepagamentos: colapso + layout cards mobile + - UX mobile profissional e consistente em todo Dashboard + ## [1.42.0] - 2025-12-16 ### Added diff --git a/VERSION b/VERSION index a50908c..b978278 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.42.0 +1.43.0 diff --git a/frontend/src/components/dashboard/BalanceProjectionChart.jsx b/frontend/src/components/dashboard/BalanceProjectionChart.jsx index 44be99c..31854e7 100644 --- a/frontend/src/components/dashboard/BalanceProjectionChart.jsx +++ b/frontend/src/components/dashboard/BalanceProjectionChart.jsx @@ -35,6 +35,8 @@ const BalanceProjectionChart = () => { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); + const [isMobile, setIsMobile] = useState(window.innerWidth < 768); + const [isExpanded, setIsExpanded] = useState(false); const loadData = useCallback(async () => { setLoading(true); @@ -42,18 +44,36 @@ const BalanceProjectionChart = () => { try { const response = await reportService.getProjectionChart({ months }); setData(response); + + // Auto-expand if we have data points in mobile + if (isMobile && response?.data?.length > 0) { + setIsExpanded(true); + } } catch (err) { console.error('Error loading projection chart:', err); setError(t('common.error')); } finally { setLoading(false); } - }, [months, t]); + }, [months, t, isMobile]); useEffect(() => { loadData(); }, [loadData]); + useEffect(() => { + const handleResize = () => { + const mobile = window.innerWidth < 768; + setIsMobile(mobile); + if (!mobile) { + setIsExpanded(false); + } + }; + + window.addEventListener('resize', handleResize); + return () => window.removeEventListener('resize', handleResize); + }, []); + const periodOptions = [ { value: 1, label: t('reports.projectionChart.1month') || '1 mês' }, { value: 2, label: t('reports.projectionChart.2months') || '2 meses' }, @@ -202,30 +222,44 @@ const BalanceProjectionChart = () => { const changeIcon = summary?.change >= 0 ? 'bi-arrow-up' : 'bi-arrow-down'; return ( -
+
{t('dashboard.clickBarToSeeDetails')}
{/* Gráfico */} -| {t('common.date')} | -{t('common.description')} | -{t('dashboard.category')} | -{t('dashboard.plannedValue')} | -{t('dashboard.actualValue')} | -{t('dashboard.difference')} | -{t('dashboard.delay')} | -% | -||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| - {new Date(tx.effective_date).toLocaleDateString(getLocale())} - | -- - {tx.description.length > 30 ? tx.description.substring(0, 30) + '...' : tx.description} - - | -
- {tx.category ? (
+ {isMobile ? (
+ /* Layout Mobile - Cards */
+
+ {selectedMonthData.transactions.map((tx) => (
+ onTransactionClick?.(tx.id)}
+ style={{
+ cursor: 'pointer',
+ background: 'rgba(0,0,0,0.3)',
+ border: '1px solid rgba(251, 191, 36, 0.2)'
+ }}
+ >
+
+
+ {tx.description.length > 25 ? tx.description.substring(0, 25) + '...' : tx.description}
+
+
+ +{currency(tx.variance, 'BRL')}
+
+
+
+
+ {tx.category && (
{tx.category.name}
- ) : (
- -
)}
- |
- - {currency(tx.planned_amount, 'BRL')} - | -- {currency(tx.actual_amount, 'BRL')} - | -- - - +{currency(tx.variance, 'BRL')} + + {new Date(tx.effective_date).toLocaleDateString(getLocale(), { day: '2-digit', month: '2-digit' })} - | -- {tx.delay_days !== null && tx.delay_days !== 0 ? ( - 0 ? 'rgba(239, 68, 68, 0.8)' : 'rgba(34, 197, 94, 0.8)' - }} - > - 0 ? '-history' : ''} me-1`} style={{ fontSize: '9px' }}> - {tx.delay_days > 0 ? `+${tx.delay_days}d` : `${tx.delay_days}d`} - - ) : ( - - - )} - | -+ + +{tx.variance_percent}% - | + + + + ))} + + ) : ( + /* Layout Desktop - Tabela */ +
| {t('common.date')} | +{t('common.description')} | +{t('dashboard.category')} | +{t('dashboard.plannedValue')} | +{t('dashboard.actualValue')} | +{t('dashboard.difference')} | +{t('dashboard.delay')} | +% |
|---|