i18n(finance): translate all help tips and guided empty states

- Added [help.*] sections to en.toml and pt.toml covering all six
  tooltip popups (free_cash, savings_rate, net_worth, monthly_needed,
  at_current_rate, disposable_after) with title, body, and formula keys
- Added step1/2/3 keys to [goals.empty] in both locales
- Added empty_state_title/subtitle and empty_step1-3 keys to
  [transactions.table] in both locales
- Updated dashboard.html, goals.html, transactions.html to use T.Get
  for all previously hardcoded English strings in tips and empty states

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Gonçalo Rodrigues 2026-06-19 22:51:17 +01:00
parent 6acea3da31
commit 6485f58f23
5 changed files with 116 additions and 26 deletions

View File

@ -293,6 +293,14 @@ btn_delete = "Delete"
empty_msg = "No transactions found."
empty_import_link = "Import some"
empty_add_btn = "add manually"
empty_state_title = "No transactions yet"
empty_state_subtitle = "Transactions are the foundation of every chart, goal, and insight in this app."
empty_step1_title = "Add an account"
empty_step1_body = "Go to Settings → Accounts and create your checking or savings account first."
empty_step2_title = "Import a CSV or add manually"
empty_step2_body = "Export a statement from your bank and import it, or tap + Add Transaction to enter one by hand."
empty_step3_title = "Tag categories & goals"
empty_step3_body = "Once imported, categorise your spending. Link categories to goals so contributions are tracked automatically."
[transactions.modal_add]
title = "Add Transaction"
@ -391,6 +399,12 @@ no_funding_yet = "No transactions tagged yet. Add a transaction and lin
title = "No goals yet"
desc = "Use the Goal Planner tab to simulate a goal and save it here."
btn_open_planner = "Open Goal Planner →"
step1_title = "Open the Goal Planner"
step1_body = "Simulate how much you need to save monthly and by when. Try different deadlines to find a realistic target."
step2_title = "Commit to the goal"
step2_body = "Mark a goal as committed so it appears in your waterfall and \"what now?\" prompts on the dashboard."
step3_title = "Fund it every month"
step3_body = "Add expense transactions tagged to this goal, or link a spending category in Settings to auto-tag them."
[goals.planner]
what_kind = "What kind of goal?"
@ -1040,3 +1054,34 @@ lever4_desc = "Even 0.5% less on the new loan saves thousands ov
empty_title = "Plan your next big goal"
empty_desc = "Model any transition where you hold an asset with a loan, want to acquire something new, and plan to sell the old to fund it — including the double-payment period, the sale, and the final payoff date."
empty_tip = "Tip: add your current asset and loan first so the planner can pre-fill the numbers."
# ── Help tooltips ─────────────────────────────────────────────────────────────
[help.free_cash]
title = "Free Cash"
body = "What's left after paying for life and funding your goals. Positive means you have room to save or spend more."
formula = "Income Living expenses Goal contributions"
[help.savings_rate]
title = "Savings Rate"
body = "The share of your income you're keeping. Above 20% is healthy; below 0% means you spent more than you earned."
formula = "(Income Expenses) ÷ Income × 100"
[help.net_worth]
title = "Net Worth"
body = "Everything you own minus everything you owe. Tracking this monthly is the single best measure of financial health."
formula = "Cash + Investments + Property equity Debts"
[help.monthly_needed]
title = "Monthly amount needed"
body = "How much to set aside each month to hit your target by the deadline."
formula = "(Target Saved) ÷ Months remaining"
[help.at_current_rate]
title = "At current rate"
body = "How many months it would actually take based on your average monthly savings. Green = on time, red = late."
[help.disposable_after]
title = "Free cash after this goal"
body = "Your estimated monthly free cash if you commit to this goal. Red means you'd need to cut spending elsewhere."
formula = "Income Living All committed goals This goal"

View File

