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