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