// BalanceOnboardingCard — empty-state onboarding for /balance. // // Issue #178. Replaces the BalanceOverviewCard when the user has no accounts // or no snapshots yet. Two vertical steps: // 1. Create an account → /balance/accounts // 2. Enter a snapshot → /balance/snapshot // // Each step has 3 states: // - "active": primary CTA, currently the next thing to do // - "done": marked with a checkmark, no CTA // - "disabled": grayed out (e.g. step 2 when 0 accounts), CTA disabled // // The whole card is replaced by BalanceOverviewCard once at least one // snapshot exists, so step 2 in practice is rendered as "active" or // "disabled"; the "done" branch is supported for completeness/tests. import { useTranslation } from "react-i18next"; import { Link } from "react-router-dom"; import type { TFunction } from "i18next"; import { Wallet, FileText, Check, ArrowRight } from "lucide-react"; interface BalanceOnboardingCardProps { /** Number of active (non-archived) accounts. */ accountsCount: number; /** Number of snapshots saved (any date). */ snapshotsCount: number; } export type StepState = "active" | "done" | "disabled"; /** * Pure helper exposed for unit tests — derives the state of each onboarding * step from the (accountsCount, snapshotsCount) pair. * * - Step 1 is "done" once at least one account exists, "active" otherwise. * - Step 2 is "done" once any snapshot exists, "active" once at least one * account exists, "disabled" otherwise. In practice the parent guard on * /balance only renders this card when snapshotsCount === 0, so the * "done" branch for step 2 is mostly defensive. */ export function deriveOnboardingSteps( accountsCount: number, snapshotsCount: number ): { step1: StepState; step2: StepState } { const step1: StepState = accountsCount >= 1 ? "done" : "active"; const step2: StepState = snapshotsCount >= 1 ? "done" : accountsCount >= 1 ? "active" : "disabled"; return { step1, step2 }; } export default function BalanceOnboardingCard({ accountsCount, snapshotsCount, }: BalanceOnboardingCardProps) { const { t } = useTranslation(); const { step1: step1State, step2: step2State } = deriveOnboardingSteps( accountsCount, snapshotsCount ); return (
{t("balance.onboarding.subtitle")}
{description}
{isDisabled && disabledHint && ({disabledHint}
)}