mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-27 06:57:43 +02:00
feat(shared-auth-ui): add GuestRegistrationNudge + complete feature texts + improve seed data
- Add GuestRegistrationNudge component: shows a floating banner after X minutes of guest usage to encourage sign-up (bottom-center, dismissible) - Add guestNudge.ts utilities (session tracking, delay, dismiss via localStorage) - Add feature texts for all 16 missing apps in GuestWelcomeModal - Integrate nudge in Todo app as reference implementation (3min delay) - Improve SkillTree seed: 3 skills across branches, 6 activities, 1 achievement - Improve Zitare seed: 5 favorites, 2 themed lists instead of 1 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
4d0e9a6a3f
commit
1570cc0bb4
8 changed files with 439 additions and 20 deletions
|
|
@ -1,32 +1,45 @@
|
|||
/**
|
||||
* Guest seed data for the SkilltTree app.
|
||||
*
|
||||
* Provides a demo skill with an activity to showcase the leveling system.
|
||||
* Provides demo skills across multiple branches with activities and an achievement
|
||||
* to showcase the leveling system, XP progression, and activity feed.
|
||||
*/
|
||||
|
||||
import type { LocalSkill, LocalActivity } from './local-store';
|
||||
import type { LocalSkill, LocalActivity, LocalAchievement } from './local-store';
|
||||
|
||||
const DEMO_SKILL_ID = 'demo-coding';
|
||||
const DEMO_CODING_ID = 'demo-coding';
|
||||
const DEMO_FITNESS_ID = 'demo-fitness';
|
||||
const DEMO_CREATIVE_ID = 'demo-creative';
|
||||
|
||||
export const guestSkills: LocalSkill[] = [
|
||||
{
|
||||
id: DEMO_SKILL_ID,
|
||||
id: DEMO_CODING_ID,
|
||||
name: 'Programmieren',
|
||||
description: 'Software-Entwicklung und Coding-Skills',
|
||||
branch: 'intellect',
|
||||
icon: '💻',
|
||||
currentXp: 150,
|
||||
totalXp: 150,
|
||||
currentXp: 250,
|
||||
totalXp: 250,
|
||||
level: 1,
|
||||
},
|
||||
{
|
||||
id: 'demo-fitness',
|
||||
id: DEMO_FITNESS_ID,
|
||||
name: 'Fitness',
|
||||
description: 'Körperliche Fitness und Training',
|
||||
branch: 'body',
|
||||
icon: '💪',
|
||||
currentXp: 50,
|
||||
totalXp: 50,
|
||||
currentXp: 120,
|
||||
totalXp: 120,
|
||||
level: 1,
|
||||
},
|
||||
{
|
||||
id: DEMO_CREATIVE_ID,
|
||||
name: 'Zeichnen',
|
||||
description: 'Illustration, Skizzen und visuelles Denken',
|
||||
branch: 'creativity',
|
||||
icon: '🎨',
|
||||
currentXp: 60,
|
||||
totalXp: 60,
|
||||
level: 0,
|
||||
},
|
||||
];
|
||||
|
|
@ -34,18 +47,61 @@ export const guestSkills: LocalSkill[] = [
|
|||
export const guestActivities: LocalActivity[] = [
|
||||
{
|
||||
id: 'activity-1',
|
||||
skillId: DEMO_SKILL_ID,
|
||||
skillId: DEMO_CODING_ID,
|
||||
xpEarned: 100,
|
||||
description: 'TypeScript-Projekt aufgesetzt',
|
||||
duration: 60,
|
||||
timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
timestamp: new Date(Date.now() - 4 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id: 'activity-2',
|
||||
skillId: DEMO_SKILL_ID,
|
||||
skillId: DEMO_FITNESS_ID,
|
||||
xpEarned: 50,
|
||||
description: '5 km Joggen im Park',
|
||||
duration: 35,
|
||||
timestamp: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id: 'activity-3',
|
||||
skillId: DEMO_CODING_ID,
|
||||
xpEarned: 100,
|
||||
description: 'REST API mit Hono gebaut',
|
||||
duration: 90,
|
||||
timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id: 'activity-4',
|
||||
skillId: DEMO_CREATIVE_ID,
|
||||
xpEarned: 60,
|
||||
description: 'Erste Skizzen mit Procreate',
|
||||
duration: 45,
|
||||
timestamp: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id: 'activity-5',
|
||||
skillId: DEMO_FITNESS_ID,
|
||||
xpEarned: 70,
|
||||
description: 'Krafttraining — Oberkörper',
|
||||
duration: 50,
|
||||
timestamp: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
},
|
||||
{
|
||||
id: 'activity-6',
|
||||
skillId: DEMO_CODING_ID,
|
||||
xpEarned: 50,
|
||||
description: 'Unit Tests geschrieben',
|
||||
duration: 30,
|
||||
timestamp: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
timestamp: new Date(Date.now() - 12 * 60 * 60 * 1000).toISOString(),
|
||||
},
|
||||
];
|
||||
|
||||
export const guestAchievements: LocalAchievement[] = [
|
||||
{
|
||||
id: 'achievement-1',
|
||||
key: 'first-skill',
|
||||
name: 'Erste Schritte',
|
||||
description: 'Deinen ersten Skill erstellt',
|
||||
icon: '🌱',
|
||||
unlockedAt: new Date(Date.now() - 4 * 24 * 60 * 60 * 1000).toISOString(),
|
||||
},
|
||||
];
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { createLocalStore, type BaseRecord } from '@manacore/local-store';
|
||||
import { guestSkills, guestActivities } from './guest-seed';
|
||||
import { guestSkills, guestActivities, guestAchievements } from './guest-seed';
|
||||
|
||||
// ─── Types ──────────────────────────────────────────────────
|
||||
|
||||
|
|
@ -58,6 +58,7 @@ export const skilltreeStore = createLocalStore({
|
|||
{
|
||||
name: 'achievements',
|
||||
indexes: ['key', 'unlockedAt'],
|
||||
guestSeed: guestAchievements,
|
||||
},
|
||||
],
|
||||
sync: {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,12 @@
|
|||
import { parseTaskInput, resolveTaskIds, formatParsedTaskPreview } from '$lib/utils/task-parser';
|
||||
import { todoOnboarding } from '$lib/stores/app-onboarding.svelte';
|
||||
import { MiniOnboardingModal } from '@manacore/shared-app-onboarding';
|
||||
import { SessionExpiredBanner, AuthGate, GuestWelcomeModal } from '@manacore/shared-auth-ui';
|
||||
import {
|
||||
SessionExpiredBanner,
|
||||
AuthGate,
|
||||
GuestWelcomeModal,
|
||||
GuestRegistrationNudge,
|
||||
} from '@manacore/shared-auth-ui';
|
||||
import { shouldShowGuestWelcome } from '@manacore/shared-auth-ui';
|
||||
import { TodoEvents } from '@manacore/shared-utils/analytics';
|
||||
import { todoStore, taskCollection } from '$lib/data/local-store';
|
||||
|
|
@ -554,6 +559,13 @@
|
|||
|
||||
{#if authStore.isAuthenticated}
|
||||
<SessionExpiredBanner locale={$locale || 'de'} loginHref="/login" />
|
||||
{:else}
|
||||
<GuestRegistrationNudge
|
||||
appId="todo"
|
||||
onRegister={() => goto('/register')}
|
||||
locale={($locale || 'de') === 'de' ? 'de' : 'en'}
|
||||
delayMinutes={3}
|
||||
/>
|
||||
{/if}
|
||||
</AuthGate>
|
||||
|
||||
|
|
|
|||
|
|
@ -5,18 +5,26 @@
|
|||
|
||||
import type { LocalFavorite, LocalQuoteList } from './local-store';
|
||||
|
||||
// Some well-known quote IDs from the content package
|
||||
// Well-known quote IDs from @zitare/content
|
||||
export const guestFavorites: LocalFavorite[] = [
|
||||
{ id: 'fav-1', quoteId: 'mot-1' },
|
||||
{ id: 'fav-2', quoteId: 'weis-3' },
|
||||
{ id: 'fav-3', quoteId: 'mot-7' },
|
||||
{ id: 'fav-4', quoteId: 'weis-1' },
|
||||
{ id: 'fav-5', quoteId: 'liebe-1' },
|
||||
];
|
||||
|
||||
export const guestLists: LocalQuoteList[] = [
|
||||
{
|
||||
id: 'list-onboarding',
|
||||
name: 'Meine Lieblingszitate',
|
||||
description: 'Eine Beispiel-Sammlung zum Ausprobieren',
|
||||
quoteIds: ['mot-1', 'weis-3'],
|
||||
id: 'list-motivation',
|
||||
name: 'Motivation & Antrieb',
|
||||
description: 'Zitate die dich voranbringen',
|
||||
quoteIds: ['mot-1', 'mot-7', 'mot-3'],
|
||||
},
|
||||
{
|
||||
id: 'list-weisheit',
|
||||
name: 'Zeitlose Weisheiten',
|
||||
description: 'Die großen Denker und Dichter',
|
||||
quoteIds: ['weis-1', 'weis-3', 'weis-5'],
|
||||
},
|
||||
];
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue