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
37 lines
1.8 KiB
TypeScript
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";
|
|
}
|