mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-15 06:52:04 +00:00
Carry the setup answers into the checklist, Settings and the module pages
The getting-started checklist reads the answers: a visit named within a month adds a "prepare the visit" row that is done once one is on the calendar, and the data-source row names the wearable that was chosen. Its per-browser state moves to one module so the done screen, the skip and Settings write the same keys. Settings → Account gains the two ways back in: "Set up again" through the restart route, which resets the ledger, keeps the answers as prefill and touches no module; and "Show the checklist again", which forgets what this browser hid. A page whose module is off now answers with the shared notice and the one action that helps, in one place for every module page: the shell maps the route to the module through the navigation model's own gate, so a page and its nav entry cannot disagree about which switch they follow. And the tour's two dead stops get their anchors on the integrations and health-record group headings.
This commit is contained in:
1 parent
a062610895
commit
ec82ad3a93
13 files changed
+325
-16
No files matched your search
@@ -48,6 +48,7 @@ import {
|
||||
type StatusMessage,
|
||||
} from "./account-section-utils";
|
||||
import { AvatarSection } from "./avatar-section";
|
||||
import { SetupCard } from "./setup-card";
|
||||
|
||||
export { resolveInitialTimezone } from "./account-section-utils";
|
||||
|
||||
@@ -330,6 +331,10 @@ export function AccountSection() {
|
||||
{/* Profile photo card */}
|
||||
<AvatarSection />
|
||||
|
||||
{/* v1.39 (C2) — the way back into the first-run experience: the setup
|
||||
questions again, and the dashboard checklist this browser hid. */}
|
||||
<SetupCard />
|
||||
|
||||
<SettingsCard>
|
||||
<SettingsCardHeader icon={User} title={t("settings.profile")} />
|
||||
<form onSubmit={handleSaveProfile} className="space-y-4">
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
"use client";
|
||||
|
||||
import { useRouter } from "next/navigation";
|
||||
import { toast } from "sonner";
|
||||
import { ListChecks, Loader2 } from "lucide-react";
|
||||
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { SettingsCard } from "@/components/settings/settings-card";
|
||||
import { SettingsCardActions } from "@/components/settings/_card-actions";
|
||||
import { SettingsCardHeader } from "@/components/settings/_card-header";
|
||||
import { useOnboardingRestart } from "@/components/onboarding/use-onboarding-flow";
|
||||
import { localizedApiError } from "@/lib/api/localized-error";
|
||||
import { useTranslations } from "@/lib/i18n/context";
|
||||
import { resetChecklistDismissals } from "@/lib/onboarding/checklist-storage";
|
||||
|
||||
/**
|
||||
* v1.39 (C2) — Settings → Account → Setup.
|
||||
*
|
||||
* The two ways back into the first-run experience (design spec §Principles 4
|
||||
* and §After the flow). "Set up again" asks the questions once more through
|
||||
* the restart route, which resets the ledger and keeps the answers as
|
||||
* prefill — and writes no module state, so a module switched on by hand is
|
||||
* never switched off by a re-run. "Show the checklist again" forgets what
|
||||
* this browser hid; the checklist's dismissals live in the browser, so the
|
||||
* button lives on the same origin.
|
||||
*/
|
||||
export function SetupCard() {
|
||||
const { t } = useTranslations();
|
||||
const router = useRouter();
|
||||
const restart = useOnboardingRestart();
|
||||
|
||||
async function setUpAgain() {
|
||||
if (restart.isPending) return;
|
||||
try {
|
||||
await restart.mutateAsync();
|
||||
router.push("/onboarding/who");
|
||||
} catch (err) {
|
||||
toast.error(localizedApiError(err, t, "onboarding.errorGeneric"));
|
||||
}
|
||||
}
|
||||
|
||||
function showChecklist() {
|
||||
const hadState = resetChecklistDismissals();
|
||||
toast.success(
|
||||
hadState
|
||||
? t("settings.setup.checklistShown")
|
||||
: t("settings.setup.checklistNothingHidden"),
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<SettingsCard data-slot="settings-setup-card">
|
||||
<SettingsCardHeader
|
||||
icon={ListChecks}
|
||||
title={t("settings.setup.title")}
|
||||
description={t("settings.setup.description")}
|
||||
/>
|
||||
<SettingsCardActions>
|
||||
<Button
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="min-h-11"
|
||||
onClick={showChecklist}
|
||||
data-slot="settings-show-checklist"
|
||||
>
|
||||
{t("settings.setup.showChecklist")}
|
||||
</Button>
|
||||
<Button
|
||||
type="button"
|
||||
size="sm"
|
||||
className="min-h-11"
|
||||
onClick={setUpAgain}
|
||||
disabled={restart.isPending}
|
||||
data-slot="settings-set-up-again"
|
||||
>
|
||||
{restart.isPending ? (
|
||||
<Loader2
|
||||
aria-hidden="true"
|
||||
className="size-4 animate-spin motion-reduce:animate-none"
|
||||
/>
|
||||
) : null}
|
||||
{t("settings.setup.setUpAgain")}
|
||||
</Button>
|
||||
</SettingsCardActions>
|
||||
</SettingsCard>
|
||||
);
|
||||
}
|
||||
@@ -43,6 +43,8 @@ export function GesundheitsakteSection() {
|
||||
|
||||
<section id="sharing" className="scroll-mt-28 space-y-4">
|
||||
<SectionHeading
|
||||
// The module tour's "export" stop (the doctor report) anchors here.
|
||||
tourId="export-hero"
|
||||
icon={Share2}
|
||||
title={t("settings.sections.sharing.title")}
|
||||
subtitle={t("settings.sections.sharing.subtitle")}
|
||||
|
||||
@@ -64,6 +64,8 @@ export function IntegrationsSection({
|
||||
<SectionHeading
|
||||
icon={Link2}
|
||||
title={t("settings.sections.integrations.connectionsHeading")}
|
||||
// The module tour's "integrations" stop anchors here.
|
||||
tourId="integrations-hero"
|
||||
/>
|
||||
<ConnectionsPanel callbackUrls={callbackUrls} />
|
||||
|
||||
|
||||
Reference in new issue
Block a user