@contractspec/example.learning-journey-ui-gamified 3.7.5 → 3.7.7

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.
Files changed (57) hide show
  1. package/.turbo/turbo-build.log +5 -5
  2. package/AGENTS.md +50 -25
  3. package/CHANGELOG.md +14 -0
  4. package/README.md +63 -20
  5. package/dist/GamifiedMiniApp.js +246 -246
  6. package/dist/browser/GamifiedMiniApp.js +246 -246
  7. package/dist/browser/components/DayCalendar.js +1 -1
  8. package/dist/browser/components/FlashCard.js +6 -6
  9. package/dist/browser/components/MasteryRing.js +1 -1
  10. package/dist/browser/components/index.js +100 -100
  11. package/dist/browser/index.js +247 -246
  12. package/dist/browser/views/Overview.js +16 -16
  13. package/dist/browser/views/Progress.js +7 -7
  14. package/dist/browser/views/Steps.js +8 -8
  15. package/dist/browser/views/Timeline.js +8 -8
  16. package/dist/browser/views/index.js +242 -242
  17. package/dist/components/DayCalendar.js +1 -1
  18. package/dist/components/FlashCard.js +6 -6
  19. package/dist/components/MasteryRing.js +1 -1
  20. package/dist/components/index.d.ts +1 -1
  21. package/dist/components/index.js +100 -100
  22. package/dist/index.d.ts +3 -3
  23. package/dist/index.js +247 -246
  24. package/dist/node/GamifiedMiniApp.js +246 -246
  25. package/dist/node/components/DayCalendar.js +1 -1
  26. package/dist/node/components/FlashCard.js +6 -6
  27. package/dist/node/components/MasteryRing.js +1 -1
  28. package/dist/node/components/index.js +100 -100
  29. package/dist/node/index.js +247 -246
  30. package/dist/node/views/Overview.js +16 -16
  31. package/dist/node/views/Progress.js +7 -7
  32. package/dist/node/views/Steps.js +8 -8
  33. package/dist/node/views/Timeline.js +8 -8
  34. package/dist/node/views/index.js +242 -242
  35. package/dist/views/Overview.js +16 -16
  36. package/dist/views/Progress.js +7 -7
  37. package/dist/views/Steps.js +8 -8
  38. package/dist/views/Timeline.js +8 -8
  39. package/dist/views/index.d.ts +1 -1
  40. package/dist/views/index.js +242 -242
  41. package/package.json +12 -12
  42. package/src/GamifiedMiniApp.tsx +70 -70
  43. package/src/components/DayCalendar.tsx +41 -41
  44. package/src/components/FlashCard.tsx +83 -83
  45. package/src/components/MasteryRing.tsx +64 -64
  46. package/src/components/index.ts +1 -1
  47. package/src/docs/learning-journey-ui-gamified.docblock.ts +11 -11
  48. package/src/example.ts +25 -25
  49. package/src/index.ts +5 -6
  50. package/src/learning-journey-ui-gamified.feature.ts +12 -12
  51. package/src/views/Overview.tsx +145 -145
  52. package/src/views/Progress.tsx +167 -167
  53. package/src/views/Steps.tsx +40 -40
  54. package/src/views/Timeline.tsx +177 -177
  55. package/src/views/index.ts +1 -1
  56. package/tsconfig.json +7 -8
  57. package/tsdown.config.js +7 -13
@@ -2,17 +2,17 @@ import type { DocBlock } from '@contractspec/lib.contracts-spec/docs';
2
2
  import { registerDocBlocks } from '@contractspec/lib.contracts-spec/docs';
3
3
 
4
4
  const blocks: DocBlock[] = [
5
- {
6
- id: 'docs.examples.learning-journey-ui-gamified',
7
- title: 'Learning Journey UI — Gamified',
8
- summary:
9
- 'UI mini-app components for gamified learning: flashcards, mastery, streak/calendar.',
10
- kind: 'reference',
11
- visibility: 'public',
12
- route: '/docs/examples/learning-journey-ui-gamified',
13
- tags: ['learning', 'ui', 'gamified'],
14
- body: `## Includes\n- Gamified mini-app shell\n- Views: overview, steps, progress, timeline\n- Components: flash card, mastery ring, day calendar\n\n## Notes\n- Compose with design system components.\n- Respect prefers-reduced-motion; keep tap targets large.`,
15
- },
5
+ {
6
+ id: 'docs.examples.learning-journey-ui-gamified',
7
+ title: 'Learning Journey UI — Gamified',
8
+ summary:
9
+ 'UI mini-app components for gamified learning: flashcards, mastery, streak/calendar.',
10
+ kind: 'reference',
11
+ visibility: 'public',
12
+ route: '/docs/examples/learning-journey-ui-gamified',
13
+ tags: ['learning', 'ui', 'gamified'],
14
+ body: `## Includes\n- Gamified mini-app shell\n- Views: overview, steps, progress, timeline\n- Components: flash card, mastery ring, day calendar\n\n## Notes\n- Compose with design system components.\n- Respect prefers-reduced-motion; keep tap targets large.`,
15
+ },
16
16
  ];
17
17
 
18
18
  registerDocBlocks(blocks);
package/src/example.ts CHANGED
@@ -1,31 +1,31 @@
1
1
  import { defineExample } from '@contractspec/lib.contracts-spec';
2
2
 
3
3
  const example = defineExample({
4
- meta: {
5
- key: 'learning-journey-ui-gamified',
6
- version: '1.0.0',
7
- title: 'Learning Journey UI — Gamified',
8
- description:
9
- 'UI mini-app for gamified learning: flashcards, mastery ring, calendar.',
10
- kind: 'ui',
11
- visibility: 'public',
12
- stability: 'experimental',
13
- owners: ['@platform.core'],
14
- tags: ['learning', 'ui', 'gamified'],
15
- },
16
- docs: {
17
- rootDocId: 'docs.examples.learning-journey-ui-gamified',
18
- },
19
- entrypoints: {
20
- packageName: '@contractspec/example.learning-journey-ui-gamified',
21
- docs: './docs',
22
- },
23
- surfaces: {
24
- templates: true,
25
- sandbox: { enabled: true, modes: ['playground', 'markdown'] },
26
- studio: { enabled: true, installable: true },
27
- mcp: { enabled: true },
28
- },
4
+ meta: {
5
+ key: 'learning-journey-ui-gamified',
6
+ version: '1.0.0',
7
+ title: 'Learning Journey UI — Gamified',
8
+ description:
9
+ 'UI mini-app for gamified learning: flashcards, mastery ring, calendar.',
10
+ kind: 'ui',
11
+ visibility: 'public',
12
+ stability: 'experimental',
13
+ owners: ['@platform.core'],
14
+ tags: ['learning', 'ui', 'gamified'],
15
+ },
16
+ docs: {
17
+ rootDocId: 'docs.examples.learning-journey-ui-gamified',
18
+ },
19
+ entrypoints: {
20
+ packageName: '@contractspec/example.learning-journey-ui-gamified',
21
+ docs: './docs',
22
+ },
23
+ surfaces: {
24
+ templates: true,
25
+ sandbox: { enabled: true, modes: ['playground', 'markdown'] },
26
+ studio: { enabled: true, installable: true },
27
+ mcp: { enabled: true },
28
+ },
29
29
  });
30
30
 
31
31
  export default example;
package/src/index.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  // Main mini-app
2
- export { GamifiedMiniApp } from './GamifiedMiniApp';
3
-
4
- // Views
5
- export { Overview, Steps, Progress, Timeline } from './views';
6
2
 
7
3
  // Components
8
- export { FlashCard, MasteryRing, DayCalendar } from './components';
9
- export * from './learning-journey-ui-gamified.feature';
4
+ export { DayCalendar, FlashCard, MasteryRing } from './components';
10
5
  export { default as example } from './example';
6
+ export { GamifiedMiniApp } from './GamifiedMiniApp';
7
+ export * from './learning-journey-ui-gamified.feature';
8
+ // Views
9
+ export { Overview, Progress, Steps, Timeline } from './views';
11
10
  import './docs';
@@ -1,17 +1,17 @@
1
1
  import { defineFeature } from '@contractspec/lib.contracts-spec';
2
2
 
