@contractspec/example.learning-journey-ui-coaching 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 -59
  2. package/.turbo/turbo-prebuild.log +1 -0
  3. package/CHANGELOG.md +18 -0
  4. package/dist/CoachingMiniApp.d.ts +4 -14
  5. package/dist/CoachingMiniApp.d.ts.map +1 -1
  6. package/dist/CoachingMiniApp.js +1056 -59
  7. package/dist/browser/CoachingMiniApp.js +1059 -0
  8. package/dist/browser/components/EngagementMeter.js +143 -0
  9. package/dist/browser/components/TipCard.js +89 -0
  10. package/dist/browser/components/TipFeed.js +90 -0
  11. package/dist/browser/components/index.js +320 -0
  12. package/dist/browser/docs/index.js +22 -0
  13. package/dist/browser/docs/learning-journey-ui-coaching.docblock.js +22 -0
  14. package/dist/browser/example.js +32 -0
  15. package/dist/browser/index.js +1118 -0
  16. package/dist/browser/views/Overview.js +303 -0
  17. package/dist/browser/views/Progress.js +344 -0
  18. package/dist/browser/views/Steps.js +159 -0
  19. package/dist/browser/views/Timeline.js +266 -0
  20. package/dist/browser/views/index.js +980 -0
  21. package/dist/components/EngagementMeter.d.ts +6 -15
  22. package/dist/components/EngagementMeter.d.ts.map +1 -1
  23. package/dist/components/EngagementMeter.js +143 -107
  24. package/dist/components/TipCard.d.ts +8 -18
  25. package/dist/components/TipCard.d.ts.map +1 -1
  26. package/dist/components/TipCard.js +86 -72
  27. package/dist/components/TipFeed.d.ts +7 -13
  28. package/dist/components/TipFeed.d.ts.map +1 -1
  29. package/dist/components/TipFeed.js +87 -62
  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 +320 -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-coaching.docblock.d.ts +2 -1
  37. package/dist/docs/learning-journey-ui-coaching.docblock.d.ts.map +1 -0
  38. package/dist/docs/learning-journey-ui-coaching.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 +1119 -14
  45. package/dist/node/CoachingMiniApp.js +1059 -0
  46. package/dist/node/components/EngagementMeter.js +143 -0
  47. package/dist/node/components/TipCard.js +89 -0
  48. package/dist/node/components/TipFeed.js +90 -0
  49. package/dist/node/components/index.js +320 -0
  50. package/dist/node/docs/index.js +22 -0
  51. package/dist/node/docs/learning-journey-ui-coaching.docblock.js +22 -0
  52. package/dist/node/example.js +32 -0
  53. package/dist/node/index.js +1118 -0
  54. package/dist/node/views/Overview.js +303 -0
  55. package/dist/node/views/Progress.js +344 -0
  56. package/dist/node/views/Steps.js +159 -0
  57. package/dist/node/views/Timeline.js +266 -0
  58. package/dist/node/views/index.js +980 -0
  59. package/dist/views/Overview.d.ts +4 -13
  60. package/dist/views/Overview.d.ts.map +1 -1
  61. package/dist/views/Overview.js +301 -148
  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 +342 -112
  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 +157 -66
  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 +264 -110
  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 +980 -5
  74. package/package.json +154 -38
  75. package/tsdown.config.js +1 -2
  76. package/.turbo/turbo-build$colon$bundle.log +0 -62
  77. package/dist/CoachingMiniApp.js.map +0 -1
  78. package/dist/components/EngagementMeter.js.map +0 -1
  79. package/dist/components/TipCard.js.map +0 -1
  80. package/dist/components/TipFeed.js.map +0 -1
  81. package/dist/docs/learning-journey-ui-coaching.docblock.js.map +0 -1
  82. package/dist/example.js.map +0 -1
  83. package/dist/views/Overview.js.map +0 -1
  84. package/dist/views/Progress.js.map +0 -1
  85. package/dist/views/Steps.js.map +0 -1
  86. package/dist/views/Timeline.js.map +0 -1
  87. package/tsconfig.tsbuildinfo +0 -1
@@ -0,0 +1,303 @@
1
+ // src/components/TipCard.tsx
2
+ import { Button } from "@contractspec/lib.design-system";
3
+ import { Card, CardContent } from "@contractspec/lib.ui-kit-web/ui/card";
4
+ import { cn } from "@contractspec/lib.ui-kit-web/ui/utils";
5
+ import { jsxDEV } from "react/jsx-dev-runtime";
6
+ "use client";
7
+ var TIP_ICONS = {
8
+ cash_buffer_too_high: "\uD83D\uDCB0",
9
+ no_savings_goal: "\uD83C\uDFAF",
10
+ irregular_savings: "\uD83D\uDCC5",
11
+ noise_late_evening: "\uD83D\uDD07",
12
+ guest_frequency_high: "\uD83D\uDC65",
13
+ shared_space_conflicts: "\uD83C\uDFE0",
14
+ default: "\uD83D\uDCA1"
15
+ };
16
+ function TipCard({
17
+ step,
18
+ isCompleted,
19
+ isCurrent,
20
+ onComplete,
21
+ onDismiss
22
+ }) {
23
+ const tipId = step.metadata?.tipId ?? "default";
24
+ const icon = TIP_ICONS[tipId] ?? TIP_ICONS.default;
25
+ return /* @__PURE__ */ jsxDEV(Card, {
26
+ className: cn("transition-all", isCompleted && "opacity-60", isCurrent && "ring-2 ring-amber-500"),
27
+ children: /* @__PURE__ */ jsxDEV(CardContent, {
28
+ className: "p-4",
29
+ children: /* @__PURE__ */ jsxDEV("div", {
30
+ className: "flex gap-4",
31
+ children: [
32
+ /* @__PURE__ */ jsxDEV("div", {
33
+ className: cn("flex h-12 w-12 shrink-0 items-center justify-center rounded-xl text-2xl", isCompleted ? "bg-green-500/10" : isCurrent ? "bg-amber-500/10" : "bg-muted"),
34
+ children: isCompleted ? "✓" : icon
35
+ }, undefined, false, undefined, this),
36
+ /* @__PURE__ */ jsxDEV("div", {
37
+ className: "min-w-0 flex-1",
38
+ children: [
39
+ /* @__PURE__ */ jsxDEV("div", {
40
+ className: "flex items-start justify-between gap-2",
41
+ children: [
42
+ /* @__PURE__ */ jsxDEV("h4", {
43
+ className: "font-semibold",
44
+ children: step.title
45
+ }, undefined, false, undefined, this),
46
+ step.xpReward && /* @__PURE__ */ jsxDEV("span", {
47
+ className: cn("shrink-0 rounded-full px-2 py-0.5 text-xs font-semibold", isCompleted ? "bg-green-500/10 text-green-500" : "bg-amber-500/10 text-amber-500"),
48
+ children: [
49
+ "+",
50
+ step.xpReward,
51
+ " XP"
52
+ ]
53
+ }, undefined, true, undefined, this)
54
+ ]
55
+ }, undefined, true, undefined, this),
56
+ /* @__PURE__ */ jsxDEV("p", {
57
+ className: "text-muted-foreground mt-1 text-sm",
58
+ children: step.description
59
+ }, undefined, false, undefined, this),
60
+ !isCompleted && /* @__PURE__ */ jsxDEV("div", {
61
+ className: "mt-3 flex flex-wrap gap-2",
62
+ children: [
63
+ /* @__PURE__ */ jsxDEV(Button, {
64
+ size: "sm",
65
+ onClick: onComplete,
66
+ children: "Take Action"
67
+ }, undefined, false, undefined, this),
68
+ /* @__PURE__ */ jsxDEV(Button, {
69
+ variant: "outline",
70
+ size: "sm",
71
+ onClick: onDismiss,
72
+ children: "Dismiss"
73
+ }, undefined, false, undefined, this)
74
+ ]
75
+ }, undefined, true, undefined, this),
76
+ isCompleted && /* @__PURE__ */ jsxDEV("p", {
77
+ className: "mt-2 text-sm text-green-500",
78
+ children: "✓ Tip acknowledged"
79
+ }, undefined, false, undefined, this)
80
+ ]
81
+ }, undefined, true, undefined, this)
82
+ ]
83
+ }, undefined, true, undefined, this)
84
+ }, undefined, false, undefined, this)
85
+ }, undefined, false, undefined, this);
86
+ }
87
+
88
+ // src/views/Overview.tsx
89
+ import { Button as Button2 } from "@contractspec/lib.design-system";
90
+ import {
91
+ Card as Card2,
92
+ CardContent as CardContent2,
93
+ CardHeader,
94
+ CardTitle
95
+ } from "@contractspec/lib.ui-kit-web/ui/card";
96
+ import {
97
+ XpBar,
98
+ StreakCounter
99
+ } from "@contractspec/example.learning-journey-ui-shared";
100
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
101
+ "use client";
102
+ function Overview({
103
+ track,
104
+ progress,
105
+ onStepComplete,
106
+ onStart
107
+ }) {
108
+ const totalXp = track.totalXp ?? track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0);
109
+ const completedSteps = progress.completedStepIds.length;
110
+ const totalSteps = track.steps.length;
111
+ const pendingSteps = totalSteps - completedSteps;
112
+ const activeTips = track.steps.filter((s) => !progress.completedStepIds.includes(s.id)).slice(0, 3);
113
+ return /* @__PURE__ */ jsxDEV2("div", {
114
+ className: "space-y-6",
115
+ children: [
116
+ /* @__PURE__ */ jsxDEV2(Card2, {
117
+ className: "overflow-hidden bg-gradient-to-br from-amber-500/10 via-orange-500/10 to-red-500/10",
118
+ children: /* @__PURE__ */ jsxDEV2(CardContent2, {
119
+ className: "p-6",
120
+ children: /* @__PURE__ */ jsxDEV2("div", {
121
+ className: "flex flex-col items-center gap-4 text-center md:flex-row md:text-left",
122
+ children: [
123
+ /* @__PURE__ */ jsxDEV2("div", {
124
+ className: "flex h-16 w-16 items-center justify-center rounded-2xl bg-gradient-to-br from-amber-500 to-orange-600 text-3xl shadow-lg",
125
+ children: "\uD83D\uDCA1"
126
+ }, undefined, false, undefined, this),
127
+ /* @__PURE__ */ jsxDEV2("div", {
128
+ className: "flex-1",
129
+ children: [
130
+ /* @__PURE__ */ jsxDEV2("h1", {
131
+ className: "text-2xl font-bold",
132
+ children: track.name
133
+ }, undefined, false, undefined, this),
134
+ /* @__PURE__ */ jsxDEV2("p", {
135
+ className: "text-muted-foreground mt-1",
136
+ children: track.description
137
+ }, undefined, false, undefined, this)
138
+ ]
139
+ }, undefined, true, undefined, this),
140
+ /* @__PURE__ */ jsxDEV2("div", {
141
+ className: "flex items-center gap-4",
142
+ children: /* @__PURE__ */ jsxDEV2(StreakCounter, {
143
+ days: progress.streakDays,
144
+ size: "lg"
145
+ }, undefined, false, undefined, this)
146
+ }, undefined, false, undefined, this)
147
+ ]
148
+ }, undefined, true, undefined, this)
149
+ }, undefined, false, undefined, this)
150
+ }, undefined, false, undefined, this),
151
+ /* @__PURE__ */ jsxDEV2("div", {
152
+ className: "grid gap-4 md:grid-cols-3",
153
+ children: [
154
+ /* @__PURE__ */ jsxDEV2(Card2, {
155
+ children: [
156
+ /* @__PURE__ */ jsxDEV2(CardHeader, {
157
+ className: "pb-2",
158
+ children: /* @__PURE__ */ jsxDEV2(CardTitle, {
159
+ className: "text-muted-foreground text-sm font-medium",
160
+ children: "Active Tips"
161
+ }, undefined, false, undefined, this)
162
+ }, undefined, false, undefined, this),
163
+ /* @__PURE__ */ jsxDEV2(CardContent2, {
164
+ children: [
165
+ /* @__PURE__ */ jsxDEV2("div", {
166
+ className: "text-3xl font-bold text-amber-500",
167
+ children: pendingSteps
168
+ }, undefined, false, undefined, this),
169
+ /* @__PURE__ */ jsxDEV2("p", {
170
+ className: "text-muted-foreground text-sm",
171
+ children: "tips for you today"
172
+ }, undefined, false, undefined, this)
173
+ ]
174
+ }, undefined, true, undefined, this)
175
+ ]
176
+ }, undefined, true, undefined, this),
177
+ /* @__PURE__ */ jsxDEV2(Card2, {
178
+ children: [
179
+ /* @__PURE__ */ jsxDEV2(CardHeader, {
180
+ className: "pb-2",
181
+ children: /* @__PURE__ */ jsxDEV2(CardTitle, {
182
+ className: "text-muted-foreground text-sm font-medium",
183
+ children: "Tips Actioned"
184
+ }, undefined, false, undefined, this)
185
+ }, undefined, false, undefined, this),
186
+ /* @__PURE__ */ jsxDEV2(CardContent2, {
187
+ children: [
188
+ /* @__PURE__ */ jsxDEV2("div", {
189
+ className: "text-3xl font-bold text-green-500",
190
+ children: completedSteps
191
+ }, undefined, false, undefined, this),
192
+ /* @__PURE__ */ jsxDEV2("p", {
193
+ className: "text-muted-foreground text-sm",
194
+ children: [
195
+ "out of ",
196
+ totalSteps,
197
+ " total"
198
+ ]
199
+ }, undefined, true, undefined, this)
200
+ ]
201
+ }, undefined, true, undefined, this)
202
+ ]
203
+ }, undefined, true, undefined, this),
204
+ /* @__PURE__ */ jsxDEV2(Card2, {
205
+ children: [
206
+ /* @__PURE__ */ jsxDEV2(CardHeader, {
207
+ className: "pb-2",
208
+ children: /* @__PURE__ */ jsxDEV2(CardTitle, {
209
+ className: "text-muted-foreground text-sm font-medium",
210
+ children: "XP Earned"
211
+ }, undefined, false, undefined, this)
212
+ }, undefined, false, undefined, this),
213
+ /* @__PURE__ */ jsxDEV2(CardContent2, {
214
+ children: [
215
+ /* @__PURE__ */ jsxDEV2("div", {
216
+ className: "text-3xl font-bold text-orange-500",
217
+ children: progress.xpEarned
218
+ }, undefined, false, undefined, this),
219
+ /* @__PURE__ */ jsxDEV2(XpBar, {
220
+ current: progress.xpEarned,
221
+ max: totalXp,
222
+ showLabel: false,
223
+ size: "sm"
224
+ }, undefined, false, undefined, this)
225
+ ]
226
+ }, undefined, true, undefined, this)
227
+ ]
228
+ }, undefined, true, undefined, this)
229
+ ]
230
+ }, undefined, true, undefined, this),
231
+ activeTips.length > 0 && /* @__PURE__ */ jsxDEV2(Card2, {
232
+ children: [
233
+ /* @__PURE__ */ jsxDEV2(CardHeader, {
234
+ className: "flex flex-row items-center justify-between",
235
+ children: [
236
+ /* @__PURE__ */ jsxDEV2(CardTitle, {
237
+ className: "flex items-center gap-2",
238
+ children: [
239
+ /* @__PURE__ */ jsxDEV2("span", {
240
+ children: "\uD83D\uDCA1"
241
+ }, undefined, false, undefined, this),
242
+ /* @__PURE__ */ jsxDEV2("span", {
243
+ children: "Tips for You"
244
+ }, undefined, false, undefined, this)
245
+ ]
246
+ }, undefined, true, undefined, this),
247
+ activeTips.length < pendingSteps && /* @__PURE__ */ jsxDEV2(Button2, {
248
+ variant: "outline",
249
+ size: "sm",
250
+ onClick: onStart,
251
+ children: [
252
+ "View All (",
253
+ pendingSteps,
254
+ ")"
255
+ ]
256
+ }, undefined, true, undefined, this)
257
+ ]
258
+ }, undefined, true, undefined, this),
259
+ /* @__PURE__ */ jsxDEV2(CardContent2, {
260
+ className: "space-y-3",
261
+ children: activeTips.map((step) => /* @__PURE__ */ jsxDEV2(TipCard, {
262
+ step,
263
+ isCompleted: false,
264
+ isCurrent: step.id === activeTips[0]?.id,
265
+ onComplete: () => onStepComplete?.(step.id)
266
+ }, step.id, false, undefined, this))
267
+ }, undefined, false, undefined, this)
268
+ ]
269
+ }, undefined, true, undefined, this),
270
+ pendingSteps === 0 && /* @__PURE__ */ jsxDEV2(Card2, {
271
+ className: "border-green-500/50 bg-green-500/5",
272
+ children: /* @__PURE__ */ jsxDEV2(CardContent2, {
273
+ className: "flex items-center gap-4 p-6",
274
+ children: [
275
+ /* @__PURE__ */ jsxDEV2("div", {
276
+ className: "text-4xl",
277
+ children: "\uD83C\uDF89"
278
+ }, undefined, false, undefined, this),
279
+ /* @__PURE__ */ jsxDEV2("div", {
280
+ children: [
281
+ /* @__PURE__ */ jsxDEV2("h3", {
282
+ className: "text-lg font-semibold text-green-500",
283
+ children: "All Tips Actioned!"
284
+ }, undefined, false, undefined, this),
285
+ /* @__PURE__ */ jsxDEV2("p", {
286
+ className: "text-muted-foreground",
287
+ children: [
288
+ "Great job! You've addressed all ",
289
+ totalSteps,
290
+ " coaching tips."
291
+ ]
292
+ }, undefined, true, undefined, this)
293
+ ]
294
+ }, undefined, true, undefined, this)
295
+ ]
296
+ }, undefined, true, undefined, this)
297
+ }, undefined, false, undefined, this)
298
+ ]
299
+ }, undefined, true, undefined, this);
300
+ }
301
+ export {
302
+ Overview
303
+ };
@@ -0,0 +1,344 @@
1
+ // src/components/EngagementMeter.tsx
2
+ import { jsxDEV } from "react/jsx-dev-runtime";
3
+ "use client";
4
+ function EngagementMeter({
5
+ acknowledged,
6
+ actioned,
7
+ pending,
8
+ streak = 0
9
+ }) {
10
+ const total = acknowledged + actioned + pending;
11
+ const actionedPercent = total > 0 ? actioned / total * 100 : 0;
12
+ const acknowledgedPercent = total > 0 ? acknowledged / total * 100 : 0;
13
+ return /* @__PURE__ */ jsxDEV("div", {
14
+ className: "space-y-4",
15
+ children: [
16
+ /* @__PURE__ */ jsxDEV("div", {
17
+ className: "flex items-center justify-center",
18
+ children: /* @__PURE__ */ jsxDEV("div", {
19
+ className: "relative h-32 w-32",
20
+ children: [
21
+ /* @__PURE__ */ jsxDEV("svg", {
22
+ className: "h-full w-full -rotate-90",
23
+ viewBox: "0 0 100 100",
24
+ children: [
25
+ /* @__PURE__ */ jsxDEV("circle", {
26
+ cx: "50",
27
+ cy: "50",
28
+ r: "40",
29
+ fill: "none",
30
+ strokeWidth: "12",
31
+ className: "stroke-muted"
32
+ }, undefined, false, undefined, this),
33
+ /* @__PURE__ */ jsxDEV("circle", {
34
+ cx: "50",
35
+ cy: "50",
36
+ r: "40",
37
+ fill: "none",
38
+ strokeWidth: "12",
39
+ strokeLinecap: "round",
40
+ strokeDasharray: `${actionedPercent * 2.51} 251`,
41
+ className: "stroke-green-500 transition-all duration-500"
42
+ }, undefined, false, undefined, this),
43
+ /* @__PURE__ */ jsxDEV("circle", {
44
+ cx: "50",
45
+ cy: "50",
46
+ r: "40",
47
+ fill: "none",
48
+ strokeWidth: "12",
49
+ strokeLinecap: "round",
50
+ strokeDasharray: `${acknowledgedPercent * 2.51} 251`,
51
+ strokeDashoffset: `${-actionedPercent * 2.51}`,
52
+ className: "stroke-amber-500 transition-all duration-500"
53
+ }, undefined, false, undefined, this)
54
+ ]
55
+ }, undefined, true, undefined, this),
56
+ /* @__PURE__ */ jsxDEV("div", {
57
+ className: "absolute inset-0 flex flex-col items-center justify-center",
58
+ children: [
59
+ /* @__PURE__ */ jsxDEV("span", {
60
+ className: "text-2xl font-bold",
61
+ children: total
62
+ }, undefined, false, undefined, this),
63
+ /* @__PURE__ */ jsxDEV("span", {
64
+ className: "text-muted-foreground text-xs",
65
+ children: "tips"
66
+ }, undefined, false, undefined, this)
67
+ ]
68
+ }, undefined, true, undefined, this)
69
+ ]
70
+ }, undefined, true, undefined, this)
71
+ }, undefined, false, undefined, this),
72
+ /* @__PURE__ */ jsxDEV("div", {
73
+ className: "flex justify-center gap-4 text-sm",
74
+ children: [
75
+ /* @__PURE__ */ jsxDEV("div", {
76
+ className: "flex items-center gap-1.5",
77
+ children: [
78
+ /* @__PURE__ */ jsxDEV("div", {
79
+ className: "h-3 w-3 rounded-full bg-green-500"
80
+ }, undefined, false, undefined, this),
81
+ /* @__PURE__ */ jsxDEV("span", {
82
+ children: [
83
+ "Actioned (",
84
+ actioned,
85
+ ")"
86
+ ]
87
+ }, undefined, true, undefined, this)
88
+ ]
89
+ }, undefined, true, undefined, this),
90
+ /* @__PURE__ */ jsxDEV("div", {
91
+ className: "flex items-center gap-1.5",
92
+ children: [
93
+ /* @__PURE__ */ jsxDEV("div", {
94
+ className: "h-3 w-3 rounded-full bg-amber-500"
95
+ }, undefined, false, undefined, this),
96
+ /* @__PURE__ */ jsxDEV("span", {
97
+ children: [
98
+ "Acknowledged (",
99
+ acknowledged,
100
+ ")"
101
+ ]
102
+ }, undefined, true, undefined, this)
103
+ ]
104
+ }, undefined, true, undefined, this),
105
+ /* @__PURE__ */ jsxDEV("div", {
106
+ className: "flex items-center gap-1.5",
107
+ children: [
108
+ /* @__PURE__ */ jsxDEV("div", {
109
+ className: "bg-muted h-3 w-3 rounded-full"
110
+ }, undefined, false, undefined, this),
111
+ /* @__PURE__ */ jsxDEV("span", {
112
+ children: [
113
+ "Pending (",
114
+ pending,
115
+ ")"
116
+ ]
117
+ }, undefined, true, undefined, this)
118
+ ]
119
+ }, undefined, true, undefined, this)
120
+ ]
121
+ }, undefined, true, undefined, this),
122
+ streak > 0 && /* @__PURE__ */ jsxDEV("div", {
123
+ className: "flex items-center justify-center gap-2 rounded-lg bg-orange-500/10 px-4 py-2",
124
+ children: [
125
+ /* @__PURE__ */ jsxDEV("span", {
126
+ className: "text-xl",
127
+ children: "\uD83D\uDD25"
128
+ }, undefined, false, undefined, this),
129
+ /* @__PURE__ */ jsxDEV("span", {
130
+ className: "font-semibold text-orange-500",
131
+ children: [
132
+ streak,
133
+ " day engagement streak!"
134
+ ]
135
+ }, undefined, true, undefined, this)
136
+ ]
137
+ }, undefined, true, undefined, this)
138
+ ]
139
+ }, undefined, true, undefined, this);
140
+ }
141
+
142
+ // src/views/Progress.tsx
143
+ import {
144
+ Card,
145
+ CardContent,
146
+ CardHeader,
147
+ CardTitle
148
+ } from "@contractspec/lib.ui-kit-web/ui/card";
149
+ import {
150
+ XpBar,
151
+ BadgeDisplay,
152
+ StreakCounter
153
+ } from "@contractspec/example.learning-journey-ui-shared";
154
+ import { jsxDEV as jsxDEV2 } from "react/jsx-dev-runtime";
155
+ "use client";
156
+ function ProgressView({ track, progress }) {
157
+ const totalXp = track.totalXp ?? track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0);
158
+ const completedSteps = progress.completedStepIds.length;
159
+ const totalSteps = track.steps.length;
160
+ const pendingSteps = totalSteps - completedSteps;
161
+ const actioned = Math.floor(completedSteps * 0.7);
162
+ const acknowledged = completedSteps - actioned;
163
+ return /* @__PURE__ */ jsxDEV2("div", {
164
+ className: "space-y-6",
165
+ children: [
166
+ /* @__PURE__ */ jsxDEV2(Card, {
167
+ children: [
168
+ /* @__PURE__ */ jsxDEV2(CardHeader, {
169
+ children: /* @__PURE__ */ jsxDEV2(CardTitle, {
170
+ className: "flex items-center gap-2",
171
+ children: [
172
+ /* @__PURE__ */ jsxDEV2("span", {
173
+ children: "\uD83D\uDCCA"
174
+ }, undefined, false, undefined, this),
175
+ /* @__PURE__ */ jsxDEV2("span", {
176
+ children: "Engagement Overview"
177
+ }, undefined, false, undefined, this)
178
+ ]
179
+ }, undefined, true, undefined, this)
180
+ }, undefined, false, undefined, this),
181
+ /* @__PURE__ */ jsxDEV2(CardContent, {
182
+ children: /* @__PURE__ */ jsxDEV2(EngagementMeter, {
183
+ actioned,
184
+ acknowledged,
185
+ pending: pendingSteps,
186
+ streak: progress.streakDays
187
+ }, undefined, false, undefined, this)
188
+ }, undefined, false, undefined, this)
189
+ ]
190
+ }, undefined, true, undefined, this),
191
+ /* @__PURE__ */ jsxDEV2("div", {
192
+ className: "grid gap-4 md:grid-cols-2",
193
+ children: [
194
+ /* @__PURE__ */ jsxDEV2(Card, {
195
+ children: [
196
+ /* @__PURE__ */ jsxDEV2(CardHeader, {
197
+ className: "pb-2",
198
+ children: /* @__PURE__ */ jsxDEV2(CardTitle, {
199
+ className: "text-muted-foreground text-sm font-medium",
200
+ children: "XP Earned"
201
+ }, undefined, false, undefined, this)
202
+ }, undefined, false, undefined, this),
203
+ /* @__PURE__ */ jsxDEV2(CardContent, {
204
+ className: "space-y-3",
205
+ children: [
206
+ /* @__PURE__ */ jsxDEV2("div", {
207
+ className: "flex items-baseline gap-2",
208
+ children: [
209
+ /* @__PURE__ */ jsxDEV2("span", {
210
+ className: "text-3xl font-bold text-orange-500",
211
+ children: progress.xpEarned
212
+ }, undefined, false, undefined, this),
213
+ /* @__PURE__ */ jsxDEV2("span", {
214
+ className: "text-muted-foreground",
215
+ children: [
216
+ "/ ",
217
+ totalXp,
218
+ " XP"
219
+ ]
220
+ }, undefined, true, undefined, this)
221
+ ]
222
+ }, undefined, true, undefined, this),
223
+ /* @__PURE__ */ jsxDEV2(XpBar, {
224
+ current: progress.xpEarned,
225
+ max: totalXp,
226
+ showLabel: false,
227
+ size: "lg"
228
+ }, undefined, false, undefined, this)
229
+ ]
230
+ }, undefined, true, undefined, this)
231
+ ]
232
+ }, undefined, true, undefined, this),
233
+ /* @__PURE__ */ jsxDEV2(Card, {
234
+ children: [
235
+ /* @__PURE__ */ jsxDEV2(CardHeader, {
236
+ className: "pb-2",
237
+ children: /* @__PURE__ */ jsxDEV2(CardTitle, {
238
+ className: "text-muted-foreground text-sm font-medium",
239
+ children: "Engagement Streak"
240
+ }, undefined, false, undefined, this)
241
+ }, undefined, false, undefined, this),
242
+ /* @__PURE__ */ jsxDEV2(CardContent, {
243
+ children: /* @__PURE__ */ jsxDEV2("div", {
244
+ className: "flex items-center gap-4",
245
+ children: [
246
+ /* @__PURE__ */ jsxDEV2(StreakCounter, {
247
+ days: progress.streakDays,
248
+ size: "lg"
249
+ }, undefined, false, undefined, this),
250
+ /* @__PURE__ */ jsxDEV2("div", {
251
+ className: "text-muted-foreground text-sm",
252
+ children: progress.streakDays > 0 ? "Keep going!" : "Start your streak today!"
253
+ }, undefined, false, undefined, this)
254
+ ]
255
+ }, undefined, true, undefined, this)
256
+ }, undefined, false, undefined, this)
257
+ ]
258
+ }, undefined, true, undefined, this)
259
+ ]
260
+ }, undefined, true, undefined, this),
261
+ /* @__PURE__ */ jsxDEV2(Card, {
262
+ children: [
263
+ /* @__PURE__ */ jsxDEV2(CardHeader, {
264
+ children: /* @__PURE__ */ jsxDEV2(CardTitle, {
265
+ className: "flex items-center gap-2",
266
+ children: [
267
+ /* @__PURE__ */ jsxDEV2("span", {
268
+ children: "\uD83C\uDFC5"
269
+ }, undefined, false, undefined, this),
270
+ /* @__PURE__ */ jsxDEV2("span", {
271
+ children: "Achievements"
272
+ }, undefined, false, undefined, this)
273
+ ]
274
+ }, undefined, true, undefined, this)
275
+ }, undefined, false, undefined, this),
276
+ /* @__PURE__ */ jsxDEV2(CardContent, {
277
+ children: [
278
+ /* @__PURE__ */ jsxDEV2(BadgeDisplay, {
279
+ badges: progress.badges,
280
+ size: "lg",
281
+ maxVisible: 10
282
+ }, undefined, false, undefined, this),
283
+ progress.badges.length === 0 && /* @__PURE__ */ jsxDEV2("p", {
284
+ className: "text-muted-foreground text-sm",
285
+ children: "Action tips to unlock achievements!"
286
+ }, undefined, false, undefined, this)
287
+ ]
288
+ }, undefined, true, undefined, this)
289
+ ]
290
+ }, undefined, true, undefined, this),
291
+ /* @__PURE__ */ jsxDEV2(Card, {
292
+ children: [
293
+ /* @__PURE__ */ jsxDEV2(CardHeader, {
294
+ children: /* @__PURE__ */ jsxDEV2(CardTitle, {
295
+ className: "flex items-center gap-2",
296
+ children: [
297
+ /* @__PURE__ */ jsxDEV2("span", {
298
+ children: "\uD83D\uDCA1"
299
+ }, undefined, false, undefined, this),
300
+ /* @__PURE__ */ jsxDEV2("span", {
301
+ children: "Tip Status"
302
+ }, undefined, false, undefined, this)
303
+ ]
304
+ }, undefined, true, undefined, this)
305
+ }, undefined, false, undefined, this),
306
+ /* @__PURE__ */ jsxDEV2(CardContent, {
307
+ children: /* @__PURE__ */ jsxDEV2("div", {
308
+ className: "space-y-3",
309
+ children: track.steps.map((step) => {
310
+ const isCompleted = progress.completedStepIds.includes(step.id);
311
+ return /* @__PURE__ */ jsxDEV2("div", {
312
+ className: "flex items-center justify-between rounded-lg border p-3",
313
+ children: [
314
+ /* @__PURE__ */ jsxDEV2("div", {
315
+ className: "flex items-center gap-3",
316
+ children: [
317
+ /* @__PURE__ */ jsxDEV2("span", {
318
+ className: isCompleted ? "text-green-500" : "text-amber-500",
319
+ children: isCompleted ? "✓" : "○"
320
+ }, undefined, false, undefined, this),
321
+ /* @__PURE__ */ jsxDEV2("span", {
322
+ className: isCompleted ? "text-muted-foreground" : "text-foreground",
323
+ children: step.title
324
+ }, undefined, false, undefined, this)
325
+ ]
326
+ }, undefined, true, undefined, this),
327
+ /* @__PURE__ */ jsxDEV2("span", {
328
+ className: `text-sm ${isCompleted ? "text-green-500" : "text-muted-foreground"}`,
329
+ children: isCompleted ? "Actioned" : "Pending"
330
+ }, undefined, false, undefined, this)
331
+ ]
332
+ }, step.id, true, undefined, this);
333
+ })
334
+ }, undefined, false, undefined, this)
335
+ }, undefined, false, undefined, this)
336
+ ]
337
+ }, undefined, true, undefined, this)
338
+ ]
339
+ }, undefined, true, undefined, this);
340
+ }
341
+ export {
342
+ ProgressView,
343
+ ProgressView as Progress
344
+ };