@ -293,6 +293,14 @@ btn_delete = "Eliminar"
empty_msg = "Nenhuma transação encontrada."
empty_import_link = "Importar algumas"
empty_add_btn = "adicionar manualmente"
empty_state_title = "Sem transações ainda"
empty_state_subtitle = "As transações são a base de todos os gráficos, objetivos e análises nesta aplicação."
empty_step1_title = "Adicionar uma conta"
empty_step1_body = "Vá a Definições → Contas e crie a sua conta à ordem ou poupança primeiro."
empty_step2_title = "Importar CSV ou adicionar manualmente"
empty_step2_body = "Exporte um extrato do seu banco e importe-o, ou toque em + Adicionar Transação para introduzir manualmente."
empty_step3_title = "Etiquetar categorias e objetivos"
empty_step3_body = "Após importar, categorize os seus gastos. Ligue categorias a objetivos para que as contribuições sejam registadas automaticamente."
[transactions.modal_add]
title = "Adicionar Transação"
@ -391,6 +399,12 @@ no_funding_yet = "Nenhuma transação etiquetada ainda. Adicione uma tr
title = "Sem objetivos ainda"
desc = "Use o separador Planeador de Objetivos para simular um objetivo e guardá-lo aqui."
btn_open_planner = "Abrir Planeador de Objetivos →"
step1_title = "Abrir o Planeador de Objetivos"
step1_body = "Simule quanto precisa de poupar mensalmente e até quando. Experimente prazos diferentes para encontrar um objetivo realista."
step2_title = "Comprometer-se com o objetivo"
step2_body = "Marque um objetivo como comprometido para que apareça na cascata e nas sugestões do painel."
step3_title = "Financiar todos os meses"
step3_body = "Adicione transações de despesa associadas a este objetivo, ou ligue uma categoria de gastos nas Definições para etiquetagem automática."
[goals.planner]
what_kind = "Que tipo de objetivo?"
@ -1040,3 +1054,34 @@ lever4_desc = "Mesmo 0,5% a menos no novo empréstimo poupa milh
empty_title = "Planeie o seu próximo grande objetivo"
empty_desc = "Modele qualquer transição em que detém um ativo com empréstimo, quer adquirir algo novo e planeia vender o antigo para financiar — incluindo o período de duplo pagamento, a venda e a data final de liquidação."
empty_tip = "Dica: adicione primeiro o seu ativo atual e o empréstimo para que o planeador preencha os valores automaticamente."
# ── Dicas de ajuda ────────────────────────────────────────────────────────────
[help.free_cash]
title = "Dinheiro Livre"
body = "O que sobra depois de pagar a vida e financiar os seus objetivos. Positivo significa que tem margem para poupar ou gastar mais."
formula = "Rendimento Despesas de vida Contribuições para objetivos"
[help.savings_rate]
title = "Taxa de Poupança"
body = "A parte do rendimento que está a guardar. Acima de 20% é saudável; abaixo de 0% significa que gastou mais do que ganhou."
formula = "(Rendimento Despesas) ÷ Rendimento × 100"
[help.net_worth]
title = "Património Líquido"
body = "Tudo o que possui menos tudo o que deve. Acompanhá-lo mensalmente é a melhor medida de saúde financeira."
formula = "Dinheiro + Investimentos + Capital próprio imóvel Dívidas"
[help.monthly_needed]
title = "Valor mensal necessário"
body = "Quanto precisa de reservar por mês para atingir o objetivo até ao prazo."
formula = "(Objetivo Poupado) ÷ Meses restantes"
[help.at_current_rate]
title = "Ao ritmo atual"
body = "Quantos meses levaria realmente com base na sua poupança mensal média. Verde = a tempo, vermelho = com atraso."
[help.disposable_after]
title = "Dinheiro livre após este objetivo"
body = "O seu dinheiro livre mensal estimado se se comprometer com este objetivo. Vermelho significa que precisaria de reduzir despesas."
formula = "Rendimento Vida Todos os objetivos comprometidos Este objetivo"

View File