3
3
  export const LearningJourneyUiGamifiedFeature = defineFeature({
4
- meta: {
5
- key: 'learning-journey-ui-gamified',
6
- version: '1.0.0',
7
- title: 'Learning Journey UI: Gamified',
8
- description:
9
- 'Gamified learning UI with drills, quests, flash cards, and mastery rings',
10
- domain: 'learning-journey',
11
- owners: ['@examples'],
12
- tags: ['learning', 'ui', 'gamified', 'drills'],
13
- stability: 'experimental',
14
- },
4
+ meta: {
5
+ key: 'learning-journey-ui-gamified',
6
+ version: '1.0.0',
7
+ title: 'Learning Journey UI: Gamified',
8
+ description:
9
+ 'Gamified learning UI with drills, quests, flash cards, and mastery rings',
10
+ domain: 'learning-journey',
11
+ owners: ['@examples'],
12
+ tags: ['learning', 'ui', 'gamified', 'drills'],
13
+ stability: 'experimental',
14
+ },
15
15
 
16
- docs: ['docs.examples.learning-journey-ui-gamified'],
16
+ docs: ['docs.examples.learning-journey-ui-gamified'],
17
17
  });
@@ -1,164 +1,164 @@
1
1
  'use client';
2
2
 
3
+ import type { LearningViewProps } from '@contractspec/example.learning-journey-ui-shared';
4
+ import {
5
+ BadgeDisplay,
6
+ StreakCounter,
7
+ XpBar,
8
+ } from '@contractspec/example.learning-journey-ui-shared';
3
9
  import { Button } from '@contractspec/lib.design-system';
4
10
  import {
5
- Card,
6
- CardContent,
7
- CardHeader,
8
- CardTitle,
11
+ Card,
12
+ CardContent,
13
+ CardHeader,
14
+ CardTitle,
9
15
  } from '@contractspec/lib.ui-kit-web/ui/card';
10
- import {
11
- XpBar,
12
- StreakCounter,
13
- BadgeDisplay,
14
- } from '@contractspec/example.learning-journey-ui-shared';
15
- import type { LearningViewProps } from '@contractspec/example.learning-journey-ui-shared';
16
16
 
17
17
  interface GamifiedOverviewProps extends LearningViewProps {
18
- onStart?: () => void;
18
+ onStart?: () => void;
19
19
  }
20
20
 
21
21
  export function Overview({ track, progress, onStart }: GamifiedOverviewProps) {
22
- const totalXp =
23
- track.totalXp ??
24
- track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0) +
25
- (track.completionRewards?.xpBonus ?? 0);
22
+ const totalXp =
23
+ track.totalXp ??
24
+ track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0) +
25
+ (track.completionRewards?.xpBonus ?? 0);
26
26
 
27
- const completedSteps = progress.completedStepIds.length;
28
- const totalSteps = track.steps.length;
29
- const isComplete = completedSteps === totalSteps;
27
+ const completedSteps = progress.completedStepIds.length;
28
+ const totalSteps = track.steps.length;
29
+ const isComplete = completedSteps === totalSteps;
30
30
 
