@contractspec/example.learning-journey-ui-onboarding 1.57.0 → 1.58.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.
Files changed (87) hide show
  1. package/.turbo/turbo-build.log +58 -62
  2. package/.turbo/turbo-prebuild.log +1 -0
  3. package/CHANGELOG.md +19 -0
  4. package/dist/OnboardingMiniApp.d.ts +4 -14
  5. package/dist/OnboardingMiniApp.d.ts.map +1 -1
  6. package/dist/OnboardingMiniApp.js +991 -59
  7. package/dist/browser/OnboardingMiniApp.js +994 -0
  8. package/dist/browser/components/CodeSnippet.js +65 -0
  9. package/dist/browser/components/JourneyMap.js +59 -0
  10. package/dist/browser/components/StepChecklist.js +97 -0
  11. package/dist/browser/components/index.js +219 -0
  12. package/dist/browser/docs/index.js +22 -0
  13. package/dist/browser/docs/learning-journey-ui-onboarding.docblock.js +22 -0
  14. package/dist/browser/example.js +32 -0
  15. package/dist/browser/index.js +1116 -0
  16. package/dist/browser/views/Overview.js +240 -0
  17. package/dist/browser/views/Progress.js +275 -0
  18. package/dist/browser/views/Steps.js +192 -0
  19. package/dist/browser/views/Timeline.js +213 -0
  20. package/dist/browser/views/index.js +915 -0
  21. package/dist/components/CodeSnippet.d.ts +5 -13
  22. package/dist/components/CodeSnippet.d.ts.map +1 -1
  23. package/dist/components/CodeSnippet.js +63 -47
  24. package/dist/components/JourneyMap.d.ts +6 -14
  25. package/dist/components/JourneyMap.d.ts.map +1 -1
  26. package/dist/components/JourneyMap.js +57 -46
  27. package/dist/components/StepChecklist.d.ts +10 -22
  28. package/dist/components/StepChecklist.d.ts.map +1 -1
  29. package/dist/components/StepChecklist.js +95 -77
  30. package/dist/components/index.d.ts +4 -4
  31. package/dist/components/index.d.ts.map +1 -0
  32. package/dist/components/index.js +219 -4
  33. package/dist/docs/index.d.ts +2 -1
  34. package/dist/docs/index.d.ts.map +1 -0
  35. package/dist/docs/index.js +23 -1
  36. package/dist/docs/learning-journey-ui-onboarding.docblock.d.ts +2 -1
  37. package/dist/docs/learning-journey-ui-onboarding.docblock.d.ts.map +1 -0
  38. package/dist/docs/learning-journey-ui-onboarding.docblock.js +21 -18
  39. package/dist/example.d.ts +2 -6
  40. package/dist/example.d.ts.map +1 -1
  41. package/dist/example.js +31 -39
  42. package/dist/index.d.ts +6 -12
  43. package/dist/index.d.ts.map +1 -0
  44. package/dist/index.js +1117 -14
  45. package/dist/node/OnboardingMiniApp.js +994 -0
  46. package/dist/node/components/CodeSnippet.js +65 -0
  47. package/dist/node/components/JourneyMap.js +59 -0
  48. package/dist/node/components/StepChecklist.js +97 -0
  49. package/dist/node/components/index.js +219 -0
  50. package/dist/node/docs/index.js +22 -0
  51. package/dist/node/docs/learning-journey-ui-onboarding.docblock.js +22 -0
  52. package/dist/node/example.js +32 -0
  53. package/dist/node/index.js +1116 -0
  54. package/dist/node/views/Overview.js +240 -0
  55. package/dist/node/views/Progress.js +275 -0
  56. package/dist/node/views/Steps.js +192 -0
  57. package/dist/node/views/Timeline.js +213 -0
  58. package/dist/node/views/index.js +915 -0
  59. package/dist/views/Overview.d.ts +4 -12
  60. package/dist/views/Overview.d.ts.map +1 -1
  61. package/dist/views/Overview.js +238 -177
  62. package/dist/views/Progress.d.ts +3 -10
  63. package/dist/views/Progress.d.ts.map +1 -1
  64. package/dist/views/Progress.js +273 -158
  65. package/dist/views/Steps.d.ts +2 -11
  66. package/dist/views/Steps.d.ts.map +1 -1
  67. package/dist/views/Steps.js +188 -87
  68. package/dist/views/Timeline.d.ts +2 -10
  69. package/dist/views/Timeline.d.ts.map +1 -1
  70. package/dist/views/Timeline.js +211 -95
  71. package/dist/views/index.d.ts +5 -5
  72. package/dist/views/index.d.ts.map +1 -0
  73. package/dist/views/index.js +915 -5
  74. package/package.json +155 -39
  75. package/tsdown.config.js +1 -2
  76. package/.turbo/turbo-build$colon$bundle.log +0 -59
  77. package/dist/OnboardingMiniApp.js.map +0 -1
  78. package/dist/components/CodeSnippet.js.map +0 -1
  79. package/dist/components/JourneyMap.js.map +0 -1
  80. package/dist/components/StepChecklist.js.map +0 -1
  81. package/dist/docs/learning-journey-ui-onboarding.docblock.js.map +0 -1
  82. package/dist/example.js.map +0 -1
  83. package/dist/views/Overview.js.map +0 -1
  84. package/dist/views/Progress.js.map +0 -1
  85. package/dist/views/Steps.js.map +0 -1
  86. package/dist/views/Timeline.js.map +0 -1
  87. package/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,1116 @@