@ -136,7 +136,7 @@
<!-- Free cash total -->
<div style="display:flex; justify-content:space-between; align-items:center; padding:14px 0 0 0; margin-top:4px; border-top:1px solid var(--border);">
<span style="font-size:14px; font-weight:600; color:var(--text);">{{$d.T.Get "dashboard.waterfall.free_cash"}}<span class="help-tip">?<div class="help-popup"><strong>Free Cash</strong>What's left after paying for life and funding your goals. Positive means you have room to save or spend more.<code>Income Living expenses Goal contributions</code></div></span></span>
<span style="font-size:14px; font-weight:600; color:var(--text);">{{$d.T.Get "dashboard.waterfall.free_cash"}}<span class="help-tip">?<div class="help-popup"><strong>{{$d.T.Get "help.free_cash.title"}}</strong>{{$d.T.Get "help.free_cash.body"}}<code>{{$d.T.Get "help.free_cash.formula"}}</code></div></span></span>
<div class="animate-counter {{if lt $d.WaterfallFreeCash 0}}negative{{else}}positive{{end}}"
style="font-size:32px; font-weight:500; letter-spacing:-1px; line-height:1;"
data-target="{{$d.WaterfallFreeCash}}" data-prefix="€">€0</div>
@ -249,7 +249,7 @@ function wfToggleCat(id) {
<div class="grid" style="margin-bottom:16px;">
<div class="card value-card animate-on-scroll">
<h2>{{$d.T.Get "dashboard.cards.savings_rate"}}<span class="help-tip">?<div class="help-popup"><strong>Savings Rate</strong>The share of your income you're keeping. Above 20% is healthy; below 0% means you spent more than you earned.<code>(Income Expenses) ÷ Income × 100</code></div></span></h2>
<h2>{{$d.T.Get "dashboard.cards.savings_rate"}}<span class="help-tip">?<div class="help-popup"><strong>{{$d.T.Get "help.savings_rate.title"}}</strong>{{$d.T.Get "help.savings_rate.body"}}<code>{{$d.T.Get "help.savings_rate.formula"}}</code></div></span></h2>
<div class="value {{if gt $d.SavingsRatePct 0}}positive{{else}}negative{{end}}">{{$d.SavingsRatePct}}%</div>
{{if $d.LastMonthSavingsRatePct}}
<p style="font-size:12px; margin-top:6px; {{if gt $d.SavingsRatePct $d.LastMonthSavingsRatePct}}color:var(--green){{else}}color:var(--red){{end}};">
@ -259,7 +259,7 @@ function wfToggleCat(id) {
</div>
<div class="card value-card animate-on-scroll">
<h2>{{$d.T.Get "dashboard.cards.net_worth"}}<span class="help-tip">?<div class="help-popup"><strong>Net Worth</strong>Everything you own minus everything you owe. Tracking this monthly is the single best measure of financial health.<code>Cash + Investments + Property equity Debts</code></div></span></h2>
<h2>{{$d.T.Get "dashboard.cards.net_worth"}}<span class="help-tip">?<div class="help-popup"><strong>{{$d.T.Get "help.net_worth.title"}}</strong>{{$d.T.Get "help.net_worth.body"}}<code>{{$d.T.Get "help.net_worth.formula"}}</code></div></span></h2>
<div class="value animate-counter {{if lt $d.NetWorthCents 0}}negative{{else}}positive{{end}}"
data-target="{{$d.NetWorthCents}}" data-prefix="€">€0.00</div>
<p style="font-size:12px; color:var(--text3); margin-top:6px;"><a href="/networth" style="color:var(--accent);">{{$d.T.Get "dashboard.cards.net_worth_link"}}</a></p>

View File

@ -80,7 +80,7 @@
<div style="display:flex; gap:24px; flex-wrap:wrap; align-items:flex-start;">
<div style="text-align:center;">
<div style="font-size:11px; color:var(--text3); margin-bottom:3px;">{{$d.T.Get "goals.goal_card.need_per_month"}}<span class="help-tip">?<div class="help-popup"><strong>Monthly amount needed</strong>How much to set aside each month to hit your target by the deadline.<code>(Target Saved) ÷ Months remaining</code></div></span></div>
<div style="font-size:11px; color:var(--text3); margin-bottom:3px;">{{$d.T.Get "goals.goal_card.need_per_month"}}<span class="help-tip">?<div class="help-popup"><strong>{{$d.T.Get "help.monthly_needed.title"}}</strong>{{$d.T.Get "help.monthly_needed.body"}}<code>{{$d.T.Get "help.monthly_needed.formula"}}</code></div></span></div>
<div class="animate-counter" style="font-size:18px; font-weight:600; color:var(--text);"
data-target="{{.MonthlyCents}}" data-prefix="€">€0</div>
</div>
@ -89,7 +89,7 @@
<div style="font-size:18px; font-weight:600; color:var(--text);">{{.MonthsLeft}}</div>
</div>
<div style="text-align:center;">
<div style="font-size:11px; color:var(--text3); margin-bottom:3px;">{{$d.T.Get "goals.goal_card.at_current_rate"}}<span class="help-tip">?<div class="help-popup"><strong>At current rate</strong>How many months it would actually take based on your average monthly savings. Green = on time, red = late.</div></span></div>
<div style="font-size:11px; color:var(--text3); margin-bottom:3px;">{{$d.T.Get "goals.goal_card.at_current_rate"}}<span class="help-tip">?<div class="help-popup"><strong>{{$d.T.Get "help.at_current_rate.title"}}</strong>{{$d.T.Get "help.at_current_rate.body"}}</div></span></div>
{{if gt .MonthsAtCurrentRate 0}}
<div style="font-size:18px; font-weight:600;
{{if .Feasible}}color:var(--green){{else}}color:var(--red){{end}};">
@ -100,7 +100,7 @@
{{end}}
</div>
<div style="text-align:center;">
<div style="font-size:11px; color:var(--text3); margin-bottom:3px;">{{$d.T.Get "goals.goal_card.disposable_after"}}<span class="help-tip">?<div class="help-popup"><strong>Free cash after this goal</strong>Your estimated monthly free cash if you commit to this goal. Red means you'd need to cut spending elsewhere.<code>Income Living All committed goals This goal</code></div></span></div>
<div style="font-size:11px; color:var(--text3); margin-bottom:3px;">{{$d.T.Get "goals.goal_card.disposable_after"}}<span class="help-tip">?<div class="help-popup"><strong>{{$d.T.Get "help.disposable_after.title"}}</strong>{{$d.T.Get "help.disposable_after.body"}}<code>{{$d.T.Get "help.disposable_after.formula"}}</code></div></span></div>
<div class="animate-counter" style="font-size:18px; font-weight:600;
{{if ge .ImpactOnDisposable 0}}color:var(--green){{else}}color:var(--red){{end}};"
data-target="{{.ImpactOnDisposable}}" data-prefix="€">€0</div>
@ -191,22 +191,22 @@
<div class="setup-step">
<span class="setup-step-num">1</span>
<div>
<strong>Open the Goal Planner</strong>
<p>Simulate how much you need to save monthly and by when. Try different deadlines to find a realistic target.</p>
<strong>{{$d.T.Get "goals.empty.step1_title"}}</strong>
<p>{{$d.T.Get "goals.empty.step1_body"}}</p>
</div>
</div>
<div class="setup-step">
<span class="setup-step-num">2</span>
<div>
<strong>Commit to the goal</strong>
<p>Mark a goal as committed so it appears in your waterfall and "what now?" prompts on the dashboard.</p>
<strong>{{$d.T.Get "goals.empty.step2_title"}}</strong>
<p>{{$d.T.Get "goals.empty.step2_body"}}</p>
</div>
</div>
<div class="setup-step">
<span class="setup-step-num">3</span>
<div>
<strong>Fund it every month</strong>
<p>Add expense transactions tagged to this goal, or link a spending category in Settings to auto-tag them.</p>
<strong>{{$d.T.Get "goals.empty.step3_title"}}</strong>
<p>{{$d.T.Get "goals.empty.step3_body"}}</p>
</div>
</div>
</div>

View File

@ -103,28 +103,28 @@
<td colspan="6" style="padding:0;">
<div style="text-align:center; padding:40px 24px 48px;">
<div style="font-size:40px; margin-bottom:14px;">🧾</div>
<div style="font-size:16px; font-weight:600; color:var(--text2); margin-bottom:8px;">No transactions yet</div>
<p style="font-size:13px; color:var(--text3); margin-bottom:28px;">Transactions are the foundation of every chart, goal, and insight in this app.</p>
<div style="font-size:16px; font-weight:600; color:var(--text2); margin-bottom:8px;">{{$d.T.Get "transactions.table.empty_state_title"}}</div>
<p style="font-size:13px; color:var(--text3); margin-bottom:28px;">{{$d.T.Get "transactions.table.empty_state_subtitle"}}</p>
<div class="setup-steps" style="margin-bottom:28px;">
<div class="setup-step">
<span class="setup-step-num">1</span>
<div>
<strong>Add an account</strong>
<p>Go to Settings → Accounts and create your checking or savings account first.</p>
<strong>{{$d.T.Get "transactions.table.empty_step1_title"}}</strong>
<p>{{$d.T.Get "transactions.table.empty_step1_body"}}</p>
</div>
</div>
<div class="setup-step">
<span class="setup-step-num">2</span>
<div>
<strong>Import a CSV or add manually</strong>
<p>Export a statement from your bank and import it, or tap "+ Add Transaction" to enter one by hand.</p>
<strong>{{$d.T.Get "transactions.table.empty_step2_title"}}</strong>
<p>{{$d.T.Get "transactions.table.empty_step2_body"}}</p>
</div>
</div>
<div class="setup-step">
<span class="setup-step-num">3</span>
<div>
<strong>Tag categories &amp; goals</strong>
<p>Once imported, categorise your spending. Link categories to goals so contributions are tracked automatically.</p>
<strong>{{$d.T.Get "transactions.table.empty_step3_title"}}</strong>
<p>{{$d.T.Get "transactions.table.empty_step3_body"}}</p>
</div>
</div>
</div>