31
- return (
32
- <div className="space-y-6">
33
- {/* Hero Card */}
34
- <Card className="overflow-hidden bg-gradient-to-br from-violet-500/10 via-purple-500/10 to-fuchsia-500/10">
35
- <CardContent className="p-6">
36
- <div className="flex flex-col items-center gap-4 text-center md:flex-row md:text-left">
37
- <div className="flex h-20 w-20 items-center justify-center rounded-2xl bg-gradient-to-br from-violet-500 to-purple-600 text-4xl shadow-lg">
38
- {isComplete ? '🏆' : '🎯'}
39
- </div>
40
- <div className="flex-1">
41
- <h1 className="text-2xl font-bold">{track.name}</h1>
42
- <p className="text-muted-foreground mt-1">{track.description}</p>
43
- </div>
44
- <div className="flex items-center gap-3">
45
- <StreakCounter days={progress.streakDays} size="lg" />
46
- </div>
47
- </div>
48
- </CardContent>
49
- </Card>
31
+ return (
32
+ <div className="space-y-6">
33
+ {/* Hero Card */}
34
+ <Card className="overflow-hidden bg-gradient-to-br from-violet-500/10 via-purple-500/10 to-fuchsia-500/10">
35
+ <CardContent className="p-6">
36
+ <div className="flex flex-col items-center gap-4 text-center md:flex-row md:text-left">
37
+ <div className="flex h-20 w-20 items-center justify-center rounded-2xl bg-gradient-to-br from-violet-500 to-purple-600 text-4xl shadow-lg">
38
+ {isComplete ? '🏆' : '🎯'}
39
+ </div>
40
+ <div className="flex-1">
41
+ <h1 className="font-bold text-2xl">{track.name}</h1>
42
+ <p className="mt-1 text-muted-foreground">{track.description}</p>
43
+ </div>
44
+ <div className="flex items-center gap-3">
45
+ <StreakCounter days={progress.streakDays} size="lg" />
46
+ </div>
47
+ </div>
48
+ </CardContent>
49
+ </Card>
50
50
 
51
- {/* Stats Grid */}
52
- <div className="grid gap-4 md:grid-cols-3">
53
- <Card>
54
- <CardHeader className="pb-2">
55
- <CardTitle className="text-muted-foreground text-sm font-medium">
56
- XP Progress
57
- </CardTitle>
58
- </CardHeader>
59
- <CardContent>
60
- <div className="text-3xl font-bold text-violet-500">
61
- {progress.xpEarned.toLocaleString()}
62
- </div>
63
- <XpBar
64
- current={progress.xpEarned}
65
- max={totalXp}
66
- showLabel={false}
67
- size="sm"
68
- />
69
- </CardContent>
70
- </Card>
51
+ {/* Stats Grid */}
52
+ <div className="grid gap-4 md:grid-cols-3">
53
+ <Card>
54
+ <CardHeader className="pb-2">
55
+ <CardTitle className="font-medium text-muted-foreground text-sm">
56
+ XP Progress
57
+ </CardTitle>
58
+ </CardHeader>
59
+ <CardContent>
60
+ <div className="font-bold text-3xl text-violet-500">
61
+ {progress.xpEarned.toLocaleString()}
62
+ </div>
63
+ <XpBar
64
+ current={progress.xpEarned}
65
+ max={totalXp}
66
+ showLabel={false}
67
+ size="sm"
68
+ />
69
+ </CardContent>
70
+ </Card>
71
71
 
72
- <Card>
73
- <CardHeader className="pb-2">
74
- <CardTitle className="text-muted-foreground text-sm font-medium">
75
- Steps Completed
76
- </CardTitle>
77
- </CardHeader>
78
- <CardContent>
79
- <div className="text-3xl font-bold">
80
- {completedSteps}{' '}
81
- <span className="text-muted-foreground text-lg">
82
- / {totalSteps}
83
- </span>
84
- </div>
85
- <div className="bg-muted mt-2 h-2 w-full overflow-hidden rounded-full">
86
- <div
87
- className="h-full bg-green-500 transition-all duration-500"
88
- style={{ width: `${(completedSteps / totalSteps) * 100}%` }}
89
- />
90
- </div>
91
- </CardContent>
92
- </Card>
72
+ <Card>
73
+ <CardHeader className="pb-2">
74
+ <CardTitle className="font-medium text-muted-foreground text-sm">
75
+ Steps Completed
76
+ </CardTitle>
77
+ </CardHeader>
78
+ <CardContent>
79
+ <div className="font-bold text-3xl">
80
+ {completedSteps}{' '}
81
+ <span className="text-lg text-muted-foreground">
82
+ / {totalSteps}
83
+ </span>
84
+ </div>
85
+ <div className="mt-2 h-2 w-full overflow-hidden rounded-full bg-muted">
86
+ <div
87
+ className="h-full bg-green-500 transition-all duration-500"
88
+ style={{ width: `${(completedSteps / totalSteps) * 100}%` }}
89
+ />
90
+ </div>
91
+ </CardContent>
92
+ </Card>
93
93
 
94
- <Card>
95
- <CardHeader className="pb-2">
96
- <CardTitle className="text-muted-foreground text-sm font-medium">
97
- Badges Earned
98
- </CardTitle>
99
- </CardHeader>
100
- <CardContent>
101
- <BadgeDisplay badges={progress.badges} size="lg" />
102
- </CardContent>
103
- </Card>
104
- </div>
94
+ <Card>
95
+ <CardHeader className="pb-2">
96
+ <CardTitle className="font-medium text-muted-foreground text-sm">
97
+ Badges Earned
98
+ </CardTitle>
99
+ </CardHeader>
100
+ <CardContent>
101
+ <BadgeDisplay badges={progress.badges} size="lg" />
102
+ </CardContent>
103
+ </Card>
104
+ </div>
105
105
 
106
- {/* Next Step Preview */}
107
- {!isComplete && (
108
- <Card>
109
- <CardHeader>
110
- <CardTitle className="flex items-center gap-2">
111
- <span>🎯</span>
112
- <span>Next Challenge</span>
113
- </CardTitle>
114
- </CardHeader>
115
- <CardContent>
116
- {(() => {
117
- const nextStep = track.steps.find(
118
- (s) => !progress.completedStepIds.includes(s.id)
119
- );
120
- if (!nextStep) return null;
106
+ {/* Next Step Preview */}
107
+ {!isComplete && (
108
+ <Card>
109
+ <CardHeader>
110
+ <CardTitle className="flex items-center gap-2">
111
+ <span>🎯</span>
112
+ <span>Next Challenge</span>
113
+ </CardTitle>
114
+ </CardHeader>
115
+ <CardContent>
116
+ {(() => {
117
+ const nextStep = track.steps.find(
118
+ (s) => !progress.completedStepIds.includes(s.id)
119
+ );
120
+ if (!nextStep) return null;
121
121
 
122
- return (
123
- <div className="flex items-center justify-between gap-4">
124
- <div>
125
- <h3 className="font-semibold">{nextStep.title}</h3>
126
- <p className="text-muted-foreground text-sm">
127
- {nextStep.description}
128
- </p>
129
- </div>
130
- <div className="flex items-center gap-3">
131
- {nextStep.xpReward && (
132
- <span className="rounded-full bg-green-500/10 px-3 py-1 text-sm font-semibold text-green-500">
133
- +{nextStep.xpReward} XP
134
- </span>
135
- )}
136
- <Button onClick={onStart}>Start</Button>
137
- </div>
138
- </div>
139
- );
140
- })()}
141
- </CardContent>
142
- </Card>
143
- )}
122
+ return (
123
+ <div className="flex items-center justify-between gap-4">
124
+ <div>
125
+ <h3 className="font-semibold">{nextStep.title}</h3>
126
+ <p className="text-muted-foreground text-sm">
127
+ {nextStep.description}
128
+ </p>
129
+ </div>
130
+ <div className="flex items-center gap-3">
131
+ {nextStep.xpReward && (
132
+ <span className="rounded-full bg-green-500/10 px-3 py-1 font-semibold text-green-500 text-sm">
133
+ +{nextStep.xpReward} XP
134
+ </span>
135
+ )}
136
+ <Button onClick={onStart}>Start</Button>
137
+ </div>
138
+ </div>
139
+ );
140
+ })()}
141
+ </CardContent>
142
+ </Card>
143
+ )}
144
144
 
145
- {/* Completion Message */}
146
- {isComplete && (
147
- <Card className="border-green-500/50 bg-green-500/5">
148
- <CardContent className="flex items-center gap-4 p-6">
149
- <div className="text-4xl">🎉</div>
150
- <div>
151
- <h3 className="text-lg font-semibold text-green-500">
152
- Track Complete!
153
- </h3>
154
- <p className="text-muted-foreground">
155
- You've mastered all {totalSteps} challenges and earned{' '}
156
- {progress.xpEarned} XP.
157
- </p>
158
- </div>
159
- </CardContent>
160
- </Card>
161
- )}
162
- </div>
163
- );
145
+ {/* Completion Message */}
146
+ {isComplete && (
147
+ <Card className="border-green-500/50 bg-green-500/5">
148
+ <CardContent className="flex items-center gap-4 p-6">
149
+ <div className="text-4xl">🎉</div>
150
+ <div>
151
+ <h3 className="font-semibold text-green-500 text-lg">
152
+ Track Complete!
153
+ </h3>
154
+ <p className="text-muted-foreground">
155
+ You've mastered all {totalSteps} challenges and earned{' '}
156
+ {progress.xpEarned} XP.
157
+ </p>
158
+ </div>
159
+ </CardContent>
160
+ </Card>
161
+ )}
162
+ </div>
163
+ );
164
164
  }