Simpl-Resultat/src/components/balance/balanceLanding.ts
le king fu 82550d6d38
All checks were successful
PR Check / rust (pull_request) Successful in 25m34s
PR Check / frontend (pull_request) Successful in 2m30s
feat(balance): tile-based landing hub + reachable account management
Decouple the /balance empty-state guard into three explicit states via a
new pure helper `deriveLandingState` (empty / accounts-no-snapshot /
populated). Having accounts but no snapshot no longer strands the user on a
snapshot-only onboarding card: each state now renders navigation tiles
(HubReportNavCard, modeled on the Reports hub), and "Manage accounts"
(/balance/accounts) is reachable in every state, including the populated
dashboard.

- Remove BalanceOnboardingCard (component + test) and the dead
  balance.onboarding.* i18n keys; add balanceLanding.ts + test.
- Add balance.hub.* and balance.landing.* keys in FR and EN.
- CHANGELOG (EN + FR) under [Unreleased].

Resolves #244
2026-07-04 17:43:43 -04:00

37 lines
1.8 KiB
TypeScript

// balanceLanding.ts — pure landing-state helper for the /balance page.
//
// Issue #244. Decouples the old boolean empty-state guard
// (`accountsCount === 0 || !hasAnySnapshot`) into three explicit states so the
// UI can stop conflating "no account yet" with "accounts but no snapshot yet":
//
// - "empty": no active account at all → offer account creation
// (StarterAccountsModal + a "Manage accounts" tile).
// - "accounts-no-snapshot": at least one account but no snapshot → offer BOTH
// "Manage accounts" and "New snapshot" tiles, without
// forcing the user toward the snapshot flow.
// - "populated": at least one account with at least one snapshot →
// render the full dashboard (overview + chart +
// accounts table) plus the navigation tiles.
//
// Extracted as a pure, DOM-free helper because this project has no
// @testing-library/react or jsdom configured — UI branching is unit-tested via
// pure helpers (same convention as `deriveOnboardingSteps` / `computeBalanceDateRange`).
export type BalanceLandingState = "empty" | "accounts-no-snapshot" | "populated";
/**
* Derive the landing state from the two independent signals the balance page
* already computes: the number of active accounts and whether ANY snapshot
* exists (probed across accounts, independent of the active period filter).
*
* @param accountsCount number of active (non-archived) accounts
* @param hasAnySnapshot true when at least one account carries a snapshot date
*/
export function deriveLandingState(
accountsCount: number,
hasAnySnapshot: boolean
): BalanceLandingState {
if (accountsCount <= 0) return "empty";
if (!hasAnySnapshot) return "accounts-no-snapshot";
return "populated";
}