1
+ // src/views/Overview.tsx
2
+ import { Button } from "@contractspec/lib.design-system";
3
+ import {
4
+ Card,
5
+ CardContent,
6
+ CardHeader,
7
+ CardTitle
8
+ } from "@contractspec/lib.ui-kit-web/ui/card";
9
+ import { Progress } from "@contractspec/lib.ui-kit-web/ui/progress";
10
+ import { XpBar } from "@contractspec/example.learning-journey-ui-shared";
11
+ import { jsxDEV } from "react/jsx-dev-runtime";
12
+ "use client";
13
+ function Overview({
14
+ track,
15
+ progress,
16
+ onStart
17
+ }) {
18
+ const totalSteps = track.steps.length;
19
+ const completedSteps = progress.completedStepIds.length;
20
+ const percentComplete = totalSteps > 0 ? completedSteps / totalSteps * 100 : 0;
21
+ const isComplete = completedSteps === totalSteps;
22
+ const remainingSteps = totalSteps - completedSteps;
23
+ const estimatedMinutes = remainingSteps * 5;
24
+ const totalXp = track.totalXp ?? track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0) + (track.completionRewards?.xpBonus ?? 0);
25
+ return /* @__PURE__ */ jsxDEV("div", {
26
+ className: "space-y-6",
27
+ children: [
28
+ /* @__PURE__ */ jsxDEV(Card, {
29
+ className: "overflow-hidden bg-gradient-to-r from-blue-500/10 via-violet-500/10 to-purple-500/10",
30
+ children: /* @__PURE__ */ jsxDEV(CardContent, {
31
+ className: "p-8",
32
+ children: /* @__PURE__ */ jsxDEV("div", {
33
+ className: "flex flex-col items-center gap-6 text-center md:flex-row md:text-left",
34
+ children: [
35
+ /* @__PURE__ */ jsxDEV("div", {
36
+ className: "flex h-20 w-20 items-center justify-center rounded-2xl bg-gradient-to-br from-blue-500 to-violet-600 text-4xl shadow-lg",
37
+ children: isComplete ? "\uD83C\uDF89" : "\uD83D\uDE80"
38
+ }, undefined, false, undefined, this),
39
+ /* @__PURE__ */ jsxDEV("div", {
40
+ className: "flex-1",
41
+ children: [
42
+ /* @__PURE__ */ jsxDEV("h1", {
43
+ className: "text-2xl font-bold",
44
+ children: track.name
45
+ }, undefined, false, undefined, this),
46
+ /* @__PURE__ */ jsxDEV("p", {
47
+ className: "text-muted-foreground mt-1 max-w-2xl",
48
+ children: track.description
49
+ }, undefined, false, undefined, this),
50
+ !isComplete && /* @__PURE__ */ jsxDEV("p", {
51
+ className: "text-muted-foreground mt-3 text-sm",
52
+ children: [
53
+ "⏱️ Estimated time:",
54
+ " ",
55
+ estimatedMinutes > 0 ? `~${estimatedMinutes} minutes` : "Less than a minute"
56
+ ]
57
+ }, undefined, true, undefined, this)
58
+ ]
59
+ }, undefined, true, undefined, this),
60
+ !isComplete && /* @__PURE__ */ jsxDEV(Button, {
61
+ size: "lg",
62
+ onClick: onStart,
63
+ children: completedSteps > 0 ? "Continue" : "Get Started"
64
+ }, undefined, false, undefined, this)
65
+ ]
66
+ }, undefined, true, undefined, this)
67
+ }, undefined, false, undefined, this)
68
+ }, undefined, false, undefined, this),
69
+ /* @__PURE__ */ jsxDEV("div", {
70
+ className: "grid gap-4 md:grid-cols-3",
71
+ children: [
72
+ /* @__PURE__ */ jsxDEV(Card, {
73
+ children: [
74
+ /* @__PURE__ */ jsxDEV(CardHeader, {
75
+ className: "pb-2",
76
+ children: /* @__PURE__ */ jsxDEV(CardTitle, {
77
+ className: "text-muted-foreground text-sm font-medium",
78
+ children: "Progress"
79
+ }, undefined, false, undefined, this)
80
+ }, undefined, false, undefined, this),
81
+ /* @__PURE__ */ jsxDEV(CardContent, {
82
+ children: [
83
+ /* @__PURE__ */ jsxDEV("div", {
84
+ className: "text-3xl font-bold",
85
+ children: [
86
+ Math.round(percentComplete),
87
+ "%"
88
+ ]
89
+ }, undefined, true, undefined, this),
90
+ /* @__PURE__ */ jsxDEV(Progress, {
91
+ value: percentComplete,
92
+ className: "mt-2 h-2"
93
+ }, undefined, false, undefined, this),
94
+ /* @__PURE__ */ jsxDEV("p", {
95
+ className: "text-muted-foreground mt-2 text-sm",
96
+ children: [
97
+ completedSteps,
98
+ " of ",
99
+ totalSteps,
100
+ " steps completed"
101
+ ]
102
+ }, undefined, true, undefined, this)
103
+ ]
104
+ }, undefined, true, undefined, this)
105
+ ]
106
+ }, undefined, true, undefined, this),
107
+ /* @__PURE__ */ jsxDEV(Card, {
108
+ children: [
109
+ /* @__PURE__ */ jsxDEV(CardHeader, {
110
+ className: "pb-2",
111
+ children: /* @__PURE__ */ jsxDEV(CardTitle, {
112
+ className: "text-muted-foreground text-sm font-medium",
113
+ children: "XP Earned"
114
+ }, undefined, false, undefined, this)
115
+ }, undefined, false, undefined, this),
116
+ /* @__PURE__ */ jsxDEV(CardContent, {
117
+ children: [
118
+ /* @__PURE__ */ jsxDEV("div", {
119
+ className: "text-3xl font-bold text-blue-500",
120
+ children: progress.xpEarned
121
+ }, undefined, false, undefined, this),
122
+ /* @__PURE__ */ jsxDEV(XpBar, {
123
+ current: progress.xpEarned,
124
+ max: totalXp,
125
+ showLabel: false,
126
+ size: "sm"
127
+ }, undefined, false, undefined, this)
128
+ ]
129
+ }, undefined, true, undefined, this)
130
+ ]
131
+ }, undefined, true, undefined, this),
132
+ /* @__PURE__ */ jsxDEV(Card, {
133
+ children: [
134
+ /* @__PURE__ */ jsxDEV(CardHeader, {
135
+ className: "pb-2",
136
+ children: /* @__PURE__ */ jsxDEV(CardTitle, {
137
+ className: "text-muted-foreground text-sm font-medium",
138
+ children: "Time Remaining"
139
+ }, undefined, false, undefined, this)
140
+ }, undefined, false, undefined, this),
141
+ /* @__PURE__ */ jsxDEV(CardContent, {
142
+ children: [
143
+ /* @__PURE__ */ jsxDEV("div", {
144
+ className: "text-3xl font-bold",
145
+ children: isComplete ? "✓" : `~${estimatedMinutes}m`
146
+ }, undefined, false, undefined, this),
147
+ /* @__PURE__ */ jsxDEV("p", {
148
+ className: "text-muted-foreground mt-2 text-sm",
149
+ children: isComplete ? "All done!" : `${remainingSteps} steps to go`
150
+ }, undefined, false, undefined, this)
151
+ ]
152
+ }, undefined, true, undefined, this)
153
+ ]
154
+ }, undefined, true, undefined, this)
155
+ ]
156
+ }, undefined, true, undefined, this),
157
+ /* @__PURE__ */ jsxDEV(Card, {
158
+ children: [
159
+ /* @__PURE__ */ jsxDEV(CardHeader, {
160
+ children: /* @__PURE__ */ jsxDEV(CardTitle, {
161
+ className: "flex items-center gap-2",
162
+ children: [
163
+ /* @__PURE__ */ jsxDEV("span", {
164
+ children: "\uD83D\uDCCB"
165
+ }, undefined, false, undefined, this),
166
+ /* @__PURE__ */ jsxDEV("span", {
167
+ children: "Your Journey"
168
+ }, undefined, false, undefined, this)
169
+ ]
170
+ }, undefined, true, undefined, this)
171
+ }, undefined, false, undefined, this),
172
+ /* @__PURE__ */ jsxDEV(CardContent, {
173
+ children: /* @__PURE__ */ jsxDEV("div", {
174
+ className: "space-y-3",
175
+ children: track.steps.map((step, index) => {
176
+ const isStepCompleted = progress.completedStepIds.includes(step.id);
177
+ const isCurrent = !isStepCompleted && track.steps.slice(0, index).every((s) => progress.completedStepIds.includes(s.id));
178
+ return /* @__PURE__ */ jsxDEV("div", {
179
+ className: "flex items-center gap-4 rounded-lg border p-3",
180
+ children: [
181
+ /* @__PURE__ */ jsxDEV("div", {
182
+ className: `flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-sm font-semibold ${isStepCompleted ? "bg-green-500 text-white" : isCurrent ? "bg-blue-500 text-white" : "bg-muted text-muted-foreground"}`,
183
+ children: isStepCompleted ? "✓" : index + 1
184
+ }, undefined, false, undefined, this),
185
+ /* @__PURE__ */ jsxDEV("div", {
186
+ className: "min-w-0 flex-1",
187
+ children: /* @__PURE__ */ jsxDEV("p", {
188
+ className: `font-medium ${isStepCompleted ? "text-green-500" : isCurrent ? "text-foreground" : "text-muted-foreground"}`,
189
+ children: step.title
190
+ }, undefined, false, undefined, this)
191
+ }, undefined, false, undefined, this),
192
+ step.xpReward && /* @__PURE__ */ jsxDEV("span", {
193
+ className: "text-muted-foreground text-sm",
194
+ children: [
195
+ "+",
196
+ step.xpReward,
197
+ " XP"
198
+ ]
199
+ }, undefined, true, undefined, this)
200
+ ]
201
+ }, step.id, true, undefined, this);
202
+ })
203
+ }, undefined, false, undefined, this)
204
+ }, undefined, false, undefined, this)
205
+ ]
206
+ }, undefined, true, undefined, this),
207
+ isComplete && /* @__PURE__ */ jsxDEV(Card, {
208
+ className: "border-green-500/50 bg-green-500/5",
209
+ children: /* @__PURE__ */ jsxDEV(CardContent, {
210
+ className: "flex items-center gap-4 p-6",
211
+ children: [
212
+ /* @__PURE__ */ jsxDEV("div", {
213
+ className: "text-4xl",
214
+ children: "\uD83C\uDF89"
215
+ }, undefined, false, undefined, this),
216
+ /* @__PURE__ */ jsxDEV("div", {
217
+ children: [
218
+ /* @__PURE__ */ jsxDEV("h3", {
219
+ className: "text-lg font-semibold text-green-500",
220
+ children: "Onboarding Complete!"
221
+ }, undefined, false, undefined, this),
222
+ /* @__PURE__ */ jsxDEV("p", {
223
+ className: "text-muted-foreground",
224
+ children: [
225
+ "You've completed all ",
226
+ totalSteps,
227
+ " steps. Welcome aboard!"
228
+ ]
229
+ }, undefined, true, undefined, this)
230
+ ]
231
+ }, undefined, true, undefined, this)
232
+ ]
233
+ }, undefined, true, undefined, this)
234
+ }, undefined, false, undefined, this)
235
+ ]
236
+ }, undefined, true, undefined, this);
237
+ }
238
+
239
+ // src/components/StepChecklist.tsx
240
+ import { Button as Button2 } from "@contractspec/lib.design-system";
241
+ import { cn } from "@contractspec/lib.ui-kit-core";
242
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
243
+ "use client";
244
+ function StepChecklist({
245
+ step,
246
+ stepNumber,
247
+ isCompleted,
248
+ isCurrent,
249
+ isExpanded,
250
+ onToggle,
251
+ onComplete
252
+ }) {
253
+ return /* @__PURE__ */ jsxDEV2("div", {
254
+ className: cn("rounded-xl border transition-all", isCompleted && "border-green-500/50 bg-green-500/5", isCurrent && !isCompleted && "border-violet-500 bg-violet-500/5", !isCompleted && !isCurrent && "border-border"),
255
+ children: [
256
+ /* @__PURE__ */ jsxDEV2("button", {
257
+ type: "button",
258
+ className: "flex w-full items-center gap-4 p-4 text-left",
259
+ onClick: onToggle,
260
+ children: [
261
+ /* @__PURE__ */ jsxDEV2("div", {
262
+ className: cn("flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-2 text-sm font-semibold transition-colors", isCompleted && "border-green-500 bg-green-500 text-white", isCurrent && !isCompleted && "border-violet-500 text-violet-500", !isCompleted && !isCurrent && "border-muted-foreground text-muted-foreground"),
263
+ children: isCompleted ? "✓" : stepNumber
264
+ }, undefined, false, undefined, this),
265
+ /* @__PURE__ */ jsxDEV2("div", {
266
+ className: "min-w-0 flex-1",
267
+ children: [
268
+ /* @__PURE__ */ jsxDEV2("h4", {
269
+ className: cn("font-semibold", isCompleted && "text-green-500", isCurrent && !isCompleted && "text-foreground", !isCompleted && !isCurrent && "text-muted-foreground"),
270
+ children: step.title
271
+ }, undefined, false, undefined, this),
272
+ !isExpanded && step.description && /* @__PURE__ */ jsxDEV2("p", {
273
+ className: "text-muted-foreground truncate text-sm",
274
+ children: step.description
275
+ }, undefined, false, undefined, this)
276
+ ]
277
+ }, undefined, true, undefined, this),
278
+ step.xpReward && /* @__PURE__ */ jsxDEV2("span", {
279
+ className: cn("shrink-0 rounded-full px-2 py-1 text-xs font-semibold", isCompleted ? "bg-green-500/10 text-green-500" : "bg-muted text-muted-foreground"),
280
+ children: [
281
+ "+",
282
+ step.xpReward,
283
+ " XP"
284
+ ]
285
+ }, undefined, true, undefined, this),
286
+ /* @__PURE__ */ jsxDEV2("span", {
287
+ className: cn("shrink-0 transition-transform", isExpanded && "rotate-180"),
288
+ children: "▼"
289
+ }, undefined, false, undefined, this)
290
+ ]
291
+ }, undefined, true, undefined, this),
292
+ isExpanded && /* @__PURE__ */ jsxDEV2("div", {
293
+ className: "border-t px-4 py-4",
294
+ children: [
295
+ step.description && /* @__PURE__ */ jsxDEV2("p", {
296
+ className: "text-muted-foreground mb-4",
297
+ children: step.description
298
+ }, undefined, false, undefined, this),
299
+ step.instructions && /* @__PURE__ */ jsxDEV2("div", {
300
+ className: "bg-muted mb-4 rounded-lg p-4",
301
+ children: [
302
+ /* @__PURE__ */ jsxDEV2("p", {
303
+ className: "mb-2 text-sm font-medium",
304
+ children: "Instructions:"
305
+ }, undefined, false, undefined, this),
306
+ /* @__PURE__ */ jsxDEV2("p", {
307
+ className: "text-muted-foreground text-sm",
308
+ children: step.instructions
309
+ }, undefined, false, undefined, this)
310
+ ]
311
+ }, undefined, true, undefined, this),
312
+ /* @__PURE__ */ jsxDEV2("div", {
313
+ className: "flex flex-wrap gap-2",
314
+ children: [
315
+ step.actionUrl && /* @__PURE__ */ jsxDEV2(Button2, {
316
+ variant: "outline",
317
+ size: "sm",
318
+ onClick: () => window.open(step.actionUrl, "_blank"),
319
+ children: step.actionLabel ?? "Try it"
320
+ }, undefined, false, undefined, this),
321
+ !isCompleted && /* @__PURE__ */ jsxDEV2(Button2, {
322
+ size: "sm",
323
+ onClick: onComplete,
324
+ children: "Mark as Complete"
325
+ }, undefined, false, undefined, this)
326
+ ]
327
+ }, undefined, true, undefined, this)
328
+ ]
329
+ }, undefined, true, undefined, this)
330
+ ]
331
+ }, undefined, true, undefined, this);
332
+ }
333
+
334
+ // src/views/Steps.tsx
335
+ import { useState } from "react";
336
+ import { Progress as Progress2 } from "@contractspec/lib.ui-kit-web/ui/progress";
337
+ import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
338
+ "use client";
339
+ function Steps({ track, progress, onStepComplete }) {
340
+ const [expandedStepId, setExpandedStepId] = useState(() => {
341
+ const firstIncomplete = track.steps.find((s) => !progress.completedStepIds.includes(s.id));
342
+ return firstIncomplete?.id ?? null;
343
+ });
344
+ const completedSteps = progress.completedStepIds.length;
345
+ const totalSteps = track.steps.length;
346
+ const percentComplete = totalSteps > 0 ? completedSteps / totalSteps * 100 : 0;
347
+ const currentStepIndex = track.steps.findIndex((s) => !progress.completedStepIds.includes(s.id));
348
+ return /* @__PURE__ */ jsxDEV3("div", {
349
+ className: "space-y-6",
350
+ children: [
351
+ /* @__PURE__ */ jsxDEV3("div", {
352
+ className: "space-y-2",
353
+ children: [
354
+ /* @__PURE__ */ jsxDEV3("div", {
355
+ className: "flex items-center justify-between",
356
+ children: [
357
+ /* @__PURE__ */ jsxDEV3("h2", {
358
+ className: "text-xl font-bold",
359
+ children: "Complete Each Step"
360
+ }, undefined, false, undefined, this),
361
+ /* @__PURE__ */ jsxDEV3("span", {
362
+ className: "text-muted-foreground text-sm",
363
+ children: [
364
+ completedSteps,
365
+ " / ",
366
+ totalSteps,
367
+ " completed"
368
+ ]
369
+ }, undefined, true, undefined, this)
370
+ ]
371
+ }, undefined, true, undefined, this),
372
+ /* @__PURE__ */ jsxDEV3(Progress2, {
373
+ value: percentComplete,
374
+ className: "h-2"
375
+ }, undefined, false, undefined, this)
376
+ ]
377
+ }, undefined, true, undefined, this),
378
+ /* @__PURE__ */ jsxDEV3("div", {
379
+ className: "space-y-3",
380
+ children: track.steps.map((step, index) => {
381
+ const isCompleted = progress.completedStepIds.includes(step.id);
382
+ const isCurrent = index === currentStepIndex;
383
+ return /* @__PURE__ */ jsxDEV3(StepChecklist, {
384
+ step,
385
+ stepNumber: index + 1,
386
+ isCompleted,
387
+ isCurrent,
388
+ isExpanded: expandedStepId === step.id,
389
+ onToggle: () => setExpandedStepId(expandedStepId === step.id ? null : step.id),
390
+ onComplete: () => {
391
+ onStepComplete?.(step.id);
392
+ const nextStep = track.steps[index + 1];
393
+ if (nextStep && !progress.completedStepIds.includes(nextStep.id)) {
394
+ setExpandedStepId(nextStep.id);
395
+ }
396
+ }
397
+ }, step.id, false, undefined, this);
398
+ })
399
+ }, undefined, false, undefined, this),
400
+ track.completionRewards && percentComplete < 100 && /* @__PURE__ */ jsxDEV3("div", {
401
+ className: "rounded-lg border border-blue-500/30 bg-blue-500/5 p-4",
402
+ children: /* @__PURE__ */ jsxDEV3("p", {
403
+ className: "text-sm",
404
+ children: [
405
+ "\uD83C\uDF81 Complete all steps to unlock:",
406
+ track.completionRewards.xpBonus && /* @__PURE__ */ jsxDEV3("span", {
407
+ className: "ml-2 font-semibold text-blue-500",
408
+ children: [
409
+ "+",
410
+ track.completionRewards.xpBonus,
411
+ " XP bonus"
412
+ ]
413
+ }, undefined, true, undefined, this),
414
+ track.completionRewards.badgeKey && /* @__PURE__ */ jsxDEV3("span", {
415
+ className: "ml-2 font-semibold text-amber-500",
416
+ children: [
417
+ '+ "',
418
+ track.completionRewards.badgeKey,
419
+ '" badge'
420
+ ]
421
+ }, undefined, true, undefined, this)
422
+ ]
423
+ }, undefined, true, undefined, this)
424
+ }, undefined, false, undefined, this)
425
+ ]
426
+ }, undefined, true, undefined, this);
427
+ }
428
+
429
+ // src/views/Progress.tsx
430
+ import {
431
+ Card as Card2,
432
+ CardContent as CardContent2,
433
+ CardHeader as CardHeader2,
434
+ CardTitle as CardTitle2
435
+ } from "@contractspec/lib.ui-kit-web/ui/card";
436
+ import { Progress as Progress3 } from "@contractspec/lib.ui-kit-web/ui/progress";
437
+ import {
438
+ XpBar as XpBar2,
439
+ BadgeDisplay
440
+ } from "@contractspec/example.learning-journey-ui-shared";
441
+ import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
442
+ "use client";
443
+ function ProgressView({ track, progress }) {
444
+ const totalSteps = track.steps.length;
445
+ const completedSteps = progress.completedStepIds.length;
446
+ const percentComplete = totalSteps > 0 ? completedSteps / totalSteps * 100 : 0;
447
+ const totalXp = track.totalXp ?? track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0) + (track.completionRewards?.xpBonus ?? 0);
448
+ const remainingSteps = totalSteps - completedSteps;
449
+ const estimatedMinutes = remainingSteps * 5;
450
+ return /* @__PURE__ */ jsxDEV4("div", {
451
+ className: "space-y-6",
452
+ children: [
453
+ /* @__PURE__ */ jsxDEV4(Card2, {
454
+ children: [
455
+ /* @__PURE__ */ jsxDEV4(CardHeader2, {
456
+ children: /* @__PURE__ */ jsxDEV4(CardTitle2, {
457
+ className: "flex items-center gap-2",
458
+ children: [
459
+ /* @__PURE__ */ jsxDEV4("span", {
460
+ children: "\uD83D\uDCC8"
461
+ }, undefined, false, undefined, this),
462
+ /* @__PURE__ */ jsxDEV4("span", {
463
+ children: "Your Progress"
464
+ }, undefined, false, undefined, this)
465
+ ]
466
+ }, undefined, true, undefined, this)
467
+ }, undefined, false, undefined, this),
468
+ /* @__PURE__ */ jsxDEV4(CardContent2, {
469
+ className: "space-y-6",
470
+ children: [
471
+ /* @__PURE__ */ jsxDEV4("div", {
472
+ className: "flex items-center justify-center",
473
+ children: /* @__PURE__ */ jsxDEV4("div", {
474
+ className: "relative flex h-40 w-40 items-center justify-center",
475
+ children: [
476
+ /* @__PURE__ */ jsxDEV4("svg", {
477
+ className: "absolute h-full w-full -rotate-90",
478
+ viewBox: "0 0 100 100",
479
+ children: [
480
+ /* @__PURE__ */ jsxDEV4("circle", {
481
+ cx: "50",
482
+ cy: "50",
483
+ r: "45",
484
+ fill: "none",
485
+ strokeWidth: "8",
486
+ className: "stroke-muted"
487
+ }, undefined, false, undefined, this),
488
+ /* @__PURE__ */ jsxDEV4("circle", {
489
+ cx: "50",
490
+ cy: "50",
491
+ r: "45",
492
+ fill: "none",
493
+ strokeWidth: "8",
494
+ strokeLinecap: "round",
495
+ strokeDasharray: `${percentComplete * 2.83} 283`,
496
+ className: "stroke-blue-500 transition-all duration-500"
497
+ }, undefined, false, undefined, this)
498
+ ]
499
+ }, undefined, true, undefined, this),
500
+ /* @__PURE__ */ jsxDEV4("div", {
501
+ className: "text-center",
502
+ children: [
503
+ /* @__PURE__ */ jsxDEV4("div", {
504
+ className: "text-3xl font-bold",
505
+ children: [
506
+ Math.round(percentComplete),
507
+ "%"
508
+ ]
509
+ }, undefined, true, undefined, this),
510
+ /* @__PURE__ */ jsxDEV4("div", {
511
+ className: "text-muted-foreground text-sm",
512
+ children: "Complete"
513
+ }, undefined, false, undefined, this)
514
+ ]
515
+ }, undefined, true, undefined, this)
516
+ ]
517
+ }, undefined, true, undefined, this)
518
+ }, undefined, false, undefined, this),
519
+ /* @__PURE__ */ jsxDEV4("div", {
520
+ className: "grid grid-cols-3 gap-4 text-center",
521
+ children: [
522
+ /* @__PURE__ */ jsxDEV4("div", {
523
+ children: [
524
+ /* @__PURE__ */ jsxDEV4("div", {
525
+ className: "text-2xl font-bold text-green-500",
526
+ children: completedSteps
527
+ }, undefined, false, undefined, this),
528
+ /* @__PURE__ */ jsxDEV4("div", {
529
+ className: "text-muted-foreground text-sm",
530
+ children: "Completed"
531
+ }, undefined, false, undefined, this)
532
+ ]
533
+ }, undefined, true, undefined, this),
534
+ /* @__PURE__ */ jsxDEV4("div", {
535
+ children: [
536
+ /* @__PURE__ */ jsxDEV4("div", {
537
+ className: "text-2xl font-bold text-orange-500",
538
+ children: remainingSteps
539
+ }, undefined, false, undefined, this),
540
+ /* @__PURE__ */ jsxDEV4("div", {
541
+ className: "text-muted-foreground text-sm",
542
+ children: "Remaining"
543
+ }, undefined, false, undefined, this)
544
+ ]
545
+ }, undefined, true, undefined, this),
546
+ /* @__PURE__ */ jsxDEV4("div", {
547
+ children: [
548
+ /* @__PURE__ */ jsxDEV4("div", {
549
+ className: "text-2xl font-bold",
550
+ children: [
551
+ estimatedMinutes,
552
+ "m"
553
+ ]
554
+ }, undefined, true, undefined, this),
555
+ /* @__PURE__ */ jsxDEV4("div", {
556
+ className: "text-muted-foreground text-sm",
557
+ children: "Est. Time"
558
+ }, undefined, false, undefined, this)
559
+ ]
560
+ }, undefined, true, undefined, this)
561
+ ]
562
+ }, undefined, true, undefined, this)
563
+ ]
564
+ }, undefined, true, undefined, this)
565
+ ]
566
+ }, undefined, true, undefined, this),
567
+ /* @__PURE__ */ jsxDEV4(Card2, {
568
+ children: [
569
+ /* @__PURE__ */ jsxDEV4(CardHeader2, {
570
+ children: /* @__PURE__ */ jsxDEV4(CardTitle2, {
571
+ className: "flex items-center gap-2",
572
+ children: [
573
+ /* @__PURE__ */ jsxDEV4("span", {
574
+ children: "⚡"
575
+ }, undefined, false, undefined, this),
576
+ /* @__PURE__ */ jsxDEV4("span", {
577
+ children: "Experience Points"
578
+ }, undefined, false, undefined, this)
579
+ ]
580
+ }, undefined, true, undefined, this)
581
+ }, undefined, false, undefined, this),
582
+ /* @__PURE__ */ jsxDEV4(CardContent2, {
583
+ className: "space-y-4",
584
+ children: [
585
+ /* @__PURE__ */ jsxDEV4("div", {
586
+ className: "flex items-baseline gap-2",
587
+ children: [
588
+ /* @__PURE__ */ jsxDEV4("span", {
589
+ className: "text-3xl font-bold text-blue-500",
590
+ children: progress.xpEarned
591
+ }, undefined, false, undefined, this),
592
+ /* @__PURE__ */ jsxDEV4("span", {
593
+ className: "text-muted-foreground",
594
+ children: [
595
+ "/ ",
596
+ totalXp,
597
+ " XP"
598
+ ]
599
+ }, undefined, true, undefined, this)
600
+ ]
601
+ }, undefined, true, undefined, this),
602
+ /* @__PURE__ */ jsxDEV4(XpBar2, {
603
+ current: progress.xpEarned,
604
+ max: totalXp,
605
+ showLabel: false,
606
+ size: "lg"
607
+ }, undefined, false, undefined, this)
608
+ ]
609
+ }, undefined, true, undefined, this)
610
+ ]
611
+ }, undefined, true, undefined, this),
612
+ /* @__PURE__ */ jsxDEV4(Card2, {
613
+ children: [
614
+ /* @__PURE__ */ jsxDEV4(CardHeader2, {
615
+ children: /* @__PURE__ */ jsxDEV4(CardTitle2, {
616
+ className: "flex items-center gap-2",
617
+ children: [
618
+ /* @__PURE__ */ jsxDEV4("span", {
619
+ children: "\uD83C\uDFC5"
620
+ }, undefined, false, undefined, this),
621
+ /* @__PURE__ */ jsxDEV4("span", {
622
+ children: "Achievements"
623
+ }, undefined, false, undefined, this)
624
+ ]
625
+ }, undefined, true, undefined, this)
626
+ }, undefined, false, undefined, this),
627
+ /* @__PURE__ */ jsxDEV4(CardContent2, {
628
+ children: [
629
+ /* @__PURE__ */ jsxDEV4(BadgeDisplay, {
630
+ badges: progress.badges,
631
+ size: "lg"
632
+ }, undefined, false, undefined, this),
633
+ progress.badges.length === 0 && track.completionRewards?.badgeKey && /* @__PURE__ */ jsxDEV4("p", {
634
+ className: "text-muted-foreground text-sm",
635
+ children: [
636
+ 'Complete all steps to earn the "',
637
+ track.completionRewards.badgeKey,
638
+ '" badge!'
639
+ ]
640
+ }, undefined, true, undefined, this)
641
+ ]
642
+ }, undefined, true, undefined, this)
643
+ ]
644
+ }, undefined, true, undefined, this),
645
+ /* @__PURE__ */ jsxDEV4(Card2, {
646
+ children: [
647
+ /* @__PURE__ */ jsxDEV4(CardHeader2, {
648
+ children: /* @__PURE__ */ jsxDEV4(CardTitle2, {
649
+ className: "flex items-center gap-2",
650
+ children: [
651
+ /* @__PURE__ */ jsxDEV4("span", {
652
+ children: "\uD83D\uDCCB"
653
+ }, undefined, false, undefined, this),
654
+ /* @__PURE__ */ jsxDEV4("span", {
655
+ children: "Step Details"
656
+ }, undefined, false, undefined, this)
657
+ ]
658
+ }, undefined, true, undefined, this)
659
+ }, undefined, false, undefined, this),
660
+ /* @__PURE__ */ jsxDEV4(CardContent2, {
661
+ children: /* @__PURE__ */ jsxDEV4("div", {
662
+ className: "space-y-3",
663
+ children: track.steps.map((step, index) => {
664
+ const isCompleted = progress.completedStepIds.includes(step.id);
665
+ const stepProgress = isCompleted ? 100 : 0;
666
+ return /* @__PURE__ */ jsxDEV4("div", {
667
+ className: "space-y-1",
668
+ children: [
669
+ /* @__PURE__ */ jsxDEV4("div", {
670
+ className: "flex items-center justify-between text-sm",
671
+ children: [
672
+ /* @__PURE__ */ jsxDEV4("span", {
673
+ className: isCompleted ? "text-green-500" : "text-foreground",
674
+ children: [
675
+ index + 1,
676
+ ". ",
677
+ step.title
678
+ ]
679
+ }, undefined, true, undefined, this),
680
+ /* @__PURE__ */ jsxDEV4("span", {
681
+ className: isCompleted ? "text-green-500" : "text-muted-foreground",
682
+ children: isCompleted ? "✓" : "Pending"
683
+ }, undefined, false, undefined, this)
684
+ ]
685
+ }, undefined, true, undefined, this),
686
+ /* @__PURE__ */ jsxDEV4(Progress3, {
687
+ value: stepProgress,
688
+ className: "h-1"
689
+ }, undefined, false, undefined, this)
690
+ ]
691
+ }, step.id, true, undefined, this);
692
+ })
693
+ }, undefined, false, undefined, this)
694
+ }, undefined, false, undefined, this)
695
+ ]
696
+ }, undefined, true, undefined, this)
697
+ ]
698
+ }, undefined, true, undefined, this);
699
+ }
700
+ // src/components/JourneyMap.tsx
701
+ import { cn as cn2 } from "@contractspec/lib.ui-kit-web/ui/utils";
702
+ import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
703
+ "use client";
704
+ var SURFACE_ICONS = {
705
+ templates: "\uD83D\uDCCB",
706
+ "spec-editor": "✏️",
707
+ regenerator: "\uD83D\uDD04",
708
+ playground: "\uD83C\uDFAE",
709
+ evolution: "\uD83E\uDD16",
710
+ dashboard: "\uD83D\uDCCA",
711
+ settings: "⚙️",
712
+ default: "\uD83D\uDCCD"
713
+ };
714
+ function JourneyMap({
715
+ steps,
716
+ completedStepIds,
717
+ currentStepId
718
+ }) {
719
+ return /* @__PURE__ */ jsxDEV5("div", {
720
+ className: "relative overflow-x-auto pb-4",
721
+ children: /* @__PURE__ */ jsxDEV5("div", {
722
+ className: "flex min-w-max items-center gap-2",
723
+ children: steps.map((step, index) => {
724
+ const isCompleted = completedStepIds.includes(step.id);
725
+ const isCurrent = step.id === currentStepId;
726
+ const surface = step.metadata?.surface ?? "default";
727
+ const icon = SURFACE_ICONS[surface] ?? SURFACE_ICONS.default;
728
+ return /* @__PURE__ */ jsxDEV5("div", {
729
+ className: "flex items-center",
730
+ children: [
731
+ /* @__PURE__ */ jsxDEV5("div", {
732
+ className: "flex flex-col items-center gap-2",
733
+ children: [
734
+ /* @__PURE__ */ jsxDEV5("div", {
735
+ className: cn2("flex h-14 w-14 items-center justify-center rounded-2xl border-2 text-2xl transition-all", isCompleted && "border-green-500 bg-green-500/10", isCurrent && !isCompleted && "border-violet-500 bg-violet-500/10 ring-4 ring-violet-500/20", !isCompleted && !isCurrent && "border-muted bg-muted/50"),
736
+ children: isCompleted ? "✓" : icon
737
+ }, undefined, false, undefined, this),
738
+ /* @__PURE__ */ jsxDEV5("div", {
739
+ className: "text-center",
740
+ children: /* @__PURE__ */ jsxDEV5("p", {
741
+ className: cn2("max-w-[100px] truncate text-xs font-medium", isCompleted && "text-green-500", isCurrent && !isCompleted && "text-violet-500", !isCompleted && !isCurrent && "text-muted-foreground"),
742
+ children: step.title
743
+ }, undefined, false, undefined, this)
744
+ }, undefined, false, undefined, this)
745
+ ]
746
+ }, undefined, true, undefined, this),
747
+ index < steps.length - 1 && /* @__PURE__ */ jsxDEV5("div", {
748
+ className: cn2("mx-2 h-1 w-8 rounded-full transition-colors", completedStepIds.includes(steps[index + 1]?.id ?? "") ? "bg-green-500" : isCompleted ? "bg-green-500/50" : "bg-muted")
749
+ }, undefined, false, undefined, this)
750
+ ]
751
+ }, step.id, true, undefined, this);
752
+ })
753
+ }, undefined, false, undefined, this)
754
+ }, undefined, false, undefined, this);
755
+ }
756
+
757
+ // src/views/Timeline.tsx
758
+ import {
759
+ Card as Card3,
760
+ CardContent as CardContent3,
761
+ CardHeader as CardHeader3,
762
+ CardTitle as CardTitle3
763
+ } from "@contractspec/lib.ui-kit-web/ui/card";
764
+ import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
765
+ "use client";
766
+ function Timeline({ track, progress }) {
767
+ const currentStepId = track.steps.find((s) => !progress.completedStepIds.includes(s.id))?.id ?? null;
768
+ return /* @__PURE__ */ jsxDEV6("div", {
769
+ className: "space-y-6",
770
+ children: [
771
+ /* @__PURE__ */ jsxDEV6("div", {
772
+ className: "text-center",
773
+ children: [
774
+ /* @__PURE__ */ jsxDEV6("h2", {
775
+ className: "text-xl font-bold",
776
+ children: "Your Learning Journey"
777
+ }, undefined, false, undefined, this),
778
+ /* @__PURE__ */ jsxDEV6("p", {
779
+ className: "text-muted-foreground",
780
+ children: "Follow the path through each surface and feature"
781
+ }, undefined, false, undefined, this)
782
+ ]
783
+ }, undefined, true, undefined, this),
784
+ /* @__PURE__ */ jsxDEV6(Card3, {
785
+ children: [
786
+ /* @__PURE__ */ jsxDEV6(CardHeader3, {
787
+ children: /* @__PURE__ */ jsxDEV6(CardTitle3, {
788
+ className: "flex items-center gap-2",
789
+ children: [
790
+ /* @__PURE__ */ jsxDEV6("span", {
791
+ children: "\uD83D\uDDFA️"
792
+ }, undefined, false, undefined, this),
793
+ /* @__PURE__ */ jsxDEV6("span", {
794
+ children: "Journey Map"
795
+ }, undefined, false, undefined, this)
796
+ ]
797
+ }, undefined, true, undefined, this)
798
+ }, undefined, false, undefined, this),
799
+ /* @__PURE__ */ jsxDEV6(CardContent3, {
800
+ children: /* @__PURE__ */ jsxDEV6(JourneyMap, {
801
+ steps: track.steps,
802
+ completedStepIds: progress.completedStepIds,
803
+ currentStepId
804
+ }, undefined, false, undefined, this)
805
+ }, undefined, false, undefined, this)
806
+ ]
807
+ }, undefined, true, undefined, this),
808
+ /* @__PURE__ */ jsxDEV6(Card3, {
809
+ children: [
810
+ /* @__PURE__ */ jsxDEV6(CardHeader3, {
811
+ children: /* @__PURE__ */ jsxDEV6(CardTitle3, {
812
+ className: "flex items-center gap-2",
813
+ children: [
814
+ /* @__PURE__ */ jsxDEV6("span", {
815
+ children: "\uD83D\uDCCD"
816
+ }, undefined, false, undefined, this),
817
+ /* @__PURE__ */ jsxDEV6("span", {
818
+ children: "Step by Step"
819
+ }, undefined, false, undefined, this)
820
+ ]
821
+ }, undefined, true, undefined, this)
822
+ }, undefined, false, undefined, this),
823
+ /* @__PURE__ */ jsxDEV6(CardContent3, {
824
+ children: /* @__PURE__ */ jsxDEV6("div", {
825
+ className: "relative",
826
+ children: [
827
+ /* @__PURE__ */ jsxDEV6("div", {
828
+ className: "bg-border absolute top-0 left-4 h-full w-0.5"
829
+ }, undefined, false, undefined, this),
830
+ /* @__PURE__ */ jsxDEV6("div", {
831
+ className: "space-y-6",
832
+ children: track.steps.map((step, index) => {
833
+ const isCompleted = progress.completedStepIds.includes(step.id);
834
+ const isCurrent = step.id === currentStepId;
835
+ const surface = step.metadata?.surface ?? "general";
836
+ return /* @__PURE__ */ jsxDEV6("div", {
837
+ className: "relative flex gap-4 pl-2",
838
+ children: [
839
+ /* @__PURE__ */ jsxDEV6("div", {
840
+ className: `relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full border-2 transition-all ${isCompleted ? "border-green-500 bg-green-500 text-white" : isCurrent ? "border-blue-500 bg-blue-500 text-white ring-4 ring-blue-500/20" : "border-border bg-background text-muted-foreground"}`,
841
+ children: isCompleted ? "✓" : index + 1
842
+ }, undefined, false, undefined, this),
843
+ /* @__PURE__ */ jsxDEV6("div", {
844
+ className: "flex-1 pb-2",
845
+ children: /* @__PURE__ */ jsxDEV6("div", {
846
+ className: "rounded-lg border p-4",
847
+ children: [
848
+ /* @__PURE__ */ jsxDEV6("div", {
849
+ className: "flex items-start justify-between gap-2",
850
+ children: [
851
+ /* @__PURE__ */ jsxDEV6("div", {
852
+ children: [
853
+ /* @__PURE__ */ jsxDEV6("div", {
854
+ className: "flex items-center gap-2",
855
+ children: [
856
+ /* @__PURE__ */ jsxDEV6("h4", {
857
+ className: `font-semibold ${isCompleted ? "text-green-500" : isCurrent ? "text-blue-500" : "text-foreground"}`,
858
+ children: step.title
859
+ }, undefined, false, undefined, this),
860
+ /* @__PURE__ */ jsxDEV6("span", {
861
+ className: "bg-muted text-muted-foreground rounded px-2 py-0.5 text-xs",
862
+ children: surface
863
+ }, undefined, false, undefined, this)
864
+ ]
865
+ }, undefined, true, undefined, this),
866
+ /* @__PURE__ */ jsxDEV6("p", {
867
+ className: "text-muted-foreground mt-1 text-sm",
868
+ children: step.description
869
+ }, undefined, false, undefined, this)
870
+ ]
871
+ }, undefined, true, undefined, this),
872
+ step.xpReward && /* @__PURE__ */ jsxDEV6("span", {
873
+ className: `shrink-0 rounded-full px-2 py-1 text-xs font-semibold ${isCompleted ? "bg-green-500/10 text-green-500" : "bg-muted text-muted-foreground"}`,
874
+ children: [
875
+ "+",
876
+ step.xpReward,
877
+ " XP"
878
+ ]
879
+ }, undefined, true, undefined, this)
880
+ ]
881
+ }, undefined, true, undefined, this),
882
+ /* @__PURE__ */ jsxDEV6("div", {
883
+ className: "mt-3 text-xs",
884
+ children: isCompleted ? /* @__PURE__ */ jsxDEV6("span", {
885
+ className: "text-green-500",
886
+ children: "✓ Completed"
887
+ }, undefined, false, undefined, this) : isCurrent ? /* @__PURE__ */ jsxDEV6("span", {
888
+ className: "text-blue-500",
889
+ children: "→ In Progress"
890
+ }, undefined, false, undefined, this) : /* @__PURE__ */ jsxDEV6("span", {
891
+ className: "text-muted-foreground",
892
+ children: "○ Not Started"
893
+ }, undefined, false, undefined, this)
894
+ }, undefined, false, undefined, this)
895
+ ]
896
+ }, undefined, true, undefined, this)
897
+ }, undefined, false, undefined, this)
898
+ ]
899
+ }, step.id, true, undefined, this);
900
+ })
901
+ }, undefined, false, undefined, this)
902
+ ]
903
+ }, undefined, true, undefined, this)
904
+ }, undefined, false, undefined, this)
905
+ ]
906
+ }, undefined, true, undefined, this)
907
+ ]
908
+ }, undefined, true, undefined, this);
909
+ }
910
+
911
+ // src/OnboardingMiniApp.tsx
912
+ import { useState as useState2, useCallback } from "react";
913
+ import { Card as Card4, CardContent as CardContent4 } from "@contractspec/lib.ui-kit-web/ui/card";
914
+ import {
915
+ ViewTabs,
916
+ useLearningProgress
917
+ } from "@contractspec/example.learning-journey-ui-shared";
918
+ import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
919
+ "use client";
920
+ function OnboardingMiniApp({
921
+ track,
922
+ progress: externalProgress,
923
+ onStepComplete: externalOnStepComplete,
924
+ onViewChange,
925
+ initialView = "overview"
926
+ }) {
927
+ const [currentView, setCurrentView] = useState2(initialView);
928
+ const { progress: internalProgress, completeStep: internalCompleteStep } = useLearningProgress(track);
929
+ const progress = externalProgress ?? internalProgress;
930
+ const handleViewChange = useCallback((view) => {
931
+ setCurrentView(view);
932
+ onViewChange?.(view);
933
+ }, [onViewChange]);
934
+ const handleStepComplete = useCallback((stepId) => {
935
+ if (externalOnStepComplete) {
936
+ externalOnStepComplete(stepId);
937
+ } else {
938
+ internalCompleteStep(stepId);
939
+ }
940
+ }, [externalOnStepComplete, internalCompleteStep]);
941
+ const handleStartFromOverview = useCallback(() => {
942
+ setCurrentView("steps");
943
+ onViewChange?.("steps");
944
+ }, [onViewChange]);
945
+ const renderView = () => {
946
+ const viewProps = {
947
+ track,
948
+ progress,
949
+ onStepComplete: handleStepComplete
950
+ };
951
+ switch (currentView) {
952
+ case "overview":
953
+ return /* @__PURE__ */ jsxDEV7(Overview, {
954
+ ...viewProps,
955
+ onStart: handleStartFromOverview
956
+ }, undefined, false, undefined, this);
957
+ case "steps":
958
+ return /* @__PURE__ */ jsxDEV7(Steps, {
959
+ ...viewProps
960
+ }, undefined, false, undefined, this);
961
+ case "progress":
962
+ return /* @__PURE__ */ jsxDEV7(ProgressView, {
963
+ ...viewProps
964
+ }, undefined, false, undefined, this);
965
+ case "timeline":
966
+ return /* @__PURE__ */ jsxDEV7(Timeline, {
967
+ ...viewProps
968
+ }, undefined, false, undefined, this);
969
+ default:
970
+ return /* @__PURE__ */ jsxDEV7(Overview, {
971
+ ...viewProps,
972
+ onStart: handleStartFromOverview
973
+ }, undefined, false, undefined, this);
974
+ }
975
+ };
976
+ return /* @__PURE__ */ jsxDEV7("div", {
977
+ className: "space-y-6",
978
+ children: [
979
+ /* @__PURE__ */ jsxDEV7(Card4, {
980
+ children: /* @__PURE__ */ jsxDEV7(CardContent4, {
981
+ className: "p-4",
982
+ children: /* @__PURE__ */ jsxDEV7(ViewTabs, {
983
+ currentView,
984
+ onViewChange: handleViewChange
985
+ }, undefined, false, undefined, this)
986
+ }, undefined, false, undefined, this)
987
+ }, undefined, false, undefined, this),
988
+ renderView()
989
+ ]
990
+ }, undefined, true, undefined, this);
991
+ }
992
+
993
+ // src/components/CodeSnippet.tsx
994
+ import { useState as useState3 } from "react";
995
+ import { Button as Button3 } from "@contractspec/lib.design-system";
996
+ import { jsxDEV as jsxDEV8, Fragment } from "react/jsx-dev-runtime";
997
+ "use client";
998
+ function CodeSnippet({
999
+ code,
1000
+ language = "typescript",
1001
+ title
1002
+ }) {
1003
+ const [copied, setCopied] = useState3(false);
1004
+ const handleCopy = async () => {
1005
+ await navigator.clipboard.writeText(code);
1006
+ setCopied(true);
1007
+ setTimeout(() => setCopied(false), 2000);
1008
+ };
1009
+ return /* @__PURE__ */ jsxDEV8("div", {
1010
+ className: "bg-muted/50 overflow-hidden rounded-lg border",
1011
+ children: [
1012
+ /* @__PURE__ */ jsxDEV8("div", {
1013
+ className: "bg-muted flex items-center justify-between border-b px-4 py-2",
1014
+ children: [
1015
+ /* @__PURE__ */ jsxDEV8("div", {
1016
+ className: "flex items-center gap-2",
1017
+ children: [
1018
+ /* @__PURE__ */ jsxDEV8("span", {
1019
+ className: "text-muted-foreground text-xs font-medium uppercase",
1020
+ children: language
1021
+ }, undefined, false, undefined, this),
1022
+ title && /* @__PURE__ */ jsxDEV8(Fragment, {
1023
+ children: [
1024
+ /* @__PURE__ */ jsxDEV8("span", {
1025
+ className: "text-muted-foreground",
1026
+ children: "•"
1027
+ }, undefined, false, undefined, this),
1028
+ /* @__PURE__ */ jsxDEV8("span", {
1029
+ className: "text-sm",
1030
+ children: title
1031
+ }, undefined, false, undefined, this)
1032
+ ]
1033
+ }, undefined, true, undefined, this)
1034
+ ]
1035
+ }, undefined, true, undefined, this),
1036
+ /* @__PURE__ */ jsxDEV8(Button3, {
1037
+ variant: "ghost",
1038
+ size: "sm",
1039
+ onClick: handleCopy,
1040
+ className: "h-7 text-xs",
1041
+ children: copied ? "✓ Copied" : "Copy"
1042
+ }, undefined, false, undefined, this)
1043
+ ]
1044
+ }, undefined, true, undefined, this),
1045
+ /* @__PURE__ */ jsxDEV8("pre", {
1046
+ className: "overflow-x-auto p-4",
1047
+ children: /* @__PURE__ */ jsxDEV8("code", {
1048
+ className: "text-sm",
1049
+ children: code
1050
+ }, undefined, false, undefined, this)
1051
+ }, undefined, false, undefined, this)
1052
+ ]
1053
+ }, undefined, true, undefined, this);
1054
+ }
1055
+ // src/docs/learning-journey-ui-onboarding.docblock.ts
1056
+ import { registerDocBlocks } from "@contractspec/lib.contracts/docs";
1057
+ var blocks = [
1058
+ {
1059
+ id: "docs.examples.learning-journey-ui-onboarding",
1060
+ title: "Learning Journey UI — Onboarding",
1061
+ summary: "UI mini-app components for onboarding: checklists, snippets, and journey mapping.",
1062
+ kind: "reference",
1063
+ visibility: "public",
1064
+ route: "/docs/examples/learning-journey-ui-onboarding",
1065
+ tags: ["learning", "ui", "onboarding"],
1066
+ body: `## Includes
1067
+ - Onboarding mini-app shell
1068
+ - Views: overview, steps, progress, timeline
1069
+ - Components: step checklist, code snippet, journey map
1070
+
1071
+ ## Notes
1072
+ - Compose with design system components.
1073
+ - Ensure accessible labels and keyboard navigation.`
1074
+ }
1075
+ ];
1076
+ registerDocBlocks(blocks);
1077
+ // src/example.ts
1078
+ import { defineExample } from "@contractspec/lib.contracts";
1079
+ var example = defineExample({
1080
+ meta: {
1081
+ key: "learning-journey-ui-onboarding",
1082
+ version: "1.0.0",
1083
+ title: "Learning Journey UI — Onboarding",
1084
+ description: "UI mini-app for onboarding patterns: checklists, code snippets, journey map.",
1085
+ kind: "ui",
1086
+ visibility: "public",
1087
+ stability: "experimental",
1088
+ owners: ["@platform.core"],
1089
+ tags: ["learning", "ui", "onboarding"]
1090
+ },
1091
+ docs: {
1092
+ rootDocId: "docs.examples.learning-journey-ui-onboarding"
1093
+ },
1094
+ entrypoints: {
1095
+ packageName: "@contractspec/example.learning-journey-ui-onboarding",
1096
+ docs: "./docs"
1097
+ },
1098
+ surfaces: {
1099
+ templates: true,
1100
+ sandbox: { enabled: true, modes: ["playground", "markdown"] },
1101
+ studio: { enabled: true, installable: true },
1102
+ mcp: { enabled: true }
1103
+ }
1104
+ });
1105
+ var example_default = example;
1106
+ export {
1107
+ example_default as example,
1108
+ Timeline,
1109
+ Steps,
1110
+ StepChecklist,
1111
+ ProgressView as Progress,
1112
+ Overview,
1113
+ OnboardingMiniApp,
1114
+ JourneyMap,
1115
+ CodeSnippet
1116
+ };