From b92b9bd2b587b4c3a79f99187ea170ca0af32a17 Mon Sep 17 00:00:00 2001
From: Till-JS <101404291+Till-JS@users.noreply.github.com>
Date: Mon, 16 Feb 2026 12:50:04 +0100
Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20feat(onboarding):=20add=20app-speci?=
=?UTF-8?q?fic=20mini-onboarding=20system?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
- Create @manacore/shared-app-onboarding package with:
- createAppOnboardingStore factory function (Svelte 5 runes)
- MiniOnboardingModal component for select/toggle/info steps
- TypeScript types for flexible step configuration
- Integrate into Calendar app with questions for:
- Week start (Monday/Sunday)
- Default view (Day/Week/Month)
- Timezone preference (Auto/Manual)
- Welcome tips
The mini-onboarding stores completion state in deviceSettings,
allowing per-device, per-app onboarding experiences.
---
apps/calendar/apps/web/package.json | 1 +
.../src/lib/stores/app-onboarding.svelte.ts | 144 +++++++++++
.../apps/web/src/routes/(app)/+layout.svelte | 7 +
packages/shared-app-onboarding/package.json | 34 +++
.../src/MiniOnboardingModal.svelte | 196 +++++++++++++++
.../src/create-app-onboarding.svelte.ts | 232 ++++++++++++++++++
packages/shared-app-onboarding/src/index.ts | 20 ++
packages/shared-app-onboarding/src/types.ts | 157 ++++++++++++
packages/shared-app-onboarding/tsconfig.json | 18 ++
9 files changed, 809 insertions(+)
create mode 100644 apps/calendar/apps/web/src/lib/stores/app-onboarding.svelte.ts
create mode 100644 packages/shared-app-onboarding/package.json
create mode 100644 packages/shared-app-onboarding/src/MiniOnboardingModal.svelte
create mode 100644 packages/shared-app-onboarding/src/create-app-onboarding.svelte.ts
create mode 100644 packages/shared-app-onboarding/src/index.ts
create mode 100644 packages/shared-app-onboarding/src/types.ts
create mode 100644 packages/shared-app-onboarding/tsconfig.json
diff --git a/apps/calendar/apps/web/package.json b/apps/calendar/apps/web/package.json
index 185954e64..f6850dfe9 100644
--- a/apps/calendar/apps/web/package.json
+++ b/apps/calendar/apps/web/package.json
@@ -52,6 +52,7 @@
"@manacore/shared-types": "workspace:*",
"@manacore/shared-ui": "workspace:*",
"@manacore/shared-utils": "workspace:*",
+ "@manacore/shared-app-onboarding": "workspace:*",
"@neodrag/svelte": "^2.3.3",
"d3-force": "^3.0.0",
"date-fns": "^4.1.0",
diff --git a/apps/calendar/apps/web/src/lib/stores/app-onboarding.svelte.ts b/apps/calendar/apps/web/src/lib/stores/app-onboarding.svelte.ts
new file mode 100644
index 000000000..e9e4ba7cb
--- /dev/null
+++ b/apps/calendar/apps/web/src/lib/stores/app-onboarding.svelte.ts
@@ -0,0 +1,144 @@
+import { createAppOnboardingStore, type AppOnboardingStep } from '@manacore/shared-app-onboarding';
+import { userSettings } from './user-settings.svelte';
+
+/**
+ * Calendar-specific onboarding steps
+ */
+const calendarOnboardingSteps: AppOnboardingStep[] = [
+ {
+ id: 'weekStart',
+ type: 'select',
+ question: 'Wann beginnt deine Woche?',
+ description: 'Diese Einstellung bestimmt die Anordnung deiner Kalenderansicht.',
+ emoji: '📅',
+ gradient: { from: 'blue-500', to: 'blue-700' },
+ options: [
+ {
+ id: 'monday',
+ label: 'Montag',
+ description: 'Europäischer Standard',
+ emoji: '1️⃣',
+ },
+ {
+ id: 'sunday',
+ label: 'Sonntag',
+ description: 'Amerikanischer Standard',
+ emoji: '7️⃣',
+ },
+ ],
+ defaultValue: 'monday',
+ },
+ {
+ id: 'defaultView',
+ type: 'select',
+ question: 'Welche Ansicht bevorzugst du?',
+ description: 'Du kannst die Ansicht jederzeit in der App wechseln.',
+ emoji: '👁️',
+ gradient: { from: 'indigo-500', to: 'indigo-700' },
+ options: [
+ {
+ id: 'day',
+ label: 'Tagesansicht',
+ description: 'Detaillierte 24-Stunden-Timeline',
+ emoji: '📆',
+ },
+ {
+ id: 'week',
+ label: 'Wochenansicht',
+ description: '7-Tage-Übersicht (Empfohlen)',
+ emoji: '🗓️',
+ },
+ {
+ id: 'month',
+ label: 'Monatsansicht',
+ description: 'Kompakte Monatsübersicht',
+ emoji: '📅',
+ },
+ ],
+ defaultValue: 'week',
+ },
+ {
+ id: 'timezone',
+ type: 'select',
+ question: 'Welche Zeitzone verwendest du?',
+ description: 'Termine werden in dieser Zeitzone angezeigt.',
+ emoji: '🌍',
+ gradient: { from: 'emerald-500', to: 'emerald-700' },
+ options: [
+ {
+ id: 'auto',
+ label: 'Automatisch erkennen',
+ description: 'Basierend auf deinem Standort',
+ emoji: '📍',
+ },
+ {
+ id: 'Europe/Berlin',
+ label: 'Berlin (MEZ/MESZ)',
+ description: 'Deutschland, Österreich, Schweiz',
+ emoji: '🇩🇪',
+ },
+ {
+ id: 'Europe/London',
+ label: 'London (GMT/BST)',
+ description: 'Großbritannien',
+ emoji: '🇬🇧',
+ },
+ {
+ id: 'America/New_York',
+ label: 'New York (EST/EDT)',
+ description: 'US-Ostküste',
+ emoji: '🇺🇸',
+ },
+ ],
+ defaultValue: 'auto',
+ },
+ {
+ id: 'welcome',
+ type: 'info',
+ question: 'Dein Kalender ist bereit!',
+ description: 'Hier sind einige Tipps für den Start:',
+ emoji: '🎉',
+ gradient: { from: 'primary', to: 'primary/70' },
+ bullets: [
+ 'Nutze die Schnelleingabe unten, um Termine per Text zu erstellen',
+ 'Drücke "F" für den Fokus-Modus ohne Ablenkungen',
+ 'Pfeiltasten navigieren zwischen Tagen/Wochen',
+ 'Ziehe Termine per Drag & Drop auf neue Zeiten',
+ ],
+ },
+];
+
+/**
+ * Calendar app onboarding store
+ *
+ * Usage in components:
+ * ```svelte
+ *
+ *
+ * {#if calendarOnboarding.shouldShow}
+ *
+ * {/if}
+ * ```
+ */
+export const calendarOnboarding = createAppOnboardingStore({
+ appId: 'calendar',
+ steps: calendarOnboardingSteps,
+ userSettings,
+ onComplete: async (preferences) => {
+ console.log('[Calendar] Onboarding completed with preferences:', preferences);
+
+ // Apply preferences to the app
+ // The preferences are automatically saved to deviceSettings by the store
+ // Additional app-specific logic can go here (e.g., applying timezone, view settings)
+ },
+ onSkip: async () => {
+ console.log('[Calendar] Onboarding skipped');
+ },
+});
diff --git a/apps/calendar/apps/web/src/routes/(app)/+layout.svelte b/apps/calendar/apps/web/src/routes/(app)/+layout.svelte
index 3b4f0cf6f..d35497da8 100644
--- a/apps/calendar/apps/web/src/routes/(app)/+layout.svelte
+++ b/apps/calendar/apps/web/src/routes/(app)/+layout.svelte
@@ -64,6 +64,8 @@
import VoiceRecordingModal from '$lib/components/voice/VoiceRecordingModal.svelte';
import { voiceRecordingStore } from '$lib/stores/voice-recording.svelte';
import { eventContextMenuStore } from '$lib/stores/eventContextMenu.svelte';
+ import { calendarOnboarding } from '$lib/stores/app-onboarding.svelte';
+ import { MiniOnboardingModal } from '@manacore/shared-app-onboarding';
// App switcher items
const appItems = getPillAppItems('calendar');
@@ -653,6 +655,11 @@
(showSettingsModal = false)} />
+
+{#if calendarOnboarding.shouldShow}
+
+{/if}
+