v1.27.5: Fix multi-currency in CashflowChart and dashboard widgets
This commit is contained in:
parent
84a1dbae29
commit
cc448b5cd4
13
CHANGELOG.md
13
CHANGELOG.md
@ -5,6 +5,19 @@ O formato segue [Keep a Changelog](https://keepachangelog.com/pt-BR/).
|
|||||||
Este projeto adota [Versionamento Semântico](https://semver.org/pt-BR/).
|
Este projeto adota [Versionamento Semântico](https://semver.org/pt-BR/).
|
||||||
|
|
||||||
|
|
||||||
|
## [1.27.5] - 2025-12-13
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
- **Dashboard Multi-Divisa Completo** - Corrigido Flujo de Caja para usar divisa dinâmica
|
||||||
|
- CashflowChart agora recebe `primaryCurrency` como prop
|
||||||
|
- Tooltips do gráfico mostram a divisa correta
|
||||||
|
- Totais do período (receita, despesa, médias) usam `primary_currency`
|
||||||
|
|
||||||
|
- **Widgets Vencidos/Futuros** - Removidas divisas fixas (BRL/EUR)
|
||||||
|
- UpcomingWidget: Footer mostra contagem de items em vez de totais monetários
|
||||||
|
- OverdueWidget: Rangos mostram contagem, footer mostra média de dias
|
||||||
|
|
||||||
|
|
||||||
## [1.27.4] - 2025-12-13
|
## [1.27.4] - 2025-12-13
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|||||||
@ -32,7 +32,7 @@ ChartJS.register(
|
|||||||
Filler
|
Filler
|
||||||
);
|
);
|
||||||
|
|
||||||
const CashflowChart = ({ data, loading, scale = 'monthly' }) => {
|
const CashflowChart = ({ data, loading, scale = 'monthly', primaryCurrency = 'EUR' }) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const { currency } = useFormatters();
|
const { currency } = useFormatters();
|
||||||
const chartRef = useRef(null);
|
const chartRef = useRef(null);
|
||||||
@ -134,7 +134,7 @@ const CashflowChart = ({ data, loading, scale = 'monthly' }) => {
|
|||||||
label: (context) => {
|
label: (context) => {
|
||||||
const value = context.parsed.y;
|
const value = context.parsed.y;
|
||||||
const label = context.dataset.label || '';
|
const label = context.dataset.label || '';
|
||||||
return `${label}: ${currency(value, 'BRL')}`;
|
return `${label}: ${currency(value, primaryCurrency)}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@ -146,8 +146,8 @@ const OverdueWidget = () => {
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex align-items-center gap-2">
|
<div className="d-flex align-items-center gap-2">
|
||||||
<span className="text-danger fw-bold small">
|
<span className="badge bg-danger" style={{ fontSize: '10px' }}>
|
||||||
{currency(range.total, 'BRL')}
|
{range.count} {range.count === 1 ? t('common.item') : t('common.items')}
|
||||||
</span>
|
</span>
|
||||||
<i className={`bi bi-chevron-${expandedRange === range.key ? 'up' : 'down'} text-slate-500`}></i>
|
<i className={`bi bi-chevron-${expandedRange === range.key ? 'up' : 'down'} text-slate-500`}></i>
|
||||||
</div>
|
</div>
|
||||||
@ -246,10 +246,10 @@ const OverdueWidget = () => {
|
|||||||
</div>
|
</div>
|
||||||
<div className="col-4">
|
<div className="col-4">
|
||||||
<small className="text-slate-500 d-block" style={{ fontSize: '10px' }}>
|
<small className="text-slate-500 d-block" style={{ fontSize: '10px' }}>
|
||||||
{t('dashboard.totalAmount')}
|
{t('dashboard.avgDays')}
|
||||||
</small>
|
</small>
|
||||||
<span className="text-danger fw-bold small">
|
<span className="text-danger fw-bold small">
|
||||||
{currency(data.summary.total_amount || 0, 'BRL')}
|
~{Math.round(data.summary.max_days_overdue / 2)} {t('common.days')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-4">
|
<div className="col-4">
|
||||||
|
|||||||
@ -161,7 +161,7 @@ const UpcomingWidget = () => {
|
|||||||
{t('dashboard.income')}
|
{t('dashboard.income')}
|
||||||
</small>
|
</small>
|
||||||
<span className="text-success fw-bold small">
|
<span className="text-success fw-bold small">
|
||||||
+{currency(data.summary.total_credit || 0, 'EUR')}
|
{data.summary.credit_count || 0} {t('common.items')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-6">
|
<div className="col-6">
|
||||||
@ -169,7 +169,7 @@ const UpcomingWidget = () => {
|
|||||||
{t('dashboard.expenses')}
|
{t('dashboard.expenses')}
|
||||||
</small>
|
</small>
|
||||||
<span className="text-danger fw-bold small">
|
<span className="text-danger fw-bold small">
|
||||||
-{currency(data.summary.total_debit || 0, 'EUR')}
|
{data.summary.debit_count || 0} {t('common.items')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -173,6 +173,7 @@
|
|||||||
"totalOverdue": "Total Overdue",
|
"totalOverdue": "Total Overdue",
|
||||||
"totalAmount": "Total Amount",
|
"totalAmount": "Total Amount",
|
||||||
"maxDelay": "Max Delay",
|
"maxDelay": "Max Delay",
|
||||||
|
"avgDays": "Average",
|
||||||
"overdueRange": {
|
"overdueRange": {
|
||||||
"critical": "Critical (> 30 days)",
|
"critical": "Critical (> 30 days)",
|
||||||
"high": "High (15-30 days)",
|
"high": "High (15-30 days)",
|
||||||
|
|||||||
@ -173,6 +173,7 @@
|
|||||||
"totalOverdue": "Total Vencido",
|
"totalOverdue": "Total Vencido",
|
||||||
"totalAmount": "Monto Total",
|
"totalAmount": "Monto Total",
|
||||||
"maxDelay": "Mayor Retraso",
|
"maxDelay": "Mayor Retraso",
|
||||||
|
"avgDays": "Promedio",
|
||||||
"overdueRange": {
|
"overdueRange": {
|
||||||
"critical": "Crítico (> 30 días)",
|
"critical": "Crítico (> 30 días)",
|
||||||
"high": "Alto (15-30 días)",
|
"high": "Alto (15-30 días)",
|
||||||
|
|||||||
@ -174,6 +174,7 @@
|
|||||||
"totalOverdue": "Total em Atraso",
|
"totalOverdue": "Total em Atraso",
|
||||||
"totalAmount": "Valor Total",
|
"totalAmount": "Valor Total",
|
||||||
"maxDelay": "Maior Atraso",
|
"maxDelay": "Maior Atraso",
|
||||||
|
"avgDays": "Média",
|
||||||
"overdueRange": {
|
"overdueRange": {
|
||||||
"critical": "Crítico (> 30 dias)",
|
"critical": "Crítico (> 30 dias)",
|
||||||
"high": "Alto (15-30 dias)",
|
"high": "Alto (15-30 dias)",
|
||||||
|
|||||||
@ -338,6 +338,7 @@ const Dashboard = () => {
|
|||||||
<CashflowChart
|
<CashflowChart
|
||||||
data={cashflow?.data || []}
|
data={cashflow?.data || []}
|
||||||
loading={cashflowLoading}
|
loading={cashflowLoading}
|
||||||
|
primaryCurrency={summary?.primary_currency || 'EUR'}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Resumo do período */}
|
{/* Resumo do período */}
|
||||||
@ -348,7 +349,7 @@ const Dashboard = () => {
|
|||||||
{t('dashboard.totalIncome')}
|
{t('dashboard.totalIncome')}
|
||||||
</small>
|
</small>
|
||||||
<span className="text-success fw-bold">
|
<span className="text-success fw-bold">
|
||||||
{currency(cashflow.totals?.income || 0, 'BRL')}
|
{currency(cashflow.totals?.income || 0, summary?.primary_currency || 'EUR')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-6 col-md-3 text-center">
|
<div className="col-6 col-md-3 text-center">
|
||||||
@ -356,7 +357,7 @@ const Dashboard = () => {
|
|||||||
{t('dashboard.totalExpenses')}
|
{t('dashboard.totalExpenses')}
|
||||||
</small>
|
</small>
|
||||||
<span className="text-danger fw-bold">
|
<span className="text-danger fw-bold">
|
||||||
{currency(cashflow.totals?.expense || 0, 'BRL')}
|
{currency(cashflow.totals?.expense || 0, summary?.primary_currency || 'EUR')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-6 col-md-3 text-center mt-2 mt-md-0">
|
<div className="col-6 col-md-3 text-center mt-2 mt-md-0">
|
||||||
@ -364,7 +365,7 @@ const Dashboard = () => {
|
|||||||
{t('dashboard.avgIncome')}
|
{t('dashboard.avgIncome')}
|
||||||
</small>
|
</small>
|
||||||
<span className="text-success">
|
<span className="text-success">
|
||||||
{currency(cashflow.totals?.average_income || 0, 'BRL')}
|
{currency(cashflow.totals?.average_income || 0, summary?.primary_currency || 'EUR')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div className="col-6 col-md-3 text-center mt-2 mt-md-0">
|
<div className="col-6 col-md-3 text-center mt-2 mt-md-0">
|
||||||
@ -372,7 +373,7 @@ const Dashboard = () => {
|
|||||||
{t('dashboard.avgExpense')}
|
{t('dashboard.avgExpense')}
|
||||||
</small>
|
</small>
|
||||||
<span className="text-danger">
|
<span className="text-danger">
|
||||||
{currency(cashflow.totals?.average_expense || 0, 'BRL')}
|
{currency(cashflow.totals?.average_expense || 0, summary?.primary_currency || 'EUR')}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user