@contractspec/example.learning-journey-ui-gamified 3.7.6 → 3.7.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.turbo/turbo-build.log +6 -6
- package/AGENTS.md +50 -25
- package/README.md +63 -20
- package/dist/GamifiedMiniApp.js +246 -246
- package/dist/browser/GamifiedMiniApp.js +246 -246
- package/dist/browser/components/DayCalendar.js +1 -1
- package/dist/browser/components/FlashCard.js +6 -6
- package/dist/browser/components/MasteryRing.js +1 -1
- package/dist/browser/components/index.js +100 -100
- package/dist/browser/index.js +247 -246
- package/dist/browser/views/Overview.js +16 -16
- package/dist/browser/views/Progress.js +7 -7
- package/dist/browser/views/Steps.js +8 -8
- package/dist/browser/views/Timeline.js +8 -8
- package/dist/browser/views/index.js +242 -242
- package/dist/components/DayCalendar.js +1 -1
- package/dist/components/FlashCard.js +6 -6
- package/dist/components/MasteryRing.js +1 -1
- package/dist/components/index.d.ts +1 -1
- package/dist/components/index.js +100 -100
- package/dist/index.d.ts +3 -3
- package/dist/index.js +247 -246
- package/dist/node/GamifiedMiniApp.js +246 -246
- package/dist/node/components/DayCalendar.js +1 -1
- package/dist/node/components/FlashCard.js +6 -6
- package/dist/node/components/MasteryRing.js +1 -1
- package/dist/node/components/index.js +100 -100
- package/dist/node/index.js +247 -246
- package/dist/node/views/Overview.js +16 -16
- package/dist/node/views/Progress.js +7 -7
- package/dist/node/views/Steps.js +8 -8
- package/dist/node/views/Timeline.js +8 -8
- package/dist/node/views/index.js +242 -242
- package/dist/views/Overview.js +16 -16
- package/dist/views/Progress.js +7 -7
- package/dist/views/Steps.js +8 -8
- package/dist/views/Timeline.js +8 -8
- package/dist/views/index.d.ts +1 -1
- package/dist/views/index.js +242 -242
- package/package.json +10 -10
- package/src/GamifiedMiniApp.tsx +70 -70
- package/src/components/DayCalendar.tsx +41 -41
- package/src/components/FlashCard.tsx +83 -83
- package/src/components/MasteryRing.tsx +64 -64
- package/src/components/index.ts +1 -1
- package/src/docs/learning-journey-ui-gamified.docblock.ts +11 -11
- package/src/example.ts +25 -25
- package/src/index.ts +5 -6
- package/src/learning-journey-ui-gamified.feature.ts +12 -12
- package/src/views/Overview.tsx +145 -145
- package/src/views/Progress.tsx +167 -167
- package/src/views/Steps.tsx +40 -40
- package/src/views/Timeline.tsx +177 -177
- package/src/views/index.ts +1 -1
- package/tsconfig.json +7 -8
- package/tsdown.config.js +7 -13
package/dist/index.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
// src/views/Overview.tsx
|
|
3
|
+
import {
|
|
4
|
+
BadgeDisplay,
|
|
5
|
+
StreakCounter,
|
|
6
|
+
XpBar
|
|
7
|
+
} from "@contractspec/example.learning-journey-ui-shared";
|
|
3
8
|
import { Button } from "@contractspec/lib.design-system";
|
|
4
9
|
import {
|
|
5
10
|
Card,
|
|
@@ -7,11 +12,6 @@ import {
|
|
|
7
12
|
CardHeader,
|
|
8
13
|
CardTitle
|
|
9
14
|
} from "@contractspec/lib.ui-kit-web/ui/card";
|
|
10
|
-
import {
|
|
11
|
-
XpBar,
|
|
12
|
-
StreakCounter,
|
|
13
|
-
BadgeDisplay
|
|
14
|
-
} from "@contractspec/example.learning-journey-ui-shared";
|
|
15
15
|
import { jsxDEV } from "react/jsx-dev-runtime";
|
|
16
16
|
"use client";
|
|
17
17
|
function Overview({ track, progress, onStart }) {
|
|
@@ -37,11 +37,11 @@ function Overview({ track, progress, onStart }) {
|
|
|
37
37
|
className: "flex-1",
|
|
38
38
|
children: [
|
|
39
39
|
/* @__PURE__ */ jsxDEV("h1", {
|
|
40
|
-
className: "text-2xl
|
|
40
|
+
className: "font-bold text-2xl",
|
|
41
41
|
children: track.name
|
|
42
42
|
}, undefined, false, undefined, this),
|
|
43
43
|
/* @__PURE__ */ jsxDEV("p", {
|
|
44
|
-
className: "text-muted-foreground
|
|
44
|
+
className: "mt-1 text-muted-foreground",
|
|
45
45
|
children: track.description
|
|
46
46
|
}, undefined, false, undefined, this)
|
|
47
47
|
]
|
|
@@ -65,14 +65,14 @@ function Overview({ track, progress, onStart }) {
|
|
|
65
65
|
/* @__PURE__ */ jsxDEV(CardHeader, {
|
|
66
66
|
className: "pb-2",
|
|
67
67
|
children: /* @__PURE__ */ jsxDEV(CardTitle, {
|
|
68
|
-
className: "text-muted-foreground text-sm
|
|
68
|
+
className: "font-medium text-muted-foreground text-sm",
|
|
69
69
|
children: "XP Progress"
|
|
70
70
|
}, undefined, false, undefined, this)
|
|
71
71
|
}, undefined, false, undefined, this),
|
|
72
72
|
/* @__PURE__ */ jsxDEV(CardContent, {
|
|
73
73
|
children: [
|
|
74
74
|
/* @__PURE__ */ jsxDEV("div", {
|
|
75
|
-
className: "
|
|
75
|
+
className: "font-bold text-3xl text-violet-500",
|
|
76
76
|
children: progress.xpEarned.toLocaleString()
|
|
77
77
|
}, undefined, false, undefined, this),
|
|
78
78
|
/* @__PURE__ */ jsxDEV(XpBar, {
|
|
@@ -90,19 +90,19 @@ function Overview({ track, progress, onStart }) {
|
|
|
90
90
|
/* @__PURE__ */ jsxDEV(CardHeader, {
|
|
91
91
|
className: "pb-2",
|
|
92
92
|
children: /* @__PURE__ */ jsxDEV(CardTitle, {
|
|
93
|
-
className: "text-muted-foreground text-sm
|
|
93
|
+
className: "font-medium text-muted-foreground text-sm",
|
|
94
94
|
children: "Steps Completed"
|
|
95
95
|
}, undefined, false, undefined, this)
|
|
96
96
|
}, undefined, false, undefined, this),
|
|
97
97
|
/* @__PURE__ */ jsxDEV(CardContent, {
|
|
98
98
|
children: [
|
|
99
99
|
/* @__PURE__ */ jsxDEV("div", {
|
|
100
|
-
className: "text-3xl
|
|
100
|
+
className: "font-bold text-3xl",
|
|
101
101
|
children: [
|
|
102
102
|
completedSteps,
|
|
103
103
|
" ",
|
|
104
104
|
/* @__PURE__ */ jsxDEV("span", {
|
|
105
|
-
className: "text-muted-foreground
|
|
105
|
+
className: "text-lg text-muted-foreground",
|
|
106
106
|
children: [
|
|
107
107
|
"/ ",
|
|
108
108
|
totalSteps
|
|
@@ -111,7 +111,7 @@ function Overview({ track, progress, onStart }) {
|
|
|
111
111
|
]
|
|
112
112
|
}, undefined, true, undefined, this),
|
|
113
113
|
/* @__PURE__ */ jsxDEV("div", {
|
|
114
|
-
className: "
|
|
114
|
+
className: "mt-2 h-2 w-full overflow-hidden rounded-full bg-muted",
|
|
115
115
|
children: /* @__PURE__ */ jsxDEV("div", {
|
|
116
116
|
className: "h-full bg-green-500 transition-all duration-500",
|
|
117
117
|
style: { width: `${completedSteps / totalSteps * 100}%` }
|
|
@@ -126,7 +126,7 @@ function Overview({ track, progress, onStart }) {
|
|
|
126
126
|
/* @__PURE__ */ jsxDEV(CardHeader, {
|
|
127
127
|
className: "pb-2",
|
|
128
128
|
children: /* @__PURE__ */ jsxDEV(CardTitle, {
|
|
129
|
-
className: "text-muted-foreground text-sm
|
|
129
|
+
className: "font-medium text-muted-foreground text-sm",
|
|
130
130
|
children: "Badges Earned"
|
|
131
131
|
}, undefined, false, undefined, this)
|
|
132
132
|
}, undefined, false, undefined, this),
|
|
@@ -179,7 +179,7 @@ function Overview({ track, progress, onStart }) {
|
|
|
179
179
|
className: "flex items-center gap-3",
|
|
180
180
|
children: [
|
|
181
181
|
nextStep.xpReward && /* @__PURE__ */ jsxDEV("span", {
|
|
182
|
-
className: "rounded-full bg-green-500/10 px-3 py-1
|
|
182
|
+
className: "rounded-full bg-green-500/10 px-3 py-1 font-semibold text-green-500 text-sm",
|
|
183
183
|
children: [
|
|
184
184
|
"+",
|
|
185
185
|
nextStep.xpReward,
|
|
@@ -210,7 +210,7 @@ function Overview({ track, progress, onStart }) {
|
|
|
210
210
|
/* @__PURE__ */ jsxDEV("div", {
|
|
211
211
|
children: [
|
|
212
212
|
/* @__PURE__ */ jsxDEV("h3", {
|
|
213
|
-
className: "
|
|
213
|
+
className: "font-semibold text-green-500 text-lg",
|
|
214
214
|
children: "Track Complete!"
|
|
215
215
|
}, undefined, false, undefined, this),
|
|
216
216
|
/* @__PURE__ */ jsxDEV("p", {
|
|
@@ -233,165 +233,10 @@ function Overview({ track, progress, onStart }) {
|
|
|
233
233
|
}, undefined, true, undefined, this);
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
// src/components/
|
|
237
|
-
import { useState } from "react";
|
|
238
|
-
import { Button as Button2 } from "@contractspec/lib.design-system";
|
|
239
|
-
import { Card as Card2, CardContent as CardContent2 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
236
|
+
// src/components/MasteryRing.tsx
|
|
240
237
|
import { cn } from "@contractspec/lib.ui-kit-web/ui/utils";
|
|
241
238
|
import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
|
|
242
239
|
"use client";
|
|
243
|
-
function FlashCard({
|
|
244
|
-
step,
|
|
245
|
-
isCompleted,
|
|
246
|
-
isCurrent,
|
|
247
|
-
onComplete
|
|
248
|
-
}) {
|
|
249
|
-
const [isFlipped, setIsFlipped] = useState(false);
|
|
250
|
-
return /* @__PURE__ */ jsxDEV2(Card2, {
|
|
251
|
-
className: cn("relative cursor-pointer overflow-hidden transition-all duration-300", isCurrent && "ring-primary ring-2", isCompleted && "opacity-60"),
|
|
252
|
-
onClick: () => !isCompleted && setIsFlipped(!isFlipped),
|
|
253
|
-
children: /* @__PURE__ */ jsxDEV2(CardContent2, {
|
|
254
|
-
className: "p-6",
|
|
255
|
-
children: [
|
|
256
|
-
/* @__PURE__ */ jsxDEV2("div", {
|
|
257
|
-
className: cn("space-y-4 transition-opacity duration-200", isFlipped ? "opacity-0" : "opacity-100"),
|
|
258
|
-
children: [
|
|
259
|
-
/* @__PURE__ */ jsxDEV2("div", {
|
|
260
|
-
className: "flex items-start justify-between",
|
|
261
|
-
children: [
|
|
262
|
-
/* @__PURE__ */ jsxDEV2("div", {
|
|
263
|
-
className: "flex-1",
|
|
264
|
-
children: [
|
|
265
|
-
/* @__PURE__ */ jsxDEV2("h3", {
|
|
266
|
-
className: "text-lg font-semibold",
|
|
267
|
-
children: step.title
|
|
268
|
-
}, undefined, false, undefined, this),
|
|
269
|
-
step.description && /* @__PURE__ */ jsxDEV2("p", {
|
|
270
|
-
className: "text-muted-foreground mt-1 text-sm",
|
|
271
|
-
children: step.description
|
|
272
|
-
}, undefined, false, undefined, this)
|
|
273
|
-
]
|
|
274
|
-
}, undefined, true, undefined, this),
|
|
275
|
-
step.xpReward && /* @__PURE__ */ jsxDEV2("span", {
|
|
276
|
-
className: "rounded-full bg-green-500/10 px-2 py-1 text-xs font-semibold text-green-500",
|
|
277
|
-
children: [
|
|
278
|
-
"+",
|
|
279
|
-
step.xpReward,
|
|
280
|
-
" XP"
|
|
281
|
-
]
|
|
282
|
-
}, undefined, true, undefined, this)
|
|
283
|
-
]
|
|
284
|
-
}, undefined, true, undefined, this),
|
|
285
|
-
isCompleted && /* @__PURE__ */ jsxDEV2("div", {
|
|
286
|
-
className: "flex items-center gap-2 text-green-500",
|
|
287
|
-
children: [
|
|
288
|
-
/* @__PURE__ */ jsxDEV2("span", {
|
|
289
|
-
children: "\u2713"
|
|
290
|
-
}, undefined, false, undefined, this),
|
|
291
|
-
/* @__PURE__ */ jsxDEV2("span", {
|
|
292
|
-
className: "text-sm font-medium",
|
|
293
|
-
children: "Completed"
|
|
294
|
-
}, undefined, false, undefined, this)
|
|
295
|
-
]
|
|
296
|
-
}, undefined, true, undefined, this),
|
|
297
|
-
isCurrent && !isCompleted && /* @__PURE__ */ jsxDEV2("p", {
|
|
298
|
-
className: "text-muted-foreground text-xs",
|
|
299
|
-
children: "Tap to reveal action"
|
|
300
|
-
}, undefined, false, undefined, this)
|
|
301
|
-
]
|
|
302
|
-
}, undefined, true, undefined, this),
|
|
303
|
-
isFlipped && !isCompleted && /* @__PURE__ */ jsxDEV2("div", {
|
|
304
|
-
className: "absolute inset-0 flex flex-col items-center justify-center gap-4 bg-gradient-to-br from-violet-500/10 to-violet-600/10 p-6",
|
|
305
|
-
children: [
|
|
306
|
-
/* @__PURE__ */ jsxDEV2("p", {
|
|
307
|
-
className: "text-center text-sm",
|
|
308
|
-
children: step.instructions ?? "Complete this step to earn XP"
|
|
309
|
-
}, undefined, false, undefined, this),
|
|
310
|
-
/* @__PURE__ */ jsxDEV2("div", {
|
|
311
|
-
className: "flex gap-2",
|
|
312
|
-
children: [
|
|
313
|
-
/* @__PURE__ */ jsxDEV2(Button2, {
|
|
314
|
-
variant: "outline",
|
|
315
|
-
size: "sm",
|
|
316
|
-
onClick: () => setIsFlipped(false),
|
|
317
|
-
children: "Back"
|
|
318
|
-
}, undefined, false, undefined, this),
|
|
319
|
-
/* @__PURE__ */ jsxDEV2(Button2, {
|
|
320
|
-
size: "sm",
|
|
321
|
-
onClick: (e) => {
|
|
322
|
-
e.stopPropagation();
|
|
323
|
-
onComplete?.();
|
|
324
|
-
},
|
|
325
|
-
children: "Mark 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
|
-
}, undefined, false, undefined, this);
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// src/views/Steps.tsx
|
|
337
|
-
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
338
|
-
"use client";
|
|
339
|
-
function Steps({ track, progress, onStepComplete }) {
|
|
340
|
-
const currentStepIndex = track.steps.findIndex((s) => !progress.completedStepIds.includes(s.id));
|
|
341
|
-
return /* @__PURE__ */ jsxDEV3("div", {
|
|
342
|
-
className: "space-y-6",
|
|
343
|
-
children: [
|
|
344
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
345
|
-
className: "text-center",
|
|
346
|
-
children: [
|
|
347
|
-
/* @__PURE__ */ jsxDEV3("h2", {
|
|
348
|
-
className: "text-xl font-bold",
|
|
349
|
-
children: "Complete Your Challenges"
|
|
350
|
-
}, undefined, false, undefined, this),
|
|
351
|
-
/* @__PURE__ */ jsxDEV3("p", {
|
|
352
|
-
className: "text-muted-foreground",
|
|
353
|
-
children: "Tap each card to reveal the action, then mark as complete"
|
|
354
|
-
}, undefined, false, undefined, this)
|
|
355
|
-
]
|
|
356
|
-
}, undefined, true, undefined, this),
|
|
357
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
358
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
359
|
-
children: track.steps.map((step, index) => {
|
|
360
|
-
const isCompleted = progress.completedStepIds.includes(step.id);
|
|
361
|
-
const isCurrent = index === currentStepIndex;
|
|
362
|
-
return /* @__PURE__ */ jsxDEV3(FlashCard, {
|
|
363
|
-
step,
|
|
364
|
-
isCompleted,
|
|
365
|
-
isCurrent,
|
|
366
|
-
onComplete: () => onStepComplete?.(step.id)
|
|
367
|
-
}, step.id, false, undefined, this);
|
|
368
|
-
})
|
|
369
|
-
}, undefined, false, undefined, this),
|
|
370
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
371
|
-
className: "text-muted-foreground text-center text-sm",
|
|
372
|
-
children: [
|
|
373
|
-
progress.completedStepIds.length,
|
|
374
|
-
" of ",
|
|
375
|
-
track.steps.length,
|
|
376
|
-
" completed",
|
|
377
|
-
track.completionRewards?.xpBonus && /* @__PURE__ */ jsxDEV3("span", {
|
|
378
|
-
className: "ml-2 text-green-500",
|
|
379
|
-
children: [
|
|
380
|
-
"(+",
|
|
381
|
-
track.completionRewards.xpBonus,
|
|
382
|
-
" XP bonus on completion)"
|
|
383
|
-
]
|
|
384
|
-
}, undefined, true, undefined, this)
|
|
385
|
-
]
|
|
386
|
-
}, undefined, true, undefined, this)
|
|
387
|
-
]
|
|
388
|
-
}, undefined, true, undefined, this);
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
// src/components/MasteryRing.tsx
|
|
392
|
-
import { cn as cn2 } from "@contractspec/lib.ui-kit-web/ui/utils";
|
|
393
|
-
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
394
|
-
"use client";
|
|
395
240
|
var sizeStyles = {
|
|
396
241
|
sm: { container: "h-16 w-16", text: "text-xs", ring: 48, stroke: 4 },
|
|
397
242
|
md: { container: "h-24 w-24", text: "text-sm", ring: 72, stroke: 6 },
|
|
@@ -413,16 +258,16 @@ function MasteryRing({
|
|
|
413
258
|
const radius = (styles.ring - styles.stroke) / 2;
|
|
414
259
|
const circumference = 2 * Math.PI * radius;
|
|
415
260
|
const strokeDashoffset = circumference - percentage / 100 * circumference;
|
|
416
|
-
return /* @__PURE__ */
|
|
417
|
-
className:
|
|
261
|
+
return /* @__PURE__ */ jsxDEV2("div", {
|
|
262
|
+
className: cn("relative flex flex-col items-center gap-1", styles.container),
|
|
418
263
|
children: [
|
|
419
|
-
/* @__PURE__ */
|
|
264
|
+
/* @__PURE__ */ jsxDEV2("svg", {
|
|
420
265
|
className: "absolute -rotate-90",
|
|
421
266
|
width: styles.ring,
|
|
422
267
|
height: styles.ring,
|
|
423
268
|
viewBox: `0 0 ${styles.ring} ${styles.ring}`,
|
|
424
269
|
children: [
|
|
425
|
-
/* @__PURE__ */
|
|
270
|
+
/* @__PURE__ */ jsxDEV2("circle", {
|
|
426
271
|
cx: styles.ring / 2,
|
|
427
272
|
cy: styles.ring / 2,
|
|
428
273
|
r: radius,
|
|
@@ -430,7 +275,7 @@ function MasteryRing({
|
|
|
430
275
|
strokeWidth: styles.stroke,
|
|
431
276
|
className: "stroke-muted"
|
|
432
277
|
}, undefined, false, undefined, this),
|
|
433
|
-
/* @__PURE__ */
|
|
278
|
+
/* @__PURE__ */ jsxDEV2("circle", {
|
|
434
279
|
cx: styles.ring / 2,
|
|
435
280
|
cy: styles.ring / 2,
|
|
436
281
|
r: radius,
|
|
@@ -439,22 +284,22 @@ function MasteryRing({
|
|
|
439
284
|
strokeLinecap: "round",
|
|
440
285
|
strokeDasharray: circumference,
|
|
441
286
|
strokeDashoffset,
|
|
442
|
-
className:
|
|
287
|
+
className: cn("transition-all duration-500", colorStyles[color])
|
|
443
288
|
}, undefined, false, undefined, this)
|
|
444
289
|
]
|
|
445
290
|
}, undefined, true, undefined, this),
|
|
446
|
-
/* @__PURE__ */
|
|
291
|
+
/* @__PURE__ */ jsxDEV2("div", {
|
|
447
292
|
className: "flex h-full flex-col items-center justify-center",
|
|
448
|
-
children: /* @__PURE__ */
|
|
449
|
-
className:
|
|
293
|
+
children: /* @__PURE__ */ jsxDEV2("span", {
|
|
294
|
+
className: cn("font-bold", styles.text),
|
|
450
295
|
children: [
|
|
451
296
|
Math.round(percentage),
|
|
452
297
|
"%"
|
|
453
298
|
]
|
|
454
299
|
}, undefined, true, undefined, this)
|
|
455
300
|
}, undefined, false, undefined, this),
|
|
456
|
-
/* @__PURE__ */
|
|
457
|
-
className:
|
|
301
|
+
/* @__PURE__ */ jsxDEV2("span", {
|
|
302
|
+
className: cn("mt-1 truncate text-muted-foreground", styles.text),
|
|
458
303
|
children: label
|
|
459
304
|
}, undefined, false, undefined, this)
|
|
460
305
|
]
|
|
@@ -463,16 +308,16 @@ function MasteryRing({
|
|
|
463
308
|
|
|
464
309
|
// src/views/Progress.tsx
|
|
465
310
|
import {
|
|
466
|
-
|
|
467
|
-
|
|
311
|
+
BadgeDisplay as BadgeDisplay2,
|
|
312
|
+
XpBar as XpBar2
|
|
313
|
+
} from "@contractspec/example.learning-journey-ui-shared";
|
|
314
|
+
import {
|
|
315
|
+
Card as Card2,
|
|
316
|
+
CardContent as CardContent2,
|
|
468
317
|
CardHeader as CardHeader2,
|
|
469
318
|
CardTitle as CardTitle2
|
|
470
319
|
} from "@contractspec/lib.ui-kit-web/ui/card";
|
|
471
|
-
import {
|
|
472
|
-
XpBar as XpBar2,
|
|
473
|
-
BadgeDisplay as BadgeDisplay2
|
|
474
|
-
} from "@contractspec/example.learning-journey-ui-shared";
|
|
475
|
-
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
320
|
+
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
476
321
|
"use client";
|
|
477
322
|
function Progress({ track, progress }) {
|
|
478
323
|
const totalXp = track.totalXp ?? track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0) + (track.completionRewards?.xpBonus ?? 0);
|
|
@@ -494,35 +339,35 @@ function Progress({ track, progress }) {
|
|
|
494
339
|
"violet",
|
|
495
340
|
"orange"
|
|
496
341
|
];
|
|
497
|
-
return /* @__PURE__ */
|
|
342
|
+
return /* @__PURE__ */ jsxDEV3("div", {
|
|
498
343
|
className: "space-y-6",
|
|
499
344
|
children: [
|
|
500
|
-
/* @__PURE__ */
|
|
345
|
+
/* @__PURE__ */ jsxDEV3(Card2, {
|
|
501
346
|
children: [
|
|
502
|
-
/* @__PURE__ */
|
|
503
|
-
children: /* @__PURE__ */
|
|
347
|
+
/* @__PURE__ */ jsxDEV3(CardHeader2, {
|
|
348
|
+
children: /* @__PURE__ */ jsxDEV3(CardTitle2, {
|
|
504
349
|
className: "flex items-center gap-2",
|
|
505
350
|
children: [
|
|
506
|
-
/* @__PURE__ */
|
|
351
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
507
352
|
children: "\u26A1"
|
|
508
353
|
}, undefined, false, undefined, this),
|
|
509
|
-
/* @__PURE__ */
|
|
354
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
510
355
|
children: "Experience Points"
|
|
511
356
|
}, undefined, false, undefined, this)
|
|
512
357
|
]
|
|
513
358
|
}, undefined, true, undefined, this)
|
|
514
359
|
}, undefined, false, undefined, this),
|
|
515
|
-
/* @__PURE__ */
|
|
360
|
+
/* @__PURE__ */ jsxDEV3(CardContent2, {
|
|
516
361
|
className: "space-y-4",
|
|
517
362
|
children: [
|
|
518
|
-
/* @__PURE__ */
|
|
363
|
+
/* @__PURE__ */ jsxDEV3("div", {
|
|
519
364
|
className: "flex items-baseline gap-2",
|
|
520
365
|
children: [
|
|
521
|
-
/* @__PURE__ */
|
|
522
|
-
className: "
|
|
366
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
367
|
+
className: "font-bold text-4xl text-violet-500",
|
|
523
368
|
children: progress.xpEarned.toLocaleString()
|
|
524
369
|
}, undefined, false, undefined, this),
|
|
525
|
-
/* @__PURE__ */
|
|
370
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
526
371
|
className: "text-muted-foreground",
|
|
527
372
|
children: [
|
|
528
373
|
"/ ",
|
|
@@ -532,18 +377,18 @@ function Progress({ track, progress }) {
|
|
|
532
377
|
}, undefined, true, undefined, this)
|
|
533
378
|
]
|
|
534
379
|
}, undefined, true, undefined, this),
|
|
535
|
-
/* @__PURE__ */
|
|
380
|
+
/* @__PURE__ */ jsxDEV3(XpBar2, {
|
|
536
381
|
current: progress.xpEarned,
|
|
537
382
|
max: totalXp,
|
|
538
383
|
showLabel: false,
|
|
539
384
|
size: "lg"
|
|
540
385
|
}, undefined, false, undefined, this),
|
|
541
|
-
track.completionRewards?.xpBonus && percentComplete < 100 && /* @__PURE__ */
|
|
386
|
+
track.completionRewards?.xpBonus && percentComplete < 100 && /* @__PURE__ */ jsxDEV3("p", {
|
|
542
387
|
className: "text-muted-foreground text-sm",
|
|
543
388
|
children: [
|
|
544
389
|
"\uD83C\uDF81 Complete all steps for a",
|
|
545
390
|
" ",
|
|
546
|
-
/* @__PURE__ */
|
|
391
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
547
392
|
className: "font-semibold text-green-500",
|
|
548
393
|
children: [
|
|
549
394
|
"+",
|
|
@@ -559,32 +404,32 @@ function Progress({ track, progress }) {
|
|
|
559
404
|
}, undefined, true, undefined, this)
|
|
560
405
|
]
|
|
561
406
|
}, undefined, true, undefined, this),
|
|
562
|
-
/* @__PURE__ */
|
|
407
|
+
/* @__PURE__ */ jsxDEV3(Card2, {
|
|
563
408
|
children: [
|
|
564
|
-
/* @__PURE__ */
|
|
565
|
-
children: /* @__PURE__ */
|
|
409
|
+
/* @__PURE__ */ jsxDEV3(CardHeader2, {
|
|
410
|
+
children: /* @__PURE__ */ jsxDEV3(CardTitle2, {
|
|
566
411
|
className: "flex items-center gap-2",
|
|
567
412
|
children: [
|
|
568
|
-
/* @__PURE__ */
|
|
413
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
569
414
|
children: "\uD83C\uDFAF"
|
|
570
415
|
}, undefined, false, undefined, this),
|
|
571
|
-
/* @__PURE__ */
|
|
416
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
572
417
|
children: "Skill Mastery"
|
|
573
418
|
}, undefined, false, undefined, this)
|
|
574
419
|
]
|
|
575
420
|
}, undefined, true, undefined, this)
|
|
576
421
|
}, undefined, false, undefined, this),
|
|
577
|
-
/* @__PURE__ */
|
|
578
|
-
children: /* @__PURE__ */
|
|
422
|
+
/* @__PURE__ */ jsxDEV3(CardContent2, {
|
|
423
|
+
children: /* @__PURE__ */ jsxDEV3("div", {
|
|
579
424
|
className: "flex flex-wrap justify-center gap-6",
|
|
580
425
|
children: [
|
|
581
|
-
Array.from(surfaces.entries()).map(([surface, data], index) => /* @__PURE__ */
|
|
426
|
+
Array.from(surfaces.entries()).map(([surface, data], index) => /* @__PURE__ */ jsxDEV3(MasteryRing, {
|
|
582
427
|
label: surface.charAt(0).toUpperCase() + surface.slice(1),
|
|
583
428
|
percentage: data.completed / data.total * 100,
|
|
584
429
|
color: surfaceColors[index % surfaceColors.length],
|
|
585
430
|
size: "lg"
|
|
586
431
|
}, surface, false, undefined, this)),
|
|
587
|
-
/* @__PURE__ */
|
|
432
|
+
/* @__PURE__ */ jsxDEV3(MasteryRing, {
|
|
588
433
|
label: "Overall",
|
|
589
434
|
percentage: percentComplete,
|
|
590
435
|
color: "violet",
|
|
@@ -595,29 +440,29 @@ function Progress({ track, progress }) {
|
|
|
595
440
|
}, undefined, false, undefined, this)
|
|
596
441
|
]
|
|
597
442
|
}, undefined, true, undefined, this),
|
|
598
|
-
/* @__PURE__ */
|
|
443
|
+
/* @__PURE__ */ jsxDEV3(Card2, {
|
|
599
444
|
children: [
|
|
600
|
-
/* @__PURE__ */
|
|
601
|
-
children: /* @__PURE__ */
|
|
445
|
+
/* @__PURE__ */ jsxDEV3(CardHeader2, {
|
|
446
|
+
children: /* @__PURE__ */ jsxDEV3(CardTitle2, {
|
|
602
447
|
className: "flex items-center gap-2",
|
|
603
448
|
children: [
|
|
604
|
-
/* @__PURE__ */
|
|
449
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
605
450
|
children: "\uD83C\uDFC5"
|
|
606
451
|
}, undefined, false, undefined, this),
|
|
607
|
-
/* @__PURE__ */
|
|
452
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
608
453
|
children: "Badges Earned"
|
|
609
454
|
}, undefined, false, undefined, this)
|
|
610
455
|
]
|
|
611
456
|
}, undefined, true, undefined, this)
|
|
612
457
|
}, undefined, false, undefined, this),
|
|
613
|
-
/* @__PURE__ */
|
|
458
|
+
/* @__PURE__ */ jsxDEV3(CardContent2, {
|
|
614
459
|
children: [
|
|
615
|
-
/* @__PURE__ */
|
|
460
|
+
/* @__PURE__ */ jsxDEV3(BadgeDisplay2, {
|
|
616
461
|
badges: progress.badges,
|
|
617
462
|
size: "lg",
|
|
618
463
|
maxVisible: 10
|
|
619
464
|
}, undefined, false, undefined, this),
|
|
620
|
-
progress.badges.length === 0 && /* @__PURE__ */
|
|
465
|
+
progress.badges.length === 0 && /* @__PURE__ */ jsxDEV3("p", {
|
|
621
466
|
className: "text-muted-foreground text-sm",
|
|
622
467
|
children: "Complete the track to earn your first badge!"
|
|
623
468
|
}, undefined, false, undefined, this)
|
|
@@ -625,44 +470,44 @@ function Progress({ track, progress }) {
|
|
|
625
470
|
}, undefined, true, undefined, this)
|
|
626
471
|
]
|
|
627
472
|
}, undefined, true, undefined, this),
|
|
628
|
-
/* @__PURE__ */
|
|
473
|
+
/* @__PURE__ */ jsxDEV3(Card2, {
|
|
629
474
|
children: [
|
|
630
|
-
/* @__PURE__ */
|
|
631
|
-
children: /* @__PURE__ */
|
|
475
|
+
/* @__PURE__ */ jsxDEV3(CardHeader2, {
|
|
476
|
+
children: /* @__PURE__ */ jsxDEV3(CardTitle2, {
|
|
632
477
|
className: "flex items-center gap-2",
|
|
633
478
|
children: [
|
|
634
|
-
/* @__PURE__ */
|
|
479
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
635
480
|
children: "\uD83D\uDCCA"
|
|
636
481
|
}, undefined, false, undefined, this),
|
|
637
|
-
/* @__PURE__ */
|
|
482
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
638
483
|
children: "Step Breakdown"
|
|
639
484
|
}, undefined, false, undefined, this)
|
|
640
485
|
]
|
|
641
486
|
}, undefined, true, undefined, this)
|
|
642
487
|
}, undefined, false, undefined, this),
|
|
643
|
-
/* @__PURE__ */
|
|
644
|
-
children: /* @__PURE__ */
|
|
488
|
+
/* @__PURE__ */ jsxDEV3(CardContent2, {
|
|
489
|
+
children: /* @__PURE__ */ jsxDEV3("div", {
|
|
645
490
|
className: "space-y-2",
|
|
646
491
|
children: track.steps.map((step) => {
|
|
647
492
|
const isCompleted = progress.completedStepIds.includes(step.id);
|
|
648
|
-
return /* @__PURE__ */
|
|
493
|
+
return /* @__PURE__ */ jsxDEV3("div", {
|
|
649
494
|
className: "flex items-center justify-between rounded-lg border p-3",
|
|
650
495
|
children: [
|
|
651
|
-
/* @__PURE__ */
|
|
496
|
+
/* @__PURE__ */ jsxDEV3("div", {
|
|
652
497
|
className: "flex items-center gap-3",
|
|
653
498
|
children: [
|
|
654
|
-
/* @__PURE__ */
|
|
499
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
655
500
|
className: isCompleted ? "text-green-500" : "text-muted-foreground",
|
|
656
501
|
children: isCompleted ? "\u2713" : "\u25CB"
|
|
657
502
|
}, undefined, false, undefined, this),
|
|
658
|
-
/* @__PURE__ */
|
|
503
|
+
/* @__PURE__ */ jsxDEV3("span", {
|
|
659
504
|
className: isCompleted ? "text-foreground" : "text-muted-foreground",
|
|
660
505
|
children: step.title
|
|
661
506
|
}, undefined, false, undefined, this)
|
|
662
507
|
]
|
|
663
508
|
}, undefined, true, undefined, this),
|
|
664
|
-
step.xpReward && /* @__PURE__ */
|
|
665
|
-
className: `text-sm
|
|
509
|
+
step.xpReward && /* @__PURE__ */ jsxDEV3("span", {
|
|
510
|
+
className: `font-medium text-sm ${isCompleted ? "text-green-500" : "text-muted-foreground"}`,
|
|
666
511
|
children: [
|
|
667
512
|
isCompleted ? "+" : "",
|
|
668
513
|
step.xpReward,
|
|
@@ -680,6 +525,161 @@ function Progress({ track, progress }) {
|
|
|
680
525
|
}, undefined, true, undefined, this);
|
|
681
526
|
}
|
|
682
527
|
|
|
528
|
+
// src/components/FlashCard.tsx
|
|
529
|
+
import { Button as Button2 } from "@contractspec/lib.design-system";
|
|
530
|
+
import { Card as Card3, CardContent as CardContent3 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
531
|
+
import { cn as cn2 } from "@contractspec/lib.ui-kit-web/ui/utils";
|
|
532
|
+
import { useState } from "react";
|
|
533
|
+
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
534
|
+
"use client";
|
|
535
|
+
function FlashCard({
|
|
536
|
+
step,
|
|
537
|
+
isCompleted,
|
|
538
|
+
isCurrent,
|
|
539
|
+
onComplete
|
|
540
|
+
}) {
|
|
541
|
+
const [isFlipped, setIsFlipped] = useState(false);
|
|
542
|
+
return /* @__PURE__ */ jsxDEV4(Card3, {
|
|
543
|
+
className: cn2("relative cursor-pointer overflow-hidden transition-all duration-300", isCurrent && "ring-2 ring-primary", isCompleted && "opacity-60"),
|
|
544
|
+
onClick: () => !isCompleted && setIsFlipped(!isFlipped),
|
|
545
|
+
children: /* @__PURE__ */ jsxDEV4(CardContent3, {
|
|
546
|
+
className: "p-6",
|
|
547
|
+
children: [
|
|
548
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
549
|
+
className: cn2("space-y-4 transition-opacity duration-200", isFlipped ? "opacity-0" : "opacity-100"),
|
|
550
|
+
children: [
|
|
551
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
552
|
+
className: "flex items-start justify-between",
|
|
553
|
+
children: [
|
|
554
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
555
|
+
className: "flex-1",
|
|
556
|
+
children: [
|
|
557
|
+
/* @__PURE__ */ jsxDEV4("h3", {
|
|
558
|
+
className: "font-semibold text-lg",
|
|
559
|
+
children: step.title
|
|
560
|
+
}, undefined, false, undefined, this),
|
|
561
|
+
step.description && /* @__PURE__ */ jsxDEV4("p", {
|
|
562
|
+
className: "mt-1 text-muted-foreground text-sm",
|
|
563
|
+
children: step.description
|
|
564
|
+
}, undefined, false, undefined, this)
|
|
565
|
+
]
|
|
566
|
+
}, undefined, true, undefined, this),
|
|
567
|
+
step.xpReward && /* @__PURE__ */ jsxDEV4("span", {
|
|
568
|
+
className: "rounded-full bg-green-500/10 px-2 py-1 font-semibold text-green-500 text-xs",
|
|
569
|
+
children: [
|
|
570
|
+
"+",
|
|
571
|
+
step.xpReward,
|
|
572
|
+
" XP"
|
|
573
|
+
]
|
|
574
|
+
}, undefined, true, undefined, this)
|
|
575
|
+
]
|
|
576
|
+
}, undefined, true, undefined, this),
|
|
577
|
+
isCompleted && /* @__PURE__ */ jsxDEV4("div", {
|
|
578
|
+
className: "flex items-center gap-2 text-green-500",
|
|
579
|
+
children: [
|
|
580
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
581
|
+
children: "\u2713"
|
|
582
|
+
}, undefined, false, undefined, this),
|
|
583
|
+
/* @__PURE__ */ jsxDEV4("span", {
|
|
584
|
+
className: "font-medium text-sm",
|
|
585
|
+
children: "Completed"
|
|
586
|
+
}, undefined, false, undefined, this)
|
|
587
|
+
]
|
|
588
|
+
}, undefined, true, undefined, this),
|
|
589
|
+
isCurrent && !isCompleted && /* @__PURE__ */ jsxDEV4("p", {
|
|
590
|
+
className: "text-muted-foreground text-xs",
|
|
591
|
+
children: "Tap to reveal action"
|
|
592
|
+
}, undefined, false, undefined, this)
|
|
593
|
+
]
|
|
594
|
+
}, undefined, true, undefined, this),
|
|
595
|
+
isFlipped && !isCompleted && /* @__PURE__ */ jsxDEV4("div", {
|
|
596
|
+
className: "absolute inset-0 flex flex-col items-center justify-center gap-4 bg-gradient-to-br from-violet-500/10 to-violet-600/10 p-6",
|
|
597
|
+
children: [
|
|
598
|
+
/* @__PURE__ */ jsxDEV4("p", {
|
|
599
|
+
className: "text-center text-sm",
|
|
600
|
+
children: step.instructions ?? "Complete this step to earn XP"
|
|
601
|
+
}, undefined, false, undefined, this),
|
|
602
|
+
/* @__PURE__ */ jsxDEV4("div", {
|
|
603
|
+
className: "flex gap-2",
|
|
604
|
+
children: [
|
|
605
|
+
/* @__PURE__ */ jsxDEV4(Button2, {
|
|
606
|
+
variant: "outline",
|
|
607
|
+
size: "sm",
|
|
608
|
+
onClick: () => setIsFlipped(false),
|
|
609
|
+
children: "Back"
|
|
610
|
+
}, undefined, false, undefined, this),
|
|
611
|
+
/* @__PURE__ */ jsxDEV4(Button2, {
|
|
612
|
+
size: "sm",
|
|
613
|
+
onClick: (e) => {
|
|
614
|
+
e.stopPropagation();
|
|
615
|
+
onComplete?.();
|
|
616
|
+
},
|
|
617
|
+
children: "Mark Complete"
|
|
618
|
+
}, undefined, false, undefined, this)
|
|
619
|
+
]
|
|
620
|
+
}, undefined, true, undefined, this)
|
|
621
|
+
]
|
|
622
|
+
}, undefined, true, undefined, this)
|
|
623
|
+
]
|
|
624
|
+
}, undefined, true, undefined, this)
|
|
625
|
+
}, undefined, false, undefined, this);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
// src/views/Steps.tsx
|
|
629
|
+
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
630
|
+
"use client";
|
|
631
|
+
function Steps({ track, progress, onStepComplete }) {
|
|
632
|
+
const currentStepIndex = track.steps.findIndex((s) => !progress.completedStepIds.includes(s.id));
|
|
633
|
+
return /* @__PURE__ */ jsxDEV5("div", {
|
|
634
|
+
className: "space-y-6",
|
|
635
|
+
children: [
|
|
636
|
+
/* @__PURE__ */ jsxDEV5("div", {
|
|
637
|
+
className: "text-center",
|
|
638
|
+
children: [
|
|
639
|
+
/* @__PURE__ */ jsxDEV5("h2", {
|
|
640
|
+
className: "font-bold text-xl",
|
|
641
|
+
children: "Complete Your Challenges"
|
|
642
|
+
}, undefined, false, undefined, this),
|
|
643
|
+
/* @__PURE__ */ jsxDEV5("p", {
|
|
644
|
+
className: "text-muted-foreground",
|
|
645
|
+
children: "Tap each card to reveal the action, then mark as complete"
|
|
646
|
+
}, undefined, false, undefined, this)
|
|
647
|
+
]
|
|
648
|
+
}, undefined, true, undefined, this),
|
|
649
|
+
/* @__PURE__ */ jsxDEV5("div", {
|
|
650
|
+
className: "grid gap-4 md:grid-cols-2",
|
|
651
|
+
children: track.steps.map((step, index) => {
|
|
652
|
+
const isCompleted = progress.completedStepIds.includes(step.id);
|
|
653
|
+
const isCurrent = index === currentStepIndex;
|
|
654
|
+
return /* @__PURE__ */ jsxDEV5(FlashCard, {
|
|
655
|
+
step,
|
|
656
|
+
isCompleted,
|
|
657
|
+
isCurrent,
|
|
658
|
+
onComplete: () => onStepComplete?.(step.id)
|
|
659
|
+
}, step.id, false, undefined, this);
|
|
660
|
+
})
|
|
661
|
+
}, undefined, false, undefined, this),
|
|
662
|
+
/* @__PURE__ */ jsxDEV5("div", {
|
|
663
|
+
className: "text-center text-muted-foreground text-sm",
|
|
664
|
+
children: [
|
|
665
|
+
progress.completedStepIds.length,
|
|
666
|
+
" of ",
|
|
667
|
+
track.steps.length,
|
|
668
|
+
" completed",
|
|
669
|
+
track.completionRewards?.xpBonus && /* @__PURE__ */ jsxDEV5("span", {
|
|
670
|
+
className: "ml-2 text-green-500",
|
|
671
|
+
children: [
|
|
672
|
+
"(+",
|
|
673
|
+
track.completionRewards.xpBonus,
|
|
674
|
+
" XP bonus on completion)"
|
|
675
|
+
]
|
|
676
|
+
}, undefined, true, undefined, this)
|
|
677
|
+
]
|
|
678
|
+
}, undefined, true, undefined, this)
|
|
679
|
+
]
|
|
680
|
+
}, undefined, true, undefined, this);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
683
|
// src/components/DayCalendar.tsx
|
|
684
684
|
import { cn as cn3 } from "@contractspec/lib.ui-kit-web/ui/utils";
|
|
685
685
|
import { jsxDEV as jsxDEV6, Fragment } from "react/jsx-dev-runtime";
|
|
@@ -697,7 +697,7 @@ function DayCalendar({
|
|
|
697
697
|
const isCurrent = day === currentDay;
|
|
698
698
|
const isLocked = day > currentDay;
|
|
699
699
|
return /* @__PURE__ */ jsxDEV6("div", {
|
|
700
|
-
className: cn3("flex h-12 w-12 flex-col items-center justify-center rounded-lg border text-sm
|
|
700
|
+
className: cn3("flex h-12 w-12 flex-col items-center justify-center rounded-lg border font-medium text-sm transition-all", isCompleted && "border-green-500 bg-green-500/10 text-green-500", isCurrent && !isCompleted && "border-violet-500 bg-violet-500/10 text-violet-500 ring-2 ring-violet-500/50", isLocked && "border-muted bg-muted/50 text-muted-foreground", !isCompleted && !isCurrent && !isLocked && "border-border bg-card"),
|
|
701
701
|
children: isCompleted ? /* @__PURE__ */ jsxDEV6("span", {
|
|
702
702
|
className: "text-lg",
|
|
703
703
|
children: "\u2713"
|
|
@@ -742,7 +742,7 @@ function Timeline({ track, progress }) {
|
|
|
742
742
|
className: "text-center",
|
|
743
743
|
children: [
|
|
744
744
|
/* @__PURE__ */ jsxDEV7("h2", {
|
|
745
|
-
className: "text-xl
|
|
745
|
+
className: "font-bold text-xl",
|
|
746
746
|
children: track.name
|
|
747
747
|
}, undefined, false, undefined, this),
|
|
748
748
|
/* @__PURE__ */ jsxDEV7("p", {
|
|
@@ -802,7 +802,7 @@ function Timeline({ track, progress }) {
|
|
|
802
802
|
className: `flex items-start gap-4 rounded-lg border p-4 ${isLocked ? "opacity-50" : ""}`,
|
|
803
803
|
children: [
|
|
804
804
|
/* @__PURE__ */ jsxDEV7("div", {
|
|
805
|
-
className: "
|
|
805
|
+
className: "flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-muted font-semibold",
|
|
806
806
|
children: isCompleted ? "\u2713" : isLocked ? "\uD83D\uDD12" : day
|
|
807
807
|
}, undefined, false, undefined, this),
|
|
808
808
|
/* @__PURE__ */ jsxDEV7("div", {
|
|
@@ -819,7 +819,7 @@ function Timeline({ track, progress }) {
|
|
|
819
819
|
]
|
|
820
820
|
}, undefined, true, undefined, this),
|
|
821
821
|
step.xpReward && /* @__PURE__ */ jsxDEV7("span", {
|
|
822
|
-
className: `text-sm
|
|
822
|
+
className: `font-medium text-sm ${isCompleted ? "text-green-500" : "text-muted-foreground"}`,
|
|
823
823
|
children: [
|
|
824
824
|
"+",
|
|
825
825
|
step.xpReward,
|
|
@@ -843,7 +843,7 @@ function Timeline({ track, progress }) {
|
|
|
843
843
|
className: "text-center",
|
|
844
844
|
children: [
|
|
845
845
|
/* @__PURE__ */ jsxDEV7("h2", {
|
|
846
|
-
className: "text-xl
|
|
846
|
+
className: "font-bold text-xl",
|
|
847
847
|
children: "Learning Path"
|
|
848
848
|
}, undefined, false, undefined, this),
|
|
849
849
|
/* @__PURE__ */ jsxDEV7("p", {
|
|
@@ -859,7 +859,7 @@ function Timeline({ track, progress }) {
|
|
|
859
859
|
className: "relative",
|
|
860
860
|
children: [
|
|
861
861
|
/* @__PURE__ */ jsxDEV7("div", {
|
|
862
|
-
className: "
|
|
862
|
+
className: "absolute top-0 left-5 h-full w-0.5 bg-border"
|
|
863
863
|
}, undefined, false, undefined, this),
|
|
864
864
|
/* @__PURE__ */ jsxDEV7("div", {
|
|
865
865
|
className: "space-y-6",
|
|
@@ -885,13 +885,13 @@ function Timeline({ track, progress }) {
|
|
|
885
885
|
children: step.title
|
|
886
886
|
}, undefined, false, undefined, this),
|
|
887
887
|
/* @__PURE__ */ jsxDEV7("p", {
|
|
888
|
-
className: "text-muted-foreground
|
|
888
|
+
className: "mt-1 text-muted-foreground text-sm",
|
|
889
889
|
children: step.description
|
|
890
890
|
}, undefined, false, undefined, this)
|
|
891
891
|
]
|
|
892
892
|
}, undefined, true, undefined, this),
|
|
893
893
|
step.xpReward && /* @__PURE__ */ jsxDEV7("span", {
|
|
894
|
-
className: `shrink-0 rounded-full px-2 py-1 text-xs
|
|
894
|
+
className: `shrink-0 rounded-full px-2 py-1 font-semibold text-xs ${isCompleted ? "bg-green-500/10 text-green-500" : "bg-muted text-muted-foreground"}`,
|
|
895
895
|
children: [
|
|
896
896
|
"+",
|
|
897
897
|
step.xpReward,
|
|
@@ -914,12 +914,12 @@ function Timeline({ track, progress }) {
|
|
|
914
914
|
}
|
|
915
915
|
|
|
916
916
|
// src/GamifiedMiniApp.tsx
|
|
917
|
-
import { useState as useState2, useCallback } from "react";
|
|
918
|
-
import { Card as Card5, CardContent as CardContent5 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
919
917
|
import {
|
|
920
|
-
|
|
921
|
-
|
|
918
|
+
useLearningProgress,
|
|
919
|
+
ViewTabs
|
|
922
920
|
} from "@contractspec/example.learning-journey-ui-shared";
|
|
921
|
+
import { Card as Card5, CardContent as CardContent5 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
922
|
+
import { useCallback, useState as useState2 } from "react";
|
|
923
923
|
import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
|
|
924
924
|
"use client";
|
|
925
925
|
function GamifiedMiniApp({
|
|
@@ -1045,6 +1045,7 @@ var example = defineExample({
|
|
|
1045
1045
|
}
|
|
1046
1046
|
});
|
|
1047
1047
|
var example_default = example;
|
|
1048
|
+
|
|
1048
1049
|
// src/learning-journey-ui-gamified.feature.ts
|
|
1049
1050
|
import { defineFeature } from "@contractspec/lib.contracts-spec";
|
|
1050
1051
|
var LearningJourneyUiGamifiedFeature = defineFeature({
|