Simpl-Resultat/src/components/dashboard/DashboardEmptyState.tsx
le king fu a060f0e0e0
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m46s
feat(onboarding): dashboard empty state, getting-started checklist and re-show button (#352)
A profile without any transaction now opens a dashboard that says what to
do: a welcome card with the expanded getting-started checklist and one
primary action towards the import page, instead of widgets showing 0 $.
With transactions, the compact checklist sits between the title and the
filter panel until it is complete or dismissed.

- `EmptyState` (pure, dashed card from the import source list; a `to`
  action renders a react-router `<Link>`, an `onClick` action a button)
- `OnboardingChecklist` (pure, expanded and compact modes; undone rows
  link to their route, the locked Budget row shows a lock, the "Base and
  up" label and links to the license card; neutral budget row and hidden
  counter until the entitlement is known)
- `DashboardEmptyState` composes both
- `DashboardPage` branches on the hook `status`: loading renders the title,
  help and banner only; error falls back to the v0.15.0 page without the
  list and logs a warning; ready with zero transactions renders the empty
  state outside the `isLoading` veil
- `useOnboardingChecklist` exposes `counters` and `error` for the page
- Users settings: "Show the getting-started checklist" button in the Guide
  section, visible only when the preference is set, with an inline
  confirmation after the click
- FR + EN keys `dashboard.empty.*`, `onboarding.checklist.*`,
  `settings.users.onboarding.*`

Tests: `EmptyState.test.tsx` and `OnboardingChecklist.test.tsx` by direct
call (FilterPanel pattern). No DB migration. CHANGELOG left to #357.

Resolves #352

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-03 19:32:43 -04:00

47 lines
1.3 KiB
TypeScript

import { useTranslation } from "react-i18next";
import { LayoutDashboard } from "lucide-react";
import EmptyState from "../shared/EmptyState";
import OnboardingChecklist from "./OnboardingChecklist";
import type { Checklist } from "../../utils/onboardingChecklist";
interface DashboardEmptyStateProps {
checklist: Checklist;
budgetReady: boolean;
/** The user dismissed the checklist: the welcome card stays, the list goes. */
hidden: boolean;
onHide: () => void;
}
/**
* Dashboard of a profile without any transaction (#352): a welcome card with
* the expanded getting-started checklist and one primary action towards the
* import page, in place of widgets showing 0 $.
*/
export default function DashboardEmptyState({
checklist,
budgetReady,
hidden,
onHide,
}: DashboardEmptyStateProps) {
const { t } = useTranslation();
return (
<EmptyState
icon={<LayoutDashboard size={40} />}
title={t("dashboard.empty.title")}
description={t("dashboard.empty.description")}
primaryAction={{ label: t("dashboard.empty.cta"), to: "/import" }}
>
{!hidden && (
<OnboardingChecklist
items={checklist.items}
done={checklist.done}
total={checklist.total}
mode="expanded"
budgetReady={budgetReady}
onHide={onHide}
/>
)}
</EmptyState>
);
}