whisper-money/resources/js/components
Víctor Falcón 1a62b8f42e
fix(dashboard): stop negative asset balances inflating net worth (#660)
## Problem

An account of type `checking`/`savings` with a genuinely **negative**
balance was:
- displayed as **positive** on the dashboard account card, and
- **added** to the net worth chart instead of subtracted,

while the **accounts page** rendered the same balance correctly as
negative.

## Root cause

The dashboard used `getAccountSign(type) * Math.abs(value)`. Liabilities
(`credit_card`/`loan`) are stored as positive magnitudes, so `-abs()`
was
correct for them — but for an **asset** holding a negative balance,
`+abs()`
flipped the sign to positive and summed it into net worth. The accounts
page
was correct because it uses the raw signed balance from
`AccountMetricsService`
with no sign transform.

## Fix

- Add `netWorthContribution(type, balance)` in `chart-calculations.ts`:
liabilities subtract their magnitude, assets keep their real sign (so an
  overdrawn asset correctly reduces net worth).
- Dashboard account card (`use-dashboard-data.ts`) now shows the raw
signed
  balance, matching the accounts page.
- Net worth headline total, short/long trend indicators and the
stacked-asset
total (`net-worth-chart.tsx`) use the raw signed value instead of
`Math.abs`.

## Tests

- 3 new unit tests in `chart-calculations.test.ts`, including a
regression case
  for a negative asset balance. Full suite: 37 passing.
2026-07-08 15:22:16 +00:00
..
accounts feat(accounts): reorder accounts with drag-and-drop (#575) 2026-06-21 11:17:45 +02:00
automation-rules fix(security): scope job-status endpoints to owner + feature-area fixes (#627) 2026-07-03 14:49:32 +02:00
budgets feat: add catch-all budgets (#527) 2026-06-15 16:07:19 +00:00
cashflow feat(analysis): per-category 12-month spending drawer (#519) 2026-06-11 09:52:53 +02:00
categories feat(analysis): per-category 12-month spending drawer (#519) 2026-06-11 09:52:53 +02:00
charts feat: single-open Sankey expand, fit overflowing children (#487) 2026-06-04 11:35:26 +02:00
dashboard fix(dashboard): stop negative asset balances inflating net worth (#660) 2026-07-08 15:22:16 +00:00
icons Subscriptions (#15) 2025-12-06 19:09:56 +01:00
integration-requests feat(integration-requests): add done status and fix review command crash on orphaned author (#601) 2026-06-27 14:42:09 +00:00
labels refactor(js): use InputError for inline form errors (#483) 2026-06-03 19:01:21 +02:00
landing feat(landing): add go now button to redirect modal (#506) 2026-06-08 09:51:35 +02:00
onboarding feat(onboarding): auto-enable AI for connected banks, ask the rest (#618) 2026-07-01 07:26:52 +00:00
open-banking feat(banking): enable Interactive Brokers for all users (#593) 2026-06-26 11:03:21 +02:00
partials fix(header): keep mobile logo on one line, compact auth buttons (#512) 2026-06-09 14:44:35 +02:00
shared feat(ai): auto-categorize transactions with AI (behind flag) (#535) 2026-06-15 16:35:20 +02:00
transactions fix(transactions): keep saved-filter delete button visible on touch and confirm before deleting (#648) 2026-07-06 09:37:38 +00:00
ui fix(chart): stop tooltip render loop crashing the dashboard (PHP-LARAVEL-3B) (#657) 2026-07-07 18:39:09 +00:00
alert-error.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
app-content.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
app-logo-icon.tsx refactor(encryption): strip client-side transaction encryption (#514) 2026-06-20 16:13:26 +00:00
app-logo.tsx Add animated logo icon that transitions based on encryption key state 2025-12-12 11:24:42 +01:00
app-shell.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
app-sidebar-header.tsx fix: keep iOS content below the notch (#280) 2026-04-13 13:59:05 +01:00
app-sidebar.tsx fix: move community link to user menu (#442) 2026-05-27 17:39:26 +02:00
appearance-tabs.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
bank-logo.tsx feat: Integrate EnableBanking as open banking provider (#106) 2026-02-12 09:09:28 +01:00
breadcrumbs.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
delete-user.tsx fix(account): block deletion while subscription or trial is active (#531) 2026-06-14 20:46:44 +02:00
encryption-key-button.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
heading-small.tsx Add Budgeting Feature to Track and Manage Spending (#36) 2026-01-21 15:25:50 +01:00
heading.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
icon.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
input-error.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
mobile-back-button.tsx fix(haptics): use a local WebHaptics wrapper (#225) 2026-03-16 11:26:04 +00:00
nav-footer.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
nav-main.tsx fix(haptics): use a local WebHaptics wrapper (#225) 2026-03-16 11:26:04 +00:00
nav-user.tsx feat(integration-requests): community board to request & vote bank integrations (#550) 2026-06-17 12:50:51 +00:00
sortable-grid.test.tsx fix(accounts): stop second long-press haptic on drag handle (#578) 2026-06-22 11:20:57 +02:00
sortable-grid.tsx fix(accounts): stop second long-press haptic on drag handle (#578) 2026-06-22 11:20:57 +02:00
support-dialog.tsx feat(support): add support link with community-first help modal (#542) 2026-06-16 13:16:04 +02:00
text-link.tsx Set up a fresh Laravel app 2025-11-07 12:01:36 +00:00
two-factor-recovery-codes.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
two-factor-setup-modal.tsx feat: Spanish localization (#74) 2026-02-08 11:58:08 +01:00
unlock-message-dialog.tsx feat(auth): show/hide toggle on password fields (#499) 2026-06-06 11:42:20 +02:00
user-info.tsx feat: Update facehash and enable blink 2026-02-24 15:54:49 +01:00
user-menu-content.test.tsx feat(integration-requests): community board to request & vote bank integrations (#550) 2026-06-17 12:50:51 +00:00
user-menu-content.tsx feat(integration-requests): community board to request & vote bank integrations (#550) 2026-06-17 12:50:51 +00:00