@contractspec/example.learning-journey-registry 1.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build$colon$bundle.log +50 -0
- package/.turbo/turbo-build.log +51 -0
- package/CHANGELOG.md +348 -0
- package/LICENSE +21 -0
- package/README.md +25 -0
- package/dist/api-types.d.ts +41 -0
- package/dist/api-types.d.ts.map +1 -0
- package/dist/api-types.js +0 -0
- package/dist/api.d.ts +13 -0
- package/dist/api.d.ts.map +1 -0
- package/dist/api.js +171 -0
- package/dist/api.js.map +1 -0
- package/dist/docs/index.d.ts +1 -0
- package/dist/docs/index.js +1 -0
- package/dist/docs/learning-journey-registry.docblock.d.ts +1 -0
- package/dist/docs/learning-journey-registry.docblock.js +38 -0
- package/dist/docs/learning-journey-registry.docblock.js.map +1 -0
- package/dist/example.d.ts +33 -0
- package/dist/example.d.ts.map +1 -0
- package/dist/example.js +35 -0
- package/dist/example.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +10 -0
- package/dist/learning-journey-registry.feature.d.ts +12 -0
- package/dist/learning-journey-registry.feature.d.ts.map +1 -0
- package/dist/learning-journey-registry.feature.js +68 -0
- package/dist/learning-journey-registry.feature.js.map +1 -0
- package/dist/presentations/index.d.ts +10 -0
- package/dist/presentations/index.d.ts.map +1 -0
- package/dist/presentations/index.js +71 -0
- package/dist/presentations/index.js.map +1 -0
- package/dist/progress-store.d.ts +11 -0
- package/dist/progress-store.d.ts.map +1 -0
- package/dist/progress-store.js +31 -0
- package/dist/progress-store.js.map +1 -0
- package/dist/tracks.d.ts +40 -0
- package/dist/tracks.d.ts.map +1 -0
- package/dist/tracks.js +48 -0
- package/dist/tracks.js.map +1 -0
- package/dist/ui/LearningMiniApp.d.ts +24 -0
- package/dist/ui/LearningMiniApp.d.ts.map +1 -0
- package/dist/ui/LearningMiniApp.js +80 -0
- package/dist/ui/LearningMiniApp.js.map +1 -0
- package/dist/ui/index.d.ts +2 -0
- package/dist/ui/index.js +3 -0
- package/example.ts +1 -0
- package/package.json +89 -0
- package/src/api-types.ts +43 -0
- package/src/api.test.ts +46 -0
- package/src/api.ts +301 -0
- package/src/docs/index.ts +1 -0
- package/src/docs/learning-journey-registry.docblock.ts +36 -0
- package/src/example.ts +24 -0
- package/src/index.ts +8 -0
- package/src/learning-journey-registry.feature.ts +64 -0
- package/src/presentations/index.ts +69 -0
- package/src/progress-store.ts +39 -0
- package/src/tracks.ts +91 -0
- package/src/ui/LearningMiniApp.tsx +121 -0
- package/src/ui/index.ts +5 -0
- package/tsconfig.json +9 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/tsdown.config.js +17 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { DocBlock } from '@contractspec/lib.contracts/docs';
|
|
2
|
+
import { registerDocBlocks } from '@contractspec/lib.contracts/docs';
|
|
3
|
+
|
|
4
|
+
const registryDocBlocks: DocBlock[] = [
|
|
5
|
+
{
|
|
6
|
+
id: 'docs.learning-journey.registry',
|
|
7
|
+
title: 'Learning Journey — Example Track Registry',
|
|
8
|
+
summary:
|
|
9
|
+
'Aggregates learning journey example tracks (Studio onboarding, Platform tour, CRM first win, Drills, Ambient Coach, Quest challenges).',
|
|
10
|
+
kind: 'usage',
|
|
11
|
+
visibility: 'public',
|
|
12
|
+
route: '/docs/learning-journey/registry',
|
|
13
|
+
tags: ['learning', 'registry', 'onboarding'],
|
|
14
|
+
body: `## Tracks
|
|
15
|
+
- \`studio_getting_started\` (Studio onboarding)
|
|
16
|
+
- \`platform_primitives_tour\` (Platform primitives)
|
|
17
|
+
- \`crm_first_win\` (CRM pipeline onboarding)
|
|
18
|
+
- \`drills_language_basics\` (Drills & SRS)
|
|
19
|
+
- \`money_ambient_coach\`, \`coliving_ambient_coach\` (Ambient tips)
|
|
20
|
+
- \`money_reset_7day\` (Quest/challenge)
|
|
21
|
+
|
|
22
|
+
## Exports
|
|
23
|
+
- \`learningJourneyTracks\` — raw specs
|
|
24
|
+
- \`onboardingTrackCatalog\` — DTOs aligned with onboarding API
|
|
25
|
+
- \`mapTrackSpecToDto\` — helper to map individual tracks
|
|
26
|
+
|
|
27
|
+
## Wiring
|
|
28
|
+
- Use with onboarding API contracts:
|
|
29
|
+
- \`learning.onboarding.listTracks\`
|
|
30
|
+
- \`learning.onboarding.getProgress\`
|
|
31
|
+
- \`learning.onboarding.recordEvent\`
|
|
32
|
+
- Intended for registry/adapters in Studio UI or services that surface tracks.`,
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
registerDocBlocks(registryDocBlocks);
|
package/src/example.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
const example = {
|
|
2
|
+
id: 'learning-journey-registry',
|
|
3
|
+
title: 'Learning Journey Registry',
|
|
4
|
+
summary:
|
|
5
|
+
'Registry of learning journey tracks + presentations + UI mini-app bindings.',
|
|
6
|
+
tags: ['learning', 'journey', 'registry'],
|
|
7
|
+
kind: 'library',
|
|
8
|
+
visibility: 'public',
|
|
9
|
+
docs: {
|
|
10
|
+
rootDocId: 'docs.examples.learning-journey-registry',
|
|
11
|
+
},
|
|
12
|
+
entrypoints: {
|
|
13
|
+
packageName: '@contractspec/example.learning-journey-registry',
|
|
14
|
+
docs: './docs',
|
|
15
|
+
},
|
|
16
|
+
surfaces: {
|
|
17
|
+
templates: true,
|
|
18
|
+
sandbox: { enabled: true, modes: ['markdown', 'specs'] },
|
|
19
|
+
studio: { enabled: true, installable: true },
|
|
20
|
+
mcp: { enabled: true },
|
|
21
|
+
},
|
|
22
|
+
} as const;
|
|
23
|
+
|
|
24
|
+
export default example;
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Learning Journey Registry Feature Module Specification
|
|
3
|
+
*
|
|
4
|
+
* Defines the feature module for the learning journey registry.
|
|
5
|
+
*/
|
|
6
|
+
import type { FeatureModuleSpec } from '@contractspec/lib.contracts';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Learning Journey Registry feature module that bundles
|
|
10
|
+
* the shared presentations for learning journey tracks.
|
|
11
|
+
*/
|
|
12
|
+
export const LearningJourneyRegistryFeature: FeatureModuleSpec = {
|
|
13
|
+
meta: {
|
|
14
|
+
key: 'learning-journey-registry',
|
|
15
|
+
version: 1,
|
|
16
|
+
title: 'Learning Journey Registry',
|
|
17
|
+
description:
|
|
18
|
+
'Shared registry and presentations for learning journey tracks',
|
|
19
|
+
domain: 'learning-journey',
|
|
20
|
+
owners: ['@learning-team'],
|
|
21
|
+
tags: ['learning', 'journey', 'onboarding', 'registry'],
|
|
22
|
+
stability: 'experimental',
|
|
23
|
+
},
|
|
24
|
+
|
|
25
|
+
// No operations in the registry - it's presentation-only
|
|
26
|
+
operations: [],
|
|
27
|
+
|
|
28
|
+
// Events emitted by this feature
|
|
29
|
+
events: [],
|
|
30
|
+
|
|
31
|
+
// Presentations associated with this feature
|
|
32
|
+
presentations: [
|
|
33
|
+
{ key: 'learning.journey.track_list', version: 1 },
|
|
34
|
+
{ key: 'learning.journey.track_detail', version: 1 },
|
|
35
|
+
{ key: 'learning.journey.progress_widget', version: 1 },
|
|
36
|
+
],
|
|
37
|
+
|
|
38
|
+
// No op to presentation links for registry
|
|
39
|
+
opToPresentation: [],
|
|
40
|
+
|
|
41
|
+
// Target requirements for multi-surface rendering
|
|
42
|
+
presentationsTargets: [
|
|
43
|
+
{
|
|
44
|
+
key: 'learning.journey.track_list',
|
|
45
|
+
version: 1,
|
|
46
|
+
targets: ['react', 'markdown'],
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
key: 'learning.journey.track_detail',
|
|
50
|
+
version: 1,
|
|
51
|
+
targets: ['react', 'markdown', 'application/json'],
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
key: 'learning.journey.progress_widget',
|
|
55
|
+
version: 1,
|
|
56
|
+
targets: ['react'],
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
|
|
60
|
+
// Capability requirements
|
|
61
|
+
capabilities: {
|
|
62
|
+
requires: [{ key: 'identity', version: 1 }],
|
|
63
|
+
},
|
|
64
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
PresentationSpecMeta,
|
|
3
|
+
PresentationSpec,
|
|
4
|
+
} from '@contractspec/lib.contracts';
|
|
5
|
+
import { StabilityEnum } from '@contractspec/lib.contracts';
|
|
6
|
+
|
|
7
|
+
const baseMeta: Pick<
|
|
8
|
+
PresentationSpecMeta,
|
|
9
|
+
'domain' | 'owners' | 'tags' | 'title' | 'stability' | 'goal' | 'context'
|
|
10
|
+
> = {
|
|
11
|
+
domain: 'learning-journey',
|
|
12
|
+
title: 'Learning Journey',
|
|
13
|
+
owners: ['@learning-team'] as string[],
|
|
14
|
+
tags: ['learning', 'journey', 'onboarding'] as string[],
|
|
15
|
+
stability: StabilityEnum.Experimental,
|
|
16
|
+
goal: 'Progress through learning tracks',
|
|
17
|
+
context: 'Learning journey section',
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const LearningTrackListPresentation: PresentationSpec = {
|
|
21
|
+
meta: {
|
|
22
|
+
key: 'learning.journey.track_list',
|
|
23
|
+
version: 1,
|
|
24
|
+
description: 'List of learning journeys available to the learner.',
|
|
25
|
+
...baseMeta,
|
|
26
|
+
},
|
|
27
|
+
source: {
|
|
28
|
+
type: 'component',
|
|
29
|
+
framework: 'react',
|
|
30
|
+
componentKey: 'LearningTrackList',
|
|
31
|
+
},
|
|
32
|
+
targets: ['react', 'markdown'],
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const LearningTrackDetailPresentation: PresentationSpec = {
|
|
36
|
+
meta: {
|
|
37
|
+
key: 'learning.journey.track_detail',
|
|
38
|
+
version: 1,
|
|
39
|
+
description: 'Track detail with steps and progress state.',
|
|
40
|
+
...baseMeta,
|
|
41
|
+
},
|
|
42
|
+
source: {
|
|
43
|
+
type: 'component',
|
|
44
|
+
framework: 'react',
|
|
45
|
+
componentKey: 'LearningTrackDetail',
|
|
46
|
+
},
|
|
47
|
+
targets: ['react', 'markdown', 'application/json'],
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export const LearningTrackProgressWidgetPresentation: PresentationSpec = {
|
|
51
|
+
meta: {
|
|
52
|
+
key: 'learning.journey.progress_widget',
|
|
53
|
+
version: 1,
|
|
54
|
+
description: 'Compact widget showing progress for active track.',
|
|
55
|
+
...baseMeta,
|
|
56
|
+
},
|
|
57
|
+
source: {
|
|
58
|
+
type: 'component',
|
|
59
|
+
framework: 'react',
|
|
60
|
+
componentKey: 'LearningTrackProgressWidget',
|
|
61
|
+
},
|
|
62
|
+
targets: ['react'],
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export const learningJourneyPresentations = [
|
|
66
|
+
LearningTrackListPresentation,
|
|
67
|
+
LearningTrackDetailPresentation,
|
|
68
|
+
LearningTrackProgressWidgetPresentation,
|
|
69
|
+
];
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { LearningJourneyTrackSpec } from '@contractspec/module.learning-journey/track-spec';
|
|
2
|
+
|
|
3
|
+
import type { TrackProgress } from './api-types';
|
|
4
|
+
|
|
5
|
+
export const progressStore = new Map<string, Map<string, TrackProgress>>();
|
|
6
|
+
|
|
7
|
+
export const getTrackResolver =
|
|
8
|
+
(tracks: LearningJourneyTrackSpec[]) =>
|
|
9
|
+
(trackId: string): LearningJourneyTrackSpec | undefined =>
|
|
10
|
+
tracks.find((t) => t.id === trackId);
|
|
11
|
+
|
|
12
|
+
export const getLearnerTracks = (learnerId: string) => {
|
|
13
|
+
const existing = progressStore.get(learnerId);
|
|
14
|
+
if (existing) return existing;
|
|
15
|
+
const map = new Map<string, TrackProgress>();
|
|
16
|
+
progressStore.set(learnerId, map);
|
|
17
|
+
return map;
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export const initProgress = (
|
|
21
|
+
learnerId: string,
|
|
22
|
+
track: LearningJourneyTrackSpec
|
|
23
|
+
): TrackProgress => ({
|
|
24
|
+
learnerId,
|
|
25
|
+
trackId: track.id,
|
|
26
|
+
progress: 0,
|
|
27
|
+
isCompleted: false,
|
|
28
|
+
xpEarned: 0,
|
|
29
|
+
steps: track.steps.map((step) => ({
|
|
30
|
+
id: step.id,
|
|
31
|
+
status: 'PENDING',
|
|
32
|
+
xpEarned: 0,
|
|
33
|
+
occurrences: 0,
|
|
34
|
+
masteryCount: 0,
|
|
35
|
+
})),
|
|
36
|
+
startedAt: undefined,
|
|
37
|
+
completedAt: undefined,
|
|
38
|
+
lastActivityAt: undefined,
|
|
39
|
+
});
|
package/src/tracks.ts
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
LearningJourneyStepSpec,
|
|
3
|
+
LearningJourneyTrackSpec,
|
|
4
|
+
StepAvailabilitySpec,
|
|
5
|
+
StepCompletionConditionSpec,
|
|
6
|
+
} from '@contractspec/module.learning-journey/track-spec';
|
|
7
|
+
import { crmLearningTracks } from '@contractspec/example.learning-journey-crm-onboarding/track';
|
|
8
|
+
import { drillTracks } from '@contractspec/example.learning-journey-duo-drills/track';
|
|
9
|
+
import { ambientCoachTracks } from '@contractspec/example.learning-journey-ambient-coach/track';
|
|
10
|
+
import { questTracks } from '@contractspec/example.learning-journey-quest-challenges/track';
|
|
11
|
+
import { platformLearningTracks } from '@contractspec/example.learning-journey-platform-tour/track';
|
|
12
|
+
import { studioLearningTracks } from '@contractspec/example.learning-journey-studio-onboarding/track';
|
|
13
|
+
|
|
14
|
+
export interface OnboardingStepDto {
|
|
15
|
+
id: string;
|
|
16
|
+
title: string;
|
|
17
|
+
description?: string;
|
|
18
|
+
completionEvent: string;
|
|
19
|
+
completionCondition?: StepCompletionConditionSpec;
|
|
20
|
+
xpReward?: number;
|
|
21
|
+
isRequired?: boolean;
|
|
22
|
+
canSkip?: boolean;
|
|
23
|
+
actionUrl?: string;
|
|
24
|
+
actionLabel?: string;
|
|
25
|
+
availability?: StepAvailabilitySpec;
|
|
26
|
+
metadata?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export interface OnboardingTrackDto {
|
|
30
|
+
id: string;
|
|
31
|
+
name: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
productId?: string;
|
|
34
|
+
targetUserSegment?: string;
|
|
35
|
+
targetRole?: string;
|
|
36
|
+
totalXp?: number;
|
|
37
|
+
streakRule?: LearningJourneyTrackSpec['streakRule'];
|
|
38
|
+
completionRewards?: LearningJourneyTrackSpec['completionRewards'];
|
|
39
|
+
steps: OnboardingStepDto[];
|
|
40
|
+
metadata?: Record<string, unknown>;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const mapStep = (step: LearningJourneyStepSpec): OnboardingStepDto => ({
|
|
44
|
+
id: step.id,
|
|
45
|
+
title: step.title,
|
|
46
|
+
description: step.description,
|
|
47
|
+
completionEvent: step.completion.eventName,
|
|
48
|
+
completionCondition: step.completion,
|
|
49
|
+
xpReward: step.xpReward,
|
|
50
|
+
isRequired: step.isRequired,
|
|
51
|
+
canSkip: step.canSkip,
|
|
52
|
+
actionUrl: step.actionUrl,
|
|
53
|
+
actionLabel: step.actionLabel,
|
|
54
|
+
availability: step.availability,
|
|
55
|
+
metadata: step.metadata,
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export const mapTrackSpecToDto = (
|
|
59
|
+
track: LearningJourneyTrackSpec
|
|
60
|
+
): OnboardingTrackDto => ({
|
|
61
|
+
id: track.id,
|
|
62
|
+
name: track.name,
|
|
63
|
+
description: track.description,
|
|
64
|
+
productId: track.productId,
|
|
65
|
+
targetUserSegment: track.targetUserSegment,
|
|
66
|
+
targetRole: track.targetRole,
|
|
67
|
+
totalXp: track.totalXp,
|
|
68
|
+
streakRule: track.streakRule,
|
|
69
|
+
completionRewards: track.completionRewards,
|
|
70
|
+
steps: track.steps.map(mapStep),
|
|
71
|
+
metadata: track.metadata,
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
export const learningJourneyTracks: LearningJourneyTrackSpec[] = [
|
|
75
|
+
...studioLearningTracks,
|
|
76
|
+
...platformLearningTracks,
|
|
77
|
+
...crmLearningTracks,
|
|
78
|
+
...drillTracks,
|
|
79
|
+
...ambientCoachTracks,
|
|
80
|
+
...questTracks,
|
|
81
|
+
];
|
|
82
|
+
|
|
83
|
+
export const onboardingTrackCatalog: OnboardingTrackDto[] =
|
|
84
|
+
learningJourneyTracks.map(mapTrackSpecToDto);
|
|
85
|
+
|
|
86
|
+
export {
|
|
87
|
+
studioLearningTracks,
|
|
88
|
+
platformLearningTracks,
|
|
89
|
+
crmLearningTracks,
|
|
90
|
+
mapStep,
|
|
91
|
+
};
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useMemo } from 'react';
|
|
4
|
+
import { GamifiedMiniApp } from '@contractspec/example.learning-journey-ui-gamified';
|
|
5
|
+
import { OnboardingMiniApp } from '@contractspec/example.learning-journey-ui-onboarding';
|
|
6
|
+
import { CoachingMiniApp } from '@contractspec/example.learning-journey-ui-coaching';
|
|
7
|
+
import type { LearningView } from '@contractspec/example.learning-journey-ui-shared';
|
|
8
|
+
import { learningJourneyTracks } from '../tracks';
|
|
9
|
+
|
|
10
|
+
/** Template IDs that map to learning journey tracks */
|
|
11
|
+
type LearningTemplateId =
|
|
12
|
+
| 'learning-journey-duo-drills'
|
|
13
|
+
| 'learning-journey-quest-challenges'
|
|
14
|
+
| 'learning-journey-studio-onboarding'
|
|
15
|
+
| 'learning-journey-platform-tour'
|
|
16
|
+
| 'learning-journey-ambient-coach'
|
|
17
|
+
| 'learning-journey-crm-onboarding';
|
|
18
|
+
|
|
19
|
+
/** Map template IDs to track IDs */
|
|
20
|
+
const TEMPLATE_TO_TRACK: Record<LearningTemplateId, string> = {
|
|
21
|
+
'learning-journey-duo-drills': 'drills_language_basics',
|
|
22
|
+
'learning-journey-quest-challenges': 'money_reset_7day',
|
|
23
|
+
'learning-journey-studio-onboarding': 'studio_getting_started',
|
|
24
|
+
'learning-journey-platform-tour': 'platform_tour',
|
|
25
|
+
'learning-journey-ambient-coach': 'money_ambient_coach',
|
|
26
|
+
'learning-journey-crm-onboarding': 'crm_first_win',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
/** Map template IDs to mini-app type */
|
|
30
|
+
const TEMPLATE_TO_APP_TYPE: Record<
|
|
31
|
+
LearningTemplateId,
|
|
32
|
+
'gamified' | 'onboarding' | 'coaching'
|
|
33
|
+
> = {
|
|
34
|
+
'learning-journey-duo-drills': 'gamified',
|
|
35
|
+
'learning-journey-quest-challenges': 'gamified',
|
|
36
|
+
'learning-journey-studio-onboarding': 'onboarding',
|
|
37
|
+
'learning-journey-platform-tour': 'onboarding',
|
|
38
|
+
'learning-journey-ambient-coach': 'coaching',
|
|
39
|
+
'learning-journey-crm-onboarding': 'coaching',
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
interface LearningMiniAppProps {
|
|
43
|
+
templateId: string;
|
|
44
|
+
initialView?: LearningView;
|
|
45
|
+
onViewChange?: (view: LearningView) => void;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/** Router component that picks the correct mini-app based on template ID */
|
|
49
|
+
export function LearningMiniApp({
|
|
50
|
+
templateId,
|
|
51
|
+
initialView = 'overview',
|
|
52
|
+
onViewChange,
|
|
53
|
+
}: LearningMiniAppProps) {
|
|
54
|
+
// Find the track for this template
|
|
55
|
+
const track = useMemo(() => {
|
|
56
|
+
const trackId = TEMPLATE_TO_TRACK[templateId as LearningTemplateId];
|
|
57
|
+
if (!trackId) return null;
|
|
58
|
+
return learningJourneyTracks.find((t) => t.id === trackId);
|
|
59
|
+
}, [templateId]);
|
|
60
|
+
|
|
61
|
+
// Determine app type
|
|
62
|
+
const appType = TEMPLATE_TO_APP_TYPE[templateId as LearningTemplateId];
|
|
63
|
+
|
|
64
|
+
if (!track) {
|
|
65
|
+
return (
|
|
66
|
+
<div className="rounded-lg border border-amber-500/50 bg-amber-500/10 p-6 text-center">
|
|
67
|
+
<p className="text-amber-500">
|
|
68
|
+
Unknown learning template: {templateId}
|
|
69
|
+
</p>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Render the appropriate mini-app
|
|
75
|
+
switch (appType) {
|
|
76
|
+
case 'gamified':
|
|
77
|
+
return (
|
|
78
|
+
<GamifiedMiniApp
|
|
79
|
+
track={track}
|
|
80
|
+
initialView={initialView}
|
|
81
|
+
onViewChange={onViewChange}
|
|
82
|
+
/>
|
|
83
|
+
);
|
|
84
|
+
case 'onboarding':
|
|
85
|
+
return (
|
|
86
|
+
<OnboardingMiniApp
|
|
87
|
+
track={track}
|
|
88
|
+
initialView={initialView}
|
|
89
|
+
onViewChange={onViewChange}
|
|
90
|
+
/>
|
|
91
|
+
);
|
|
92
|
+
case 'coaching':
|
|
93
|
+
return (
|
|
94
|
+
<CoachingMiniApp
|
|
95
|
+
track={track}
|
|
96
|
+
initialView={initialView}
|
|
97
|
+
onViewChange={onViewChange}
|
|
98
|
+
/>
|
|
99
|
+
);
|
|
100
|
+
default:
|
|
101
|
+
return (
|
|
102
|
+
<div className="rounded-lg border border-red-500/50 bg-red-500/10 p-6 text-center">
|
|
103
|
+
<p className="text-red-500">
|
|
104
|
+
Unknown app type for template: {templateId}
|
|
105
|
+
</p>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** Check if a template ID is a learning journey template */
|
|
112
|
+
export function isLearningTemplate(
|
|
113
|
+
templateId: string
|
|
114
|
+
): templateId is LearningTemplateId {
|
|
115
|
+
return templateId in TEMPLATE_TO_TRACK;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/** Get all learning template IDs */
|
|
119
|
+
export function getLearningTemplateIds(): LearningTemplateId[] {
|
|
120
|
+
return Object.keys(TEMPLATE_TO_TRACK) as LearningTemplateId[];
|
|
121
|
+
}
|
package/src/ui/index.ts
ADDED