From e5cd98936fab626a5711d251687ca4a3f6bcd091 Mon Sep 17 00:00:00 2001 From: Till JS Date: Sun, 26 Apr 2026 21:52:52 +0200 Subject: [PATCH] feat(onboarding): card redesign + add wish step routing to feedback hub MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Onboarding wird zur 4-Step-Card im Workbench-Look und schließt mit einer Freitext-Frage, die als @mana/feedback-Record landet. UI-Redesign: - Wraps die Screens in einer zentrierten Card mit ModuleShell-Chrome (paper texture, soft border, 1.25rem radius, dual shadow). Liest sich wie eine Workbench-Page statt eines flat Takeover-Screens. - Header weg. Globaler Skip-Button sitzt unten links, Step-Dots zentriert unten — drei-Spalten-Grid hält Dots perfekt zentriert egal wie breit der Skip-Button ist. - Per-Screen-Skip-Buttons aus name/ und templates/ entfernt — eine einzige Skip-Affordance reicht. Wish-Step (neu, Step 4): - /onboarding/wish: Freitext-Textarea (max 2000), Aktivierungstext ("Eine letzte Sache — was wünschst du dir von Mana?"). Submit postet fail-soft an feedbackService.createFeedback({ category: 'onboarding-wish', isPublic: false }) — Server-Down blockiert das Onboarding nicht. - onboarding-flow Store um pendingWish erweitert (Back-Nav-Preserve). - Layout: 3 → 4 Step-Dots, Path-Mapping erweitert. - markComplete + reset wandert von templates' Fertig-Handler in den wish-Screen; templates' Button heißt jetzt "Weiter" und routet zu /onboarding/wish. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../src/lib/stores/onboarding-flow.svelte.ts | 12 +- .../routes/(app)/onboarding/+layout.svelte | 217 ++++++++++++----- .../routes/(app)/onboarding/name/+page.svelte | 40 +-- .../(app)/onboarding/templates/+page.svelte | 60 ++--- .../routes/(app)/onboarding/wish/+page.svelte | 229 ++++++++++++++++++ 5 files changed, 412 insertions(+), 146 deletions(-) create mode 100644 apps/mana/apps/web/src/routes/(app)/onboarding/wish/+page.svelte diff --git a/apps/mana/apps/web/src/lib/stores/onboarding-flow.svelte.ts b/apps/mana/apps/web/src/lib/stores/onboarding-flow.svelte.ts index 4648b0696..c86d2827a 100644 --- a/apps/mana/apps/web/src/lib/stores/onboarding-flow.svelte.ts +++ b/apps/mana/apps/web/src/lib/stores/onboarding-flow.svelte.ts @@ -1,8 +1,8 @@ /** - * Ephemeral state for the three-screen onboarding flow — holds values + * Ephemeral state for the four-screen onboarding flow — holds values * a later screen needs from an earlier screen (the freshly-typed name * for Screen 2's greeting, the multi-selected template ids for the - * Screen 3 finish handler). + * Screen 3 finish handler, the wish text for Screen 4's submit). * * Deliberately module-local and non-persistent: * - The canonical source of truth is `authStore.user` (name) and the @@ -18,6 +18,7 @@ let pendingName = $state(null); let selectedTemplateIds = $state([]); +let pendingWish = $state(''); export const onboardingFlow = { get pendingName() { @@ -26,14 +27,21 @@ export const onboardingFlow = { get selectedTemplateIds() { return selectedTemplateIds; }, + get pendingWish() { + return pendingWish; + }, setPendingName(value: string) { pendingName = value.trim() || null; }, setSelectedTemplateIds(ids: string[]) { selectedTemplateIds = ids; }, + setPendingWish(value: string) { + pendingWish = value; + }, reset() { pendingName = null; selectedTemplateIds = []; + pendingWish = ''; }, }; diff --git a/apps/mana/apps/web/src/routes/(app)/onboarding/+layout.svelte b/apps/mana/apps/web/src/routes/(app)/onboarding/+layout.svelte index 5f08fe995..33467336d 100644 --- a/apps/mana/apps/web/src/routes/(app)/onboarding/+layout.svelte +++ b/apps/mana/apps/web/src/routes/(app)/onboarding/+layout.svelte @@ -1,16 +1,22 @@
-
-
- {#each [0, 1, 2] as step (step)} - - {/each} -
- -
+
+
+ {@render children()} +
-
- {@render children()} -
+
+ +
+ {#each [0, 1, 2, 3] as step (step)} + + {/each} +
+ +
+
diff --git a/apps/mana/apps/web/src/routes/(app)/onboarding/name/+page.svelte b/apps/mana/apps/web/src/routes/(app)/onboarding/name/+page.svelte index ba8bda267..748b700b8 100644 --- a/apps/mana/apps/web/src/routes/(app)/onboarding/name/+page.svelte +++ b/apps/mana/apps/web/src/routes/(app)/onboarding/name/+page.svelte @@ -60,23 +60,6 @@ } } - async function handleSkip() { - const fallback = (authStore.user?.email ?? '').split('@')[0] || 'du'; - saving = true; - error = null; - try { - // Persist the fallback too so the user shows up as something - // other than "User 1234" in admin UIs — cheap, idempotent. - await saveName(fallback); - } catch (err) { - console.warn('[onboarding/name] skip-save failed:', err); - } finally { - saving = false; - } - onboardingFlow.setPendingName(fallback); - await goto('/onboarding/look'); - } - function handleKeydown(e: KeyboardEvent) { if (e.key === 'Enter' && canSubmit) { e.preventDefault(); @@ -109,9 +92,6 @@
- + +
+ + +