@contractspec/example.learning-journey-ui-coaching 3.7.17 → 3.7.19
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 +48 -48
- package/CHANGELOG.md +30 -0
- package/dist/CoachingMiniApp.js +1 -1059
- package/dist/browser/CoachingMiniApp.js +1 -1059
- package/dist/browser/components/EngagementMeter.js +1 -143
- package/dist/browser/components/TipCard.js +1 -89
- package/dist/browser/components/TipFeed.js +1 -90
- package/dist/browser/components/index.js +1 -320
- package/dist/browser/docs/index.js +2 -16
- package/dist/browser/docs/learning-journey-ui-coaching.docblock.js +2 -16
- package/dist/browser/example.js +1 -32
- package/dist/browser/index.js +2 -1129
- package/dist/browser/learning-journey-ui-coaching.feature.js +1 -18
- package/dist/browser/views/Overview.js +1 -303
- package/dist/browser/views/Progress.js +1 -344
- package/dist/browser/views/Steps.js +1 -159
- package/dist/browser/views/Timeline.js +1 -266
- package/dist/browser/views/index.js +1 -980
- package/dist/components/EngagementMeter.js +1 -143
- package/dist/components/TipCard.js +1 -89
- package/dist/components/TipFeed.js +1 -90
- package/dist/components/index.js +1 -320
- package/dist/docs/index.js +2 -16
- package/dist/docs/learning-journey-ui-coaching.docblock.js +2 -16
- package/dist/example.js +1 -32
- package/dist/index.js +2 -1129
- package/dist/learning-journey-ui-coaching.feature.js +1 -18
- package/dist/node/CoachingMiniApp.js +1 -1059
- package/dist/node/components/EngagementMeter.js +1 -143
- package/dist/node/components/TipCard.js +1 -89
- package/dist/node/components/TipFeed.js +1 -90
- package/dist/node/components/index.js +1 -320
- package/dist/node/docs/index.js +2 -16
- package/dist/node/docs/learning-journey-ui-coaching.docblock.js +2 -16
- package/dist/node/example.js +1 -32
- package/dist/node/index.js +2 -1129
- package/dist/node/learning-journey-ui-coaching.feature.js +1 -18
- package/dist/node/views/Overview.js +1 -303
- package/dist/node/views/Progress.js +1 -344
- package/dist/node/views/Steps.js +1 -159
- package/dist/node/views/Timeline.js +1 -266
- package/dist/node/views/index.js +1 -980
- package/dist/views/Overview.js +1 -303
- package/dist/views/Progress.js +1 -344
- package/dist/views/Steps.js +1 -159
- package/dist/views/Timeline.js +1 -266
- package/dist/views/index.js +1 -980
- package/package.json +11 -11
|
@@ -1,1059 +1 @@
|
|
|
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 font-semibold text-xs", 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: "mt-1 text-muted-foreground 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-green-500 text-sm",
|
|
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 {
|
|
90
|
-
StreakCounter,
|
|
91
|
-
XpBar
|
|
92
|
-
} from "@contractspec/example.learning-journey-ui-shared";
|
|
93
|
-
import { Button as Button2 } from "@contractspec/lib.design-system";
|
|
94
|
-
import {
|
|
95
|
-
Card as Card2,
|
|
96
|
-
CardContent as CardContent2,
|
|
97
|
-
CardHeader,
|
|
98
|
-
CardTitle
|
|
99
|
-
} from "@contractspec/lib.ui-kit-web/ui/card";
|
|
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: "font-bold text-2xl",
|
|
132
|
-
children: track.name
|
|
133
|
-
}, undefined, false, undefined, this),
|
|
134
|
-
/* @__PURE__ */ jsxDEV2("p", {
|
|
135
|
-
className: "mt-1 text-muted-foreground",
|
|
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: "font-medium text-muted-foreground text-sm",
|
|
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: "font-bold text-3xl 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: "font-medium text-muted-foreground text-sm",
|
|
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: "font-bold text-3xl 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: "font-medium text-muted-foreground text-sm",
|
|
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: "font-bold text-3xl 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: "font-semibold text-green-500 text-lg",
|
|
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
|
-
|
|
302
|
-
// src/components/EngagementMeter.tsx
|
|
303
|
-
import { jsxDEV as jsxDEV3 } from "react/jsx-dev-runtime";
|
|
304
|
-
"use client";
|
|
305
|
-
function EngagementMeter({
|
|
306
|
-
acknowledged,
|
|
307
|
-
actioned,
|
|
308
|
-
pending,
|
|
309
|
-
streak = 0
|
|
310
|
-
}) {
|
|
311
|
-
const total = acknowledged + actioned + pending;
|
|
312
|
-
const actionedPercent = total > 0 ? actioned / total * 100 : 0;
|
|
313
|
-
const acknowledgedPercent = total > 0 ? acknowledged / total * 100 : 0;
|
|
314
|
-
return /* @__PURE__ */ jsxDEV3("div", {
|
|
315
|
-
className: "space-y-4",
|
|
316
|
-
children: [
|
|
317
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
318
|
-
className: "flex items-center justify-center",
|
|
319
|
-
children: /* @__PURE__ */ jsxDEV3("div", {
|
|
320
|
-
className: "relative h-32 w-32",
|
|
321
|
-
children: [
|
|
322
|
-
/* @__PURE__ */ jsxDEV3("svg", {
|
|
323
|
-
className: "h-full w-full -rotate-90",
|
|
324
|
-
viewBox: "0 0 100 100",
|
|
325
|
-
children: [
|
|
326
|
-
/* @__PURE__ */ jsxDEV3("circle", {
|
|
327
|
-
cx: "50",
|
|
328
|
-
cy: "50",
|
|
329
|
-
r: "40",
|
|
330
|
-
fill: "none",
|
|
331
|
-
strokeWidth: "12",
|
|
332
|
-
className: "stroke-muted"
|
|
333
|
-
}, undefined, false, undefined, this),
|
|
334
|
-
/* @__PURE__ */ jsxDEV3("circle", {
|
|
335
|
-
cx: "50",
|
|
336
|
-
cy: "50",
|
|
337
|
-
r: "40",
|
|
338
|
-
fill: "none",
|
|
339
|
-
strokeWidth: "12",
|
|
340
|
-
strokeLinecap: "round",
|
|
341
|
-
strokeDasharray: `${actionedPercent * 2.51} 251`,
|
|
342
|
-
className: "stroke-green-500 transition-all duration-500"
|
|
343
|
-
}, undefined, false, undefined, this),
|
|
344
|
-
/* @__PURE__ */ jsxDEV3("circle", {
|
|
345
|
-
cx: "50",
|
|
346
|
-
cy: "50",
|
|
347
|
-
r: "40",
|
|
348
|
-
fill: "none",
|
|
349
|
-
strokeWidth: "12",
|
|
350
|
-
strokeLinecap: "round",
|
|
351
|
-
strokeDasharray: `${acknowledgedPercent * 2.51} 251`,
|
|
352
|
-
strokeDashoffset: `${-actionedPercent * 2.51}`,
|
|
353
|
-
className: "stroke-amber-500 transition-all duration-500"
|
|
354
|
-
}, undefined, false, undefined, this)
|
|
355
|
-
]
|
|
356
|
-
}, undefined, true, undefined, this),
|
|
357
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
358
|
-
className: "absolute inset-0 flex flex-col items-center justify-center",
|
|
359
|
-
children: [
|
|
360
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
361
|
-
className: "font-bold text-2xl",
|
|
362
|
-
children: total
|
|
363
|
-
}, undefined, false, undefined, this),
|
|
364
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
365
|
-
className: "text-muted-foreground text-xs",
|
|
366
|
-
children: "tips"
|
|
367
|
-
}, undefined, false, undefined, this)
|
|
368
|
-
]
|
|
369
|
-
}, undefined, true, undefined, this)
|
|
370
|
-
]
|
|
371
|
-
}, undefined, true, undefined, this)
|
|
372
|
-
}, undefined, false, undefined, this),
|
|
373
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
374
|
-
className: "flex justify-center gap-4 text-sm",
|
|
375
|
-
children: [
|
|
376
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
377
|
-
className: "flex items-center gap-1.5",
|
|
378
|
-
children: [
|
|
379
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
380
|
-
className: "h-3 w-3 rounded-full bg-green-500"
|
|
381
|
-
}, undefined, false, undefined, this),
|
|
382
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
383
|
-
children: [
|
|
384
|
-
"Actioned (",
|
|
385
|
-
actioned,
|
|
386
|
-
")"
|
|
387
|
-
]
|
|
388
|
-
}, undefined, true, undefined, this)
|
|
389
|
-
]
|
|
390
|
-
}, undefined, true, undefined, this),
|
|
391
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
392
|
-
className: "flex items-center gap-1.5",
|
|
393
|
-
children: [
|
|
394
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
395
|
-
className: "h-3 w-3 rounded-full bg-amber-500"
|
|
396
|
-
}, undefined, false, undefined, this),
|
|
397
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
398
|
-
children: [
|
|
399
|
-
"Acknowledged (",
|
|
400
|
-
acknowledged,
|
|
401
|
-
")"
|
|
402
|
-
]
|
|
403
|
-
}, undefined, true, undefined, this)
|
|
404
|
-
]
|
|
405
|
-
}, undefined, true, undefined, this),
|
|
406
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
407
|
-
className: "flex items-center gap-1.5",
|
|
408
|
-
children: [
|
|
409
|
-
/* @__PURE__ */ jsxDEV3("div", {
|
|
410
|
-
className: "h-3 w-3 rounded-full bg-muted"
|
|
411
|
-
}, undefined, false, undefined, this),
|
|
412
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
413
|
-
children: [
|
|
414
|
-
"Pending (",
|
|
415
|
-
pending,
|
|
416
|
-
")"
|
|
417
|
-
]
|
|
418
|
-
}, undefined, true, undefined, this)
|
|
419
|
-
]
|
|
420
|
-
}, undefined, true, undefined, this)
|
|
421
|
-
]
|
|
422
|
-
}, undefined, true, undefined, this),
|
|
423
|
-
streak > 0 && /* @__PURE__ */ jsxDEV3("div", {
|
|
424
|
-
className: "flex items-center justify-center gap-2 rounded-lg bg-orange-500/10 px-4 py-2",
|
|
425
|
-
children: [
|
|
426
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
427
|
-
className: "text-xl",
|
|
428
|
-
children: "\uD83D\uDD25"
|
|
429
|
-
}, undefined, false, undefined, this),
|
|
430
|
-
/* @__PURE__ */ jsxDEV3("span", {
|
|
431
|
-
className: "font-semibold text-orange-500",
|
|
432
|
-
children: [
|
|
433
|
-
streak,
|
|
434
|
-
" day engagement streak!"
|
|
435
|
-
]
|
|
436
|
-
}, undefined, true, undefined, this)
|
|
437
|
-
]
|
|
438
|
-
}, undefined, true, undefined, this)
|
|
439
|
-
]
|
|
440
|
-
}, undefined, true, undefined, this);
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
// src/views/Progress.tsx
|
|
444
|
-
import {
|
|
445
|
-
BadgeDisplay,
|
|
446
|
-
StreakCounter as StreakCounter2,
|
|
447
|
-
XpBar as XpBar2
|
|
448
|
-
} from "@contractspec/example.learning-journey-ui-shared";
|
|
449
|
-
import {
|
|
450
|
-
Card as Card3,
|
|
451
|
-
CardContent as CardContent3,
|
|
452
|
-
CardHeader as CardHeader2,
|
|
453
|
-
CardTitle as CardTitle2
|
|
454
|
-
} from "@contractspec/lib.ui-kit-web/ui/card";
|
|
455
|
-
import { jsxDEV as jsxDEV4 } from "react/jsx-dev-runtime";
|
|
456
|
-
"use client";
|
|
457
|
-
function ProgressView({ track, progress }) {
|
|
458
|
-
const totalXp = track.totalXp ?? track.steps.reduce((sum, s) => sum + (s.xpReward ?? 0), 0);
|
|
459
|
-
const completedSteps = progress.completedStepIds.length;
|
|
460
|
-
const totalSteps = track.steps.length;
|
|
461
|
-
const pendingSteps = totalSteps - completedSteps;
|
|
462
|
-
const actioned = Math.floor(completedSteps * 0.7);
|
|
463
|
-
const acknowledged = completedSteps - actioned;
|
|
464
|
-
return /* @__PURE__ */ jsxDEV4("div", {
|
|
465
|
-
className: "space-y-6",
|
|
466
|
-
children: [
|
|
467
|
-
/* @__PURE__ */ jsxDEV4(Card3, {
|
|
468
|
-
children: [
|
|
469
|
-
/* @__PURE__ */ jsxDEV4(CardHeader2, {
|
|
470
|
-
children: /* @__PURE__ */ jsxDEV4(CardTitle2, {
|
|
471
|
-
className: "flex items-center gap-2",
|
|
472
|
-
children: [
|
|
473
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
474
|
-
children: "\uD83D\uDCCA"
|
|
475
|
-
}, undefined, false, undefined, this),
|
|
476
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
477
|
-
children: "Engagement Overview"
|
|
478
|
-
}, undefined, false, undefined, this)
|
|
479
|
-
]
|
|
480
|
-
}, undefined, true, undefined, this)
|
|
481
|
-
}, undefined, false, undefined, this),
|
|
482
|
-
/* @__PURE__ */ jsxDEV4(CardContent3, {
|
|
483
|
-
children: /* @__PURE__ */ jsxDEV4(EngagementMeter, {
|
|
484
|
-
actioned,
|
|
485
|
-
acknowledged,
|
|
486
|
-
pending: pendingSteps,
|
|
487
|
-
streak: progress.streakDays
|
|
488
|
-
}, undefined, false, undefined, this)
|
|
489
|
-
}, undefined, false, undefined, this)
|
|
490
|
-
]
|
|
491
|
-
}, undefined, true, undefined, this),
|
|
492
|
-
/* @__PURE__ */ jsxDEV4("div", {
|
|
493
|
-
className: "grid gap-4 md:grid-cols-2",
|
|
494
|
-
children: [
|
|
495
|
-
/* @__PURE__ */ jsxDEV4(Card3, {
|
|
496
|
-
children: [
|
|
497
|
-
/* @__PURE__ */ jsxDEV4(CardHeader2, {
|
|
498
|
-
className: "pb-2",
|
|
499
|
-
children: /* @__PURE__ */ jsxDEV4(CardTitle2, {
|
|
500
|
-
className: "font-medium text-muted-foreground text-sm",
|
|
501
|
-
children: "XP Earned"
|
|
502
|
-
}, undefined, false, undefined, this)
|
|
503
|
-
}, undefined, false, undefined, this),
|
|
504
|
-
/* @__PURE__ */ jsxDEV4(CardContent3, {
|
|
505
|
-
className: "space-y-3",
|
|
506
|
-
children: [
|
|
507
|
-
/* @__PURE__ */ jsxDEV4("div", {
|
|
508
|
-
className: "flex items-baseline gap-2",
|
|
509
|
-
children: [
|
|
510
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
511
|
-
className: "font-bold text-3xl text-orange-500",
|
|
512
|
-
children: progress.xpEarned
|
|
513
|
-
}, undefined, false, undefined, this),
|
|
514
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
515
|
-
className: "text-muted-foreground",
|
|
516
|
-
children: [
|
|
517
|
-
"/ ",
|
|
518
|
-
totalXp,
|
|
519
|
-
" XP"
|
|
520
|
-
]
|
|
521
|
-
}, undefined, true, undefined, this)
|
|
522
|
-
]
|
|
523
|
-
}, undefined, true, undefined, this),
|
|
524
|
-
/* @__PURE__ */ jsxDEV4(XpBar2, {
|
|
525
|
-
current: progress.xpEarned,
|
|
526
|
-
max: totalXp,
|
|
527
|
-
showLabel: false,
|
|
528
|
-
size: "lg"
|
|
529
|
-
}, undefined, false, undefined, this)
|
|
530
|
-
]
|
|
531
|
-
}, undefined, true, undefined, this)
|
|
532
|
-
]
|
|
533
|
-
}, undefined, true, undefined, this),
|
|
534
|
-
/* @__PURE__ */ jsxDEV4(Card3, {
|
|
535
|
-
children: [
|
|
536
|
-
/* @__PURE__ */ jsxDEV4(CardHeader2, {
|
|
537
|
-
className: "pb-2",
|
|
538
|
-
children: /* @__PURE__ */ jsxDEV4(CardTitle2, {
|
|
539
|
-
className: "font-medium text-muted-foreground text-sm",
|
|
540
|
-
children: "Engagement Streak"
|
|
541
|
-
}, undefined, false, undefined, this)
|
|
542
|
-
}, undefined, false, undefined, this),
|
|
543
|
-
/* @__PURE__ */ jsxDEV4(CardContent3, {
|
|
544
|
-
children: /* @__PURE__ */ jsxDEV4("div", {
|
|
545
|
-
className: "flex items-center gap-4",
|
|
546
|
-
children: [
|
|
547
|
-
/* @__PURE__ */ jsxDEV4(StreakCounter2, {
|
|
548
|
-
days: progress.streakDays,
|
|
549
|
-
size: "lg"
|
|
550
|
-
}, undefined, false, undefined, this),
|
|
551
|
-
/* @__PURE__ */ jsxDEV4("div", {
|
|
552
|
-
className: "text-muted-foreground text-sm",
|
|
553
|
-
children: progress.streakDays > 0 ? "Keep going!" : "Start your streak today!"
|
|
554
|
-
}, undefined, false, undefined, this)
|
|
555
|
-
]
|
|
556
|
-
}, undefined, true, undefined, this)
|
|
557
|
-
}, undefined, false, undefined, this)
|
|
558
|
-
]
|
|
559
|
-
}, undefined, true, undefined, this)
|
|
560
|
-
]
|
|
561
|
-
}, undefined, true, undefined, this),
|
|
562
|
-
/* @__PURE__ */ jsxDEV4(Card3, {
|
|
563
|
-
children: [
|
|
564
|
-
/* @__PURE__ */ jsxDEV4(CardHeader2, {
|
|
565
|
-
children: /* @__PURE__ */ jsxDEV4(CardTitle2, {
|
|
566
|
-
className: "flex items-center gap-2",
|
|
567
|
-
children: [
|
|
568
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
569
|
-
children: "\uD83C\uDFC5"
|
|
570
|
-
}, undefined, false, undefined, this),
|
|
571
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
572
|
-
children: "Achievements"
|
|
573
|
-
}, undefined, false, undefined, this)
|
|
574
|
-
]
|
|
575
|
-
}, undefined, true, undefined, this)
|
|
576
|
-
}, undefined, false, undefined, this),
|
|
577
|
-
/* @__PURE__ */ jsxDEV4(CardContent3, {
|
|
578
|
-
children: [
|
|
579
|
-
/* @__PURE__ */ jsxDEV4(BadgeDisplay, {
|
|
580
|
-
badges: progress.badges,
|
|
581
|
-
size: "lg",
|
|
582
|
-
maxVisible: 10
|
|
583
|
-
}, undefined, false, undefined, this),
|
|
584
|
-
progress.badges.length === 0 && /* @__PURE__ */ jsxDEV4("p", {
|
|
585
|
-
className: "text-muted-foreground text-sm",
|
|
586
|
-
children: "Action tips to unlock achievements!"
|
|
587
|
-
}, undefined, false, undefined, this)
|
|
588
|
-
]
|
|
589
|
-
}, undefined, true, undefined, this)
|
|
590
|
-
]
|
|
591
|
-
}, undefined, true, undefined, this),
|
|
592
|
-
/* @__PURE__ */ jsxDEV4(Card3, {
|
|
593
|
-
children: [
|
|
594
|
-
/* @__PURE__ */ jsxDEV4(CardHeader2, {
|
|
595
|
-
children: /* @__PURE__ */ jsxDEV4(CardTitle2, {
|
|
596
|
-
className: "flex items-center gap-2",
|
|
597
|
-
children: [
|
|
598
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
599
|
-
children: "\uD83D\uDCA1"
|
|
600
|
-
}, undefined, false, undefined, this),
|
|
601
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
602
|
-
children: "Tip Status"
|
|
603
|
-
}, undefined, false, undefined, this)
|
|
604
|
-
]
|
|
605
|
-
}, undefined, true, undefined, this)
|
|
606
|
-
}, undefined, false, undefined, this),
|
|
607
|
-
/* @__PURE__ */ jsxDEV4(CardContent3, {
|
|
608
|
-
children: /* @__PURE__ */ jsxDEV4("div", {
|
|
609
|
-
className: "space-y-3",
|
|
610
|
-
children: track.steps.map((step) => {
|
|
611
|
-
const isCompleted = progress.completedStepIds.includes(step.id);
|
|
612
|
-
return /* @__PURE__ */ jsxDEV4("div", {
|
|
613
|
-
className: "flex items-center justify-between rounded-lg border p-3",
|
|
614
|
-
children: [
|
|
615
|
-
/* @__PURE__ */ jsxDEV4("div", {
|
|
616
|
-
className: "flex items-center gap-3",
|
|
617
|
-
children: [
|
|
618
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
619
|
-
className: isCompleted ? "text-green-500" : "text-amber-500",
|
|
620
|
-
children: isCompleted ? "✓" : "○"
|
|
621
|
-
}, undefined, false, undefined, this),
|
|
622
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
623
|
-
className: isCompleted ? "text-muted-foreground" : "text-foreground",
|
|
624
|
-
children: step.title
|
|
625
|
-
}, undefined, false, undefined, this)
|
|
626
|
-
]
|
|
627
|
-
}, undefined, true, undefined, this),
|
|
628
|
-
/* @__PURE__ */ jsxDEV4("span", {
|
|
629
|
-
className: `text-sm ${isCompleted ? "text-green-500" : "text-muted-foreground"}`,
|
|
630
|
-
children: isCompleted ? "Actioned" : "Pending"
|
|
631
|
-
}, undefined, false, undefined, this)
|
|
632
|
-
]
|
|
633
|
-
}, step.id, true, undefined, this);
|
|
634
|
-
})
|
|
635
|
-
}, undefined, false, undefined, this)
|
|
636
|
-
}, undefined, false, undefined, this)
|
|
637
|
-
]
|
|
638
|
-
}, undefined, true, undefined, this)
|
|
639
|
-
]
|
|
640
|
-
}, undefined, true, undefined, this);
|
|
641
|
-
}
|
|
642
|
-
// src/views/Steps.tsx
|
|
643
|
-
import { jsxDEV as jsxDEV5 } from "react/jsx-dev-runtime";
|
|
644
|
-
"use client";
|
|
645
|
-
function Steps({ track, progress, onStepComplete }) {
|
|
646
|
-
const completedSteps = progress.completedStepIds.length;
|
|
647
|
-
const totalSteps = track.steps.length;
|
|
648
|
-
const sortedSteps = [...track.steps].sort((a, b) => {
|
|
649
|
-
const aCompleted = progress.completedStepIds.includes(a.id);
|
|
650
|
-
const bCompleted = progress.completedStepIds.includes(b.id);
|
|
651
|
-
if (aCompleted === bCompleted)
|
|
652
|
-
return 0;
|
|
653
|
-
return aCompleted ? 1 : -1;
|
|
654
|
-
});
|
|
655
|
-
const currentStepId = track.steps.find((s) => !progress.completedStepIds.includes(s.id))?.id;
|
|
656
|
-
return /* @__PURE__ */ jsxDEV5("div", {
|
|
657
|
-
className: "space-y-6",
|
|
658
|
-
children: [
|
|
659
|
-
/* @__PURE__ */ jsxDEV5("div", {
|
|
660
|
-
className: "text-center",
|
|
661
|
-
children: [
|
|
662
|
-
/* @__PURE__ */ jsxDEV5("h2", {
|
|
663
|
-
className: "font-bold text-xl",
|
|
664
|
-
children: "Coaching Tips"
|
|
665
|
-
}, undefined, false, undefined, this),
|
|
666
|
-
/* @__PURE__ */ jsxDEV5("p", {
|
|
667
|
-
className: "text-muted-foreground",
|
|
668
|
-
children: "Review and take action on personalized tips"
|
|
669
|
-
}, undefined, false, undefined, this),
|
|
670
|
-
/* @__PURE__ */ jsxDEV5("p", {
|
|
671
|
-
className: "mt-2 text-muted-foreground text-sm",
|
|
672
|
-
children: [
|
|
673
|
-
completedSteps,
|
|
674
|
-
" of ",
|
|
675
|
-
totalSteps,
|
|
676
|
-
" tips actioned"
|
|
677
|
-
]
|
|
678
|
-
}, undefined, true, undefined, this)
|
|
679
|
-
]
|
|
680
|
-
}, undefined, true, undefined, this),
|
|
681
|
-
/* @__PURE__ */ jsxDEV5("div", {
|
|
682
|
-
className: "space-y-3",
|
|
683
|
-
children: sortedSteps.map((step) => {
|
|
684
|
-
const isCompleted = progress.completedStepIds.includes(step.id);
|
|
685
|
-
const isCurrent = step.id === currentStepId;
|
|
686
|
-
return /* @__PURE__ */ jsxDEV5(TipCard, {
|
|
687
|
-
step,
|
|
688
|
-
isCompleted,
|
|
689
|
-
isCurrent,
|
|
690
|
-
onComplete: () => onStepComplete?.(step.id),
|
|
691
|
-
onDismiss: () => onStepComplete?.(step.id)
|
|
692
|
-
}, step.id, false, undefined, this);
|
|
693
|
-
})
|
|
694
|
-
}, undefined, false, undefined, this),
|
|
695
|
-
completedSteps === totalSteps && /* @__PURE__ */ jsxDEV5("div", {
|
|
696
|
-
className: "text-center text-muted-foreground",
|
|
697
|
-
children: [
|
|
698
|
-
/* @__PURE__ */ jsxDEV5("span", {
|
|
699
|
-
className: "text-2xl",
|
|
700
|
-
children: "✨"
|
|
701
|
-
}, undefined, false, undefined, this),
|
|
702
|
-
/* @__PURE__ */ jsxDEV5("p", {
|
|
703
|
-
className: "mt-2",
|
|
704
|
-
children: "All tips have been addressed!"
|
|
705
|
-
}, undefined, false, undefined, this)
|
|
706
|
-
]
|
|
707
|
-
}, undefined, true, undefined, this)
|
|
708
|
-
]
|
|
709
|
-
}, undefined, true, undefined, this);
|
|
710
|
-
}
|
|
711
|
-
|
|
712
|
-
// src/components/TipFeed.tsx
|
|
713
|
-
import { cn as cn2 } from "@contractspec/lib.ui-kit-web/ui/utils";
|
|
714
|
-
import { jsxDEV as jsxDEV6 } from "react/jsx-dev-runtime";
|
|
715
|
-
"use client";
|
|
716
|
-
var TIP_ICONS2 = {
|
|
717
|
-
cash_buffer_too_high: "\uD83D\uDCB0",
|
|
718
|
-
no_savings_goal: "\uD83C\uDFAF",
|
|
719
|
-
irregular_savings: "\uD83D\uDCC5",
|
|
720
|
-
noise_late_evening: "\uD83D\uDD07",
|
|
721
|
-
guest_frequency_high: "\uD83D\uDC65",
|
|
722
|
-
shared_space_conflicts: "\uD83C\uDFE0",
|
|
723
|
-
default: "\uD83D\uDCA1"
|
|
724
|
-
};
|
|
725
|
-
function TipFeed({ items }) {
|
|
726
|
-
if (items.length === 0) {
|
|
727
|
-
return /* @__PURE__ */ jsxDEV6("div", {
|
|
728
|
-
className: "py-8 text-center text-muted-foreground",
|
|
729
|
-
children: "No tips yet. Start engaging with coaching tips!"
|
|
730
|
-
}, undefined, false, undefined, this);
|
|
731
|
-
}
|
|
732
|
-
return /* @__PURE__ */ jsxDEV6("div", {
|
|
733
|
-
className: "relative",
|
|
734
|
-
children: [
|
|
735
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
736
|
-
className: "absolute top-0 left-4 h-full w-0.5 bg-border"
|
|
737
|
-
}, undefined, false, undefined, this),
|
|
738
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
739
|
-
className: "space-y-4",
|
|
740
|
-
children: items.map((item) => {
|
|
741
|
-
const tipId = item.step.metadata?.tipId ?? "default";
|
|
742
|
-
const icon = TIP_ICONS2[tipId] ?? TIP_ICONS2.default;
|
|
743
|
-
return /* @__PURE__ */ jsxDEV6("div", {
|
|
744
|
-
className: "relative flex gap-4 pl-2",
|
|
745
|
-
children: [
|
|
746
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
747
|
-
className: cn2("relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-sm", item.isCompleted ? "bg-green-500 text-white" : "bg-muted text-muted-foreground"),
|
|
748
|
-
children: item.isCompleted ? "✓" : icon
|
|
749
|
-
}, undefined, false, undefined, this),
|
|
750
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
751
|
-
className: "flex-1 rounded-lg border bg-card p-3",
|
|
752
|
-
children: [
|
|
753
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
754
|
-
className: "flex items-start justify-between gap-2",
|
|
755
|
-
children: [
|
|
756
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
757
|
-
children: [
|
|
758
|
-
/* @__PURE__ */ jsxDEV6("p", {
|
|
759
|
-
className: "font-medium",
|
|
760
|
-
children: item.step.title
|
|
761
|
-
}, undefined, false, undefined, this),
|
|
762
|
-
/* @__PURE__ */ jsxDEV6("p", {
|
|
763
|
-
className: "mt-0.5 text-muted-foreground text-sm",
|
|
764
|
-
children: item.step.description
|
|
765
|
-
}, undefined, false, undefined, this)
|
|
766
|
-
]
|
|
767
|
-
}, undefined, true, undefined, this),
|
|
768
|
-
item.step.xpReward && /* @__PURE__ */ jsxDEV6("span", {
|
|
769
|
-
className: cn2("shrink-0 font-medium text-xs", item.isCompleted ? "text-green-500" : "text-muted-foreground"),
|
|
770
|
-
children: [
|
|
771
|
-
"+",
|
|
772
|
-
item.step.xpReward,
|
|
773
|
-
" XP"
|
|
774
|
-
]
|
|
775
|
-
}, undefined, true, undefined, this)
|
|
776
|
-
]
|
|
777
|
-
}, undefined, true, undefined, this),
|
|
778
|
-
/* @__PURE__ */ jsxDEV6("div", {
|
|
779
|
-
className: "mt-2 flex items-center gap-2 text-muted-foreground text-xs",
|
|
780
|
-
children: item.isCompleted ? /* @__PURE__ */ jsxDEV6("span", {
|
|
781
|
-
className: "text-green-500",
|
|
782
|
-
children: [
|
|
783
|
-
"✓ Completed",
|
|
784
|
-
item.completedAt && ` • ${item.completedAt}`
|
|
785
|
-
]
|
|
786
|
-
}, undefined, true, undefined, this) : /* @__PURE__ */ jsxDEV6("span", {
|
|
787
|
-
children: "Pending action"
|
|
788
|
-
}, undefined, false, undefined, this)
|
|
789
|
-
}, undefined, false, undefined, this)
|
|
790
|
-
]
|
|
791
|
-
}, undefined, true, undefined, this)
|
|
792
|
-
]
|
|
793
|
-
}, item.step.id, true, undefined, this);
|
|
794
|
-
})
|
|
795
|
-
}, undefined, false, undefined, this)
|
|
796
|
-
]
|
|
797
|
-
}, undefined, true, undefined, this);
|
|
798
|
-
}
|
|
799
|
-
|
|
800
|
-
// src/views/Timeline.tsx
|
|
801
|
-
import {
|
|
802
|
-
Card as Card4,
|
|
803
|
-
CardContent as CardContent4,
|
|
804
|
-
CardHeader as CardHeader3,
|
|
805
|
-
CardTitle as CardTitle3
|
|
806
|
-
} from "@contractspec/lib.ui-kit-web/ui/card";
|
|
807
|
-
import { jsxDEV as jsxDEV7 } from "react/jsx-dev-runtime";
|
|
808
|
-
"use client";
|
|
809
|
-
function Timeline({ track, progress }) {
|
|
810
|
-
const feedItems = track.steps.map((step) => ({
|
|
811
|
-
step,
|
|
812
|
-
isCompleted: progress.completedStepIds.includes(step.id),
|
|
813
|
-
completedAt: progress.completedStepIds.includes(step.id) ? "Recently" : undefined
|
|
814
|
-
})).sort((a, b) => {
|
|
815
|
-
if (a.isCompleted && !b.isCompleted)
|
|
816
|
-
return -1;
|
|
817
|
-
if (!a.isCompleted && b.isCompleted)
|
|
818
|
-
return 1;
|
|
819
|
-
return 0;
|
|
820
|
-
});
|
|
821
|
-
const completedCount = feedItems.filter((f) => f.isCompleted).length;
|
|
822
|
-
const pendingCount = feedItems.length - completedCount;
|
|
823
|
-
return /* @__PURE__ */ jsxDEV7("div", {
|
|
824
|
-
className: "space-y-6",
|
|
825
|
-
children: [
|
|
826
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
827
|
-
className: "text-center",
|
|
828
|
-
children: [
|
|
829
|
-
/* @__PURE__ */ jsxDEV7("h2", {
|
|
830
|
-
className: "font-bold text-xl",
|
|
831
|
-
children: "Activity Timeline"
|
|
832
|
-
}, undefined, false, undefined, this),
|
|
833
|
-
/* @__PURE__ */ jsxDEV7("p", {
|
|
834
|
-
className: "text-muted-foreground",
|
|
835
|
-
children: "Your coaching journey and tip history"
|
|
836
|
-
}, undefined, false, undefined, this)
|
|
837
|
-
]
|
|
838
|
-
}, undefined, true, undefined, this),
|
|
839
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
840
|
-
className: "grid grid-cols-2 gap-4",
|
|
841
|
-
children: [
|
|
842
|
-
/* @__PURE__ */ jsxDEV7(Card4, {
|
|
843
|
-
children: /* @__PURE__ */ jsxDEV7(CardContent4, {
|
|
844
|
-
className: "p-4 text-center",
|
|
845
|
-
children: [
|
|
846
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
847
|
-
className: "font-bold text-2xl text-green-500",
|
|
848
|
-
children: completedCount
|
|
849
|
-
}, undefined, false, undefined, this),
|
|
850
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
851
|
-
className: "text-muted-foreground text-sm",
|
|
852
|
-
children: "Tips Actioned"
|
|
853
|
-
}, undefined, false, undefined, this)
|
|
854
|
-
]
|
|
855
|
-
}, undefined, true, undefined, this)
|
|
856
|
-
}, undefined, false, undefined, this),
|
|
857
|
-
/* @__PURE__ */ jsxDEV7(Card4, {
|
|
858
|
-
children: /* @__PURE__ */ jsxDEV7(CardContent4, {
|
|
859
|
-
className: "p-4 text-center",
|
|
860
|
-
children: [
|
|
861
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
862
|
-
className: "font-bold text-2xl text-amber-500",
|
|
863
|
-
children: pendingCount
|
|
864
|
-
}, undefined, false, undefined, this),
|
|
865
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
866
|
-
className: "text-muted-foreground text-sm",
|
|
867
|
-
children: "Tips Pending"
|
|
868
|
-
}, undefined, false, undefined, this)
|
|
869
|
-
]
|
|
870
|
-
}, undefined, true, undefined, this)
|
|
871
|
-
}, undefined, false, undefined, this)
|
|
872
|
-
]
|
|
873
|
-
}, undefined, true, undefined, this),
|
|
874
|
-
/* @__PURE__ */ jsxDEV7(Card4, {
|
|
875
|
-
children: [
|
|
876
|
-
/* @__PURE__ */ jsxDEV7(CardHeader3, {
|
|
877
|
-
children: /* @__PURE__ */ jsxDEV7(CardTitle3, {
|
|
878
|
-
className: "flex items-center gap-2",
|
|
879
|
-
children: [
|
|
880
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
881
|
-
children: "\uD83D\uDCDD"
|
|
882
|
-
}, undefined, false, undefined, this),
|
|
883
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
884
|
-
children: "Coaching Feed"
|
|
885
|
-
}, undefined, false, undefined, this)
|
|
886
|
-
]
|
|
887
|
-
}, undefined, true, undefined, this)
|
|
888
|
-
}, undefined, false, undefined, this),
|
|
889
|
-
/* @__PURE__ */ jsxDEV7(CardContent4, {
|
|
890
|
-
children: /* @__PURE__ */ jsxDEV7(TipFeed, {
|
|
891
|
-
items: feedItems
|
|
892
|
-
}, undefined, false, undefined, this)
|
|
893
|
-
}, undefined, false, undefined, this)
|
|
894
|
-
]
|
|
895
|
-
}, undefined, true, undefined, this),
|
|
896
|
-
/* @__PURE__ */ jsxDEV7(Card4, {
|
|
897
|
-
children: [
|
|
898
|
-
/* @__PURE__ */ jsxDEV7(CardHeader3, {
|
|
899
|
-
children: /* @__PURE__ */ jsxDEV7(CardTitle3, {
|
|
900
|
-
className: "flex items-center gap-2",
|
|
901
|
-
children: [
|
|
902
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
903
|
-
children: "\uD83D\uDCC8"
|
|
904
|
-
}, undefined, false, undefined, this),
|
|
905
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
906
|
-
children: "Journey Stats"
|
|
907
|
-
}, undefined, false, undefined, this)
|
|
908
|
-
]
|
|
909
|
-
}, undefined, true, undefined, this)
|
|
910
|
-
}, undefined, false, undefined, this),
|
|
911
|
-
/* @__PURE__ */ jsxDEV7(CardContent4, {
|
|
912
|
-
children: /* @__PURE__ */ jsxDEV7("div", {
|
|
913
|
-
className: "space-y-4",
|
|
914
|
-
children: [
|
|
915
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
916
|
-
className: "flex items-center justify-between",
|
|
917
|
-
children: [
|
|
918
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
919
|
-
className: "text-muted-foreground",
|
|
920
|
-
children: "Total Tips"
|
|
921
|
-
}, undefined, false, undefined, this),
|
|
922
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
923
|
-
className: "font-semibold",
|
|
924
|
-
children: track.steps.length
|
|
925
|
-
}, undefined, false, undefined, this)
|
|
926
|
-
]
|
|
927
|
-
}, undefined, true, undefined, this),
|
|
928
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
929
|
-
className: "flex items-center justify-between",
|
|
930
|
-
children: [
|
|
931
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
932
|
-
className: "text-muted-foreground",
|
|
933
|
-
children: "Completed"
|
|
934
|
-
}, undefined, false, undefined, this),
|
|
935
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
936
|
-
className: "font-semibold text-green-500",
|
|
937
|
-
children: completedCount
|
|
938
|
-
}, undefined, false, undefined, this)
|
|
939
|
-
]
|
|
940
|
-
}, undefined, true, undefined, this),
|
|
941
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
942
|
-
className: "flex items-center justify-between",
|
|
943
|
-
children: [
|
|
944
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
945
|
-
className: "text-muted-foreground",
|
|
946
|
-
children: "XP Earned"
|
|
947
|
-
}, undefined, false, undefined, this),
|
|
948
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
949
|
-
className: "font-semibold text-orange-500",
|
|
950
|
-
children: progress.xpEarned
|
|
951
|
-
}, undefined, false, undefined, this)
|
|
952
|
-
]
|
|
953
|
-
}, undefined, true, undefined, this),
|
|
954
|
-
/* @__PURE__ */ jsxDEV7("div", {
|
|
955
|
-
className: "flex items-center justify-between",
|
|
956
|
-
children: [
|
|
957
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
958
|
-
className: "text-muted-foreground",
|
|
959
|
-
children: "Current Streak"
|
|
960
|
-
}, undefined, false, undefined, this),
|
|
961
|
-
/* @__PURE__ */ jsxDEV7("span", {
|
|
962
|
-
className: "font-semibold",
|
|
963
|
-
children: progress.streakDays > 0 ? `\uD83D\uDD25 ${progress.streakDays} days` : "Start today!"
|
|
964
|
-
}, undefined, false, undefined, this)
|
|
965
|
-
]
|
|
966
|
-
}, undefined, true, undefined, this)
|
|
967
|
-
]
|
|
968
|
-
}, undefined, true, undefined, this)
|
|
969
|
-
}, undefined, false, undefined, this)
|
|
970
|
-
]
|
|
971
|
-
}, undefined, true, undefined, this)
|
|
972
|
-
]
|
|
973
|
-
}, undefined, true, undefined, this);
|
|
974
|
-
}
|
|
975
|
-
|
|
976
|
-
// src/CoachingMiniApp.tsx
|
|
977
|
-
import {
|
|
978
|
-
useLearningProgress,
|
|
979
|
-
ViewTabs
|
|
980
|
-
} from "@contractspec/example.learning-journey-ui-shared";
|
|
981
|
-
import { Card as Card5, CardContent as CardContent5 } from "@contractspec/lib.ui-kit-web/ui/card";
|
|
982
|
-
import { useCallback, useState } from "react";
|
|
983
|
-
import { jsxDEV as jsxDEV8 } from "react/jsx-dev-runtime";
|
|
984
|
-
"use client";
|
|
985
|
-
function CoachingMiniApp({
|
|
986
|
-
track,
|
|
987
|
-
progress: externalProgress,
|
|
988
|
-
onStepComplete: externalOnStepComplete,
|
|
989
|
-
onViewChange,
|
|
990
|
-
initialView = "overview"
|
|
991
|
-
}) {
|
|
992
|
-
const [currentView, setCurrentView] = useState(initialView);
|
|
993
|
-
const { progress: internalProgress, completeStep: internalCompleteStep } = useLearningProgress(track);
|
|
994
|
-
const progress = externalProgress ?? internalProgress;
|
|
995
|
-
const handleViewChange = useCallback((view) => {
|
|
996
|
-
setCurrentView(view);
|
|
997
|
-
onViewChange?.(view);
|
|
998
|
-
}, [onViewChange]);
|
|
999
|
-
const handleStepComplete = useCallback((stepId) => {
|
|
1000
|
-
if (externalOnStepComplete) {
|
|
1001
|
-
externalOnStepComplete(stepId);
|
|
1002
|
-
} else {
|
|
1003
|
-
internalCompleteStep(stepId);
|
|
1004
|
-
}
|
|
1005
|
-
}, [externalOnStepComplete, internalCompleteStep]);
|
|
1006
|
-
const handleStartFromOverview = useCallback(() => {
|
|
1007
|
-
setCurrentView("steps");
|
|
1008
|
-
onViewChange?.("steps");
|
|
1009
|
-
}, [onViewChange]);
|
|
1010
|
-
const renderView = () => {
|
|
1011
|
-
const viewProps = {
|
|
1012
|
-
track,
|
|
1013
|
-
progress,
|
|
1014
|
-
onStepComplete: handleStepComplete
|
|
1015
|
-
};
|
|
1016
|
-
switch (currentView) {
|
|
1017
|
-
case "overview":
|
|
1018
|
-
return /* @__PURE__ */ jsxDEV8(Overview, {
|
|
1019
|
-
...viewProps,
|
|
1020
|
-
onStart: handleStartFromOverview
|
|
1021
|
-
}, undefined, false, undefined, this);
|
|
1022
|
-
case "steps":
|
|
1023
|
-
return /* @__PURE__ */ jsxDEV8(Steps, {
|
|
1024
|
-
...viewProps
|
|
1025
|
-
}, undefined, false, undefined, this);
|
|
1026
|
-
case "progress":
|
|
1027
|
-
return /* @__PURE__ */ jsxDEV8(ProgressView, {
|
|
1028
|
-
...viewProps
|
|
1029
|
-
}, undefined, false, undefined, this);
|
|
1030
|
-
case "timeline":
|
|
1031
|
-
return /* @__PURE__ */ jsxDEV8(Timeline, {
|
|
1032
|
-
...viewProps
|
|
1033
|
-
}, undefined, false, undefined, this);
|
|
1034
|
-
default:
|
|
1035
|
-
return /* @__PURE__ */ jsxDEV8(Overview, {
|
|
1036
|
-
...viewProps,
|
|
1037
|
-
onStart: handleStartFromOverview
|
|
1038
|
-
}, undefined, false, undefined, this);
|
|
1039
|
-
}
|
|
1040
|
-
};
|
|
1041
|
-
return /* @__PURE__ */ jsxDEV8("div", {
|
|
1042
|
-
className: "space-y-6",
|
|
1043
|
-
children: [
|
|
1044
|
-
/* @__PURE__ */ jsxDEV8(Card5, {
|
|
1045
|
-
children: /* @__PURE__ */ jsxDEV8(CardContent5, {
|
|
1046
|
-
className: "p-4",
|
|
1047
|
-
children: /* @__PURE__ */ jsxDEV8(ViewTabs, {
|
|
1048
|
-
currentView,
|
|
1049
|
-
onViewChange: handleViewChange
|
|
1050
|
-
}, undefined, false, undefined, this)
|
|
1051
|
-
}, undefined, false, undefined, this)
|
|
1052
|
-
}, undefined, false, undefined, this),
|
|
1053
|
-
renderView()
|
|
1054
|
-
]
|
|
1055
|
-
}, undefined, true, undefined, this);
|
|
1056
|
-
}
|
|
1057
|
-
export {
|
|
1058
|
-
CoachingMiniApp
|
|
1059
|
-
};
|
|
1
|
+
import{Button as d}from"@contractspec/lib.design-system";import{Card as qq,CardContent as zq}from"@contractspec/lib.ui-kit-web/ui/card";import{cn as m}from"@contractspec/lib.ui-kit-web/ui/utils";import{jsx as N,jsxs as V}from"react/jsx-runtime";var i={cash_buffer_too_high:"\uD83D\uDCB0",no_savings_goal:"\uD83C\uDFAF",irregular_savings:"\uD83D\uDCC5",noise_late_evening:"\uD83D\uDD07",guest_frequency_high:"\uD83D\uDC65",shared_space_conflicts:"\uD83C\uDFE0",default:"\uD83D\uDCA1"};function T({step:z,isCompleted:q,isCurrent:R,onComplete:Q,onDismiss:y}){let U=z.metadata?.tipId??"default",Z=i[U]??i.default;return N(qq,{className:m("transition-all",q&&"opacity-60",R&&"ring-2 ring-amber-500"),children:N(zq,{className:"p-4",children:V("div",{className:"flex gap-4",children:[N("div",{className:m("flex h-12 w-12 shrink-0 items-center justify-center rounded-xl text-2xl",q?"bg-green-500/10":R?"bg-amber-500/10":"bg-muted"),children:q?"✓":Z}),V("div",{className:"min-w-0 flex-1",children:[V("div",{className:"flex items-start justify-between gap-2",children:[N("h4",{className:"font-semibold",children:z.title}),z.xpReward&&V("span",{className:m("shrink-0 rounded-full px-2 py-0.5 font-semibold text-xs",q?"bg-green-500/10 text-green-500":"bg-amber-500/10 text-amber-500"),children:["+",z.xpReward," XP"]})]}),N("p",{className:"mt-1 text-muted-foreground text-sm",children:z.description}),!q&&V("div",{className:"mt-3 flex flex-wrap gap-2",children:[N(d,{size:"sm",onClick:Q,children:"Take Action"}),N(d,{variant:"outline",size:"sm",onClick:y,children:"Dismiss"})]}),q&&N("p",{className:"mt-2 text-green-500 text-sm",children:"✓ Tip acknowledged"})]})]})})})}import{StreakCounter as Gq,XpBar as Jq}from"@contractspec/example.learning-journey-ui-shared";import{Button as Kq}from"@contractspec/lib.design-system";import{Card as f,CardContent as H,CardHeader as u,CardTitle as w}from"@contractspec/lib.ui-kit-web/ui/card";import{jsx as J,jsxs as $}from"react/jsx-runtime";function l({track:z,progress:q,onStepComplete:R,onStart:Q}){let y=z.totalXp??z.steps.reduce((W,O)=>W+(O.xpReward??0),0),U=q.completedStepIds.length,Z=z.steps.length,Y=Z-U,A=z.steps.filter((W)=>!q.completedStepIds.includes(W.id)).slice(0,3);return $("div",{className:"space-y-6",children:[J(f,{className:"overflow-hidden bg-gradient-to-br from-amber-500/10 via-orange-500/10 to-red-500/10",children:J(H,{className:"p-6",children:$("div",{className:"flex flex-col items-center gap-4 text-center md:flex-row md:text-left",children:[J("div",{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",children:"\uD83D\uDCA1"}),$("div",{className:"flex-1",children:[J("h1",{className:"font-bold text-2xl",children:z.name}),J("p",{className:"mt-1 text-muted-foreground",children:z.description})]}),J("div",{className:"flex items-center gap-4",children:J(Gq,{days:q.streakDays,size:"lg"})})]})})}),$("div",{className:"grid gap-4 md:grid-cols-3",children:[$(f,{children:[J(u,{className:"pb-2",children:J(w,{className:"font-medium text-muted-foreground text-sm",children:"Active Tips"})}),$(H,{children:[J("div",{className:"font-bold text-3xl text-amber-500",children:Y}),J("p",{className:"text-muted-foreground text-sm",children:"tips for you today"})]})]}),$(f,{children:[J(u,{className:"pb-2",children:J(w,{className:"font-medium text-muted-foreground text-sm",children:"Tips Actioned"})}),$(H,{children:[J("div",{className:"font-bold text-3xl text-green-500",children:U}),$("p",{className:"text-muted-foreground text-sm",children:["out of ",Z," total"]})]})]}),$(f,{children:[J(u,{className:"pb-2",children:J(w,{className:"font-medium text-muted-foreground text-sm",children:"XP Earned"})}),$(H,{children:[J("div",{className:"font-bold text-3xl text-orange-500",children:q.xpEarned}),J(Jq,{current:q.xpEarned,max:y,showLabel:!1,size:"sm"})]})]})]}),A.length>0&&$(f,{children:[$(u,{className:"flex flex-row items-center justify-between",children:[$(w,{className:"flex items-center gap-2",children:[J("span",{children:"\uD83D\uDCA1"}),J("span",{children:"Tips for You"})]}),A.length<Y&&$(Kq,{variant:"outline",size:"sm",onClick:Q,children:["View All (",Y,")"]})]}),J(H,{className:"space-y-3",children:A.map((W)=>J(T,{step:W,isCompleted:!1,isCurrent:W.id===A[0]?.id,onComplete:()=>R?.(W.id)},W.id))})]}),Y===0&&J(f,{className:"border-green-500/50 bg-green-500/5",children:$(H,{className:"flex items-center gap-4 p-6",children:[J("div",{className:"text-4xl",children:"\uD83C\uDF89"}),$("div",{children:[J("h3",{className:"font-semibold text-green-500 text-lg",children:"All Tips Actioned!"}),$("p",{className:"text-muted-foreground",children:["Great job! You've addressed all ",Z," coaching tips."]})]})]})})]})}import{jsx as F,jsxs as M}from"react/jsx-runtime";function n({acknowledged:z,actioned:q,pending:R,streak:Q=0}){let y=z+q+R,U=y>0?q/y*100:0,Z=y>0?z/y*100:0;return M("div",{className:"space-y-4",children:[F("div",{className:"flex items-center justify-center",children:M("div",{className:"relative h-32 w-32",children:[M("svg",{className:"h-full w-full -rotate-90",viewBox:"0 0 100 100",children:[F("circle",{cx:"50",cy:"50",r:"40",fill:"none",strokeWidth:"12",className:"stroke-muted"}),F("circle",{cx:"50",cy:"50",r:"40",fill:"none",strokeWidth:"12",strokeLinecap:"round",strokeDasharray:`${U*2.51} 251`,className:"stroke-green-500 transition-all duration-500"}),F("circle",{cx:"50",cy:"50",r:"40",fill:"none",strokeWidth:"12",strokeLinecap:"round",strokeDasharray:`${Z*2.51} 251`,strokeDashoffset:`${-U*2.51}`,className:"stroke-amber-500 transition-all duration-500"})]}),M("div",{className:"absolute inset-0 flex flex-col items-center justify-center",children:[F("span",{className:"font-bold text-2xl",children:y}),F("span",{className:"text-muted-foreground text-xs",children:"tips"})]})]})}),M("div",{className:"flex justify-center gap-4 text-sm",children:[M("div",{className:"flex items-center gap-1.5",children:[F("div",{className:"h-3 w-3 rounded-full bg-green-500"}),M("span",{children:["Actioned (",q,")"]})]}),M("div",{className:"flex items-center gap-1.5",children:[F("div",{className:"h-3 w-3 rounded-full bg-amber-500"}),M("span",{children:["Acknowledged (",z,")"]})]}),M("div",{className:"flex items-center gap-1.5",children:[F("div",{className:"h-3 w-3 rounded-full bg-muted"}),M("span",{children:["Pending (",R,")"]})]})]}),Q>0&&M("div",{className:"flex items-center justify-center gap-2 rounded-lg bg-orange-500/10 px-4 py-2",children:[F("span",{className:"text-xl",children:"\uD83D\uDD25"}),M("span",{className:"font-semibold text-orange-500",children:[Q," day engagement streak!"]})]})]})}import{BadgeDisplay as Qq,StreakCounter as Rq,XpBar as Uq}from"@contractspec/example.learning-journey-ui-shared";import{Card as I,CardContent as P,CardHeader as b,CardTitle as v}from"@contractspec/lib.ui-kit-web/ui/card";import{jsx as G,jsxs as E}from"react/jsx-runtime";function j({track:z,progress:q}){let R=z.totalXp??z.steps.reduce((A,W)=>A+(W.xpReward??0),0),Q=q.completedStepIds.length,U=z.steps.length-Q,Z=Math.floor(Q*0.7),Y=Q-Z;return E("div",{className:"space-y-6",children:[E(I,{children:[G(b,{children:E(v,{className:"flex items-center gap-2",children:[G("span",{children:"\uD83D\uDCCA"}),G("span",{children:"Engagement Overview"})]})}),G(P,{children:G(n,{actioned:Z,acknowledged:Y,pending:U,streak:q.streakDays})})]}),E("div",{className:"grid gap-4 md:grid-cols-2",children:[E(I,{children:[G(b,{className:"pb-2",children:G(v,{className:"font-medium text-muted-foreground text-sm",children:"XP Earned"})}),E(P,{className:"space-y-3",children:[E("div",{className:"flex items-baseline gap-2",children:[G("span",{className:"font-bold text-3xl text-orange-500",children:q.xpEarned}),E("span",{className:"text-muted-foreground",children:["/ ",R," XP"]})]}),G(Uq,{current:q.xpEarned,max:R,showLabel:!1,size:"lg"})]})]}),E(I,{children:[G(b,{className:"pb-2",children:G(v,{className:"font-medium text-muted-foreground text-sm",children:"Engagement Streak"})}),G(P,{children:E("div",{className:"flex items-center gap-4",children:[G(Rq,{days:q.streakDays,size:"lg"}),G("div",{className:"text-muted-foreground text-sm",children:q.streakDays>0?"Keep going!":"Start your streak today!"})]})})]})]}),E(I,{children:[G(b,{children:E(v,{className:"flex items-center gap-2",children:[G("span",{children:"\uD83C\uDFC5"}),G("span",{children:"Achievements"})]})}),E(P,{children:[G(Qq,{badges:q.badges,size:"lg",maxVisible:10}),q.badges.length===0&&G("p",{className:"text-muted-foreground text-sm",children:"Action tips to unlock achievements!"})]})]}),E(I,{children:[G(b,{children:E(v,{className:"flex items-center gap-2",children:[G("span",{children:"\uD83D\uDCA1"}),G("span",{children:"Tip Status"})]})}),G(P,{children:G("div",{className:"space-y-3",children:z.steps.map((A)=>{let W=q.completedStepIds.includes(A.id);return E("div",{className:"flex items-center justify-between rounded-lg border p-3",children:[E("div",{className:"flex items-center gap-3",children:[G("span",{className:W?"text-green-500":"text-amber-500",children:W?"✓":"○"}),G("span",{className:W?"text-muted-foreground":"text-foreground",children:A.title})]}),G("span",{className:`text-sm ${W?"text-green-500":"text-muted-foreground"}`,children:W?"Actioned":"Pending"})]},A.id)})})})]})]})}import{jsx as h,jsxs as S}from"react/jsx-runtime";function o({track:z,progress:q,onStepComplete:R}){let Q=q.completedStepIds.length,y=z.steps.length,U=[...z.steps].sort((Y,A)=>{let W=q.completedStepIds.includes(Y.id),O=q.completedStepIds.includes(A.id);if(W===O)return 0;return W?1:-1}),Z=z.steps.find((Y)=>!q.completedStepIds.includes(Y.id))?.id;return S("div",{className:"space-y-6",children:[S("div",{className:"text-center",children:[h("h2",{className:"font-bold text-xl",children:"Coaching Tips"}),h("p",{className:"text-muted-foreground",children:"Review and take action on personalized tips"}),S("p",{className:"mt-2 text-muted-foreground text-sm",children:[Q," of ",y," tips actioned"]})]}),h("div",{className:"space-y-3",children:U.map((Y)=>{let A=q.completedStepIds.includes(Y.id),W=Y.id===Z;return h(T,{step:Y,isCompleted:A,isCurrent:W,onComplete:()=>R?.(Y.id),onDismiss:()=>R?.(Y.id)},Y.id)})}),Q===y&&S("div",{className:"text-center text-muted-foreground",children:[h("span",{className:"text-2xl",children:"✨"}),h("p",{className:"mt-2",children:"All tips have been addressed!"})]})]})}import{cn as x}from"@contractspec/lib.ui-kit-web/ui/utils";import{jsx as _,jsxs as B}from"react/jsx-runtime";var a={cash_buffer_too_high:"\uD83D\uDCB0",no_savings_goal:"\uD83C\uDFAF",irregular_savings:"\uD83D\uDCC5",noise_late_evening:"\uD83D\uDD07",guest_frequency_high:"\uD83D\uDC65",shared_space_conflicts:"\uD83C\uDFE0",default:"\uD83D\uDCA1"};function p({items:z}){if(z.length===0)return _("div",{className:"py-8 text-center text-muted-foreground",children:"No tips yet. Start engaging with coaching tips!"});return B("div",{className:"relative",children:[_("div",{className:"absolute top-0 left-4 h-full w-0.5 bg-border"}),_("div",{className:"space-y-4",children:z.map((q)=>{let R=q.step.metadata?.tipId??"default",Q=a[R]??a.default;return B("div",{className:"relative flex gap-4 pl-2",children:[_("div",{className:x("relative z-10 flex h-8 w-8 shrink-0 items-center justify-center rounded-full text-sm",q.isCompleted?"bg-green-500 text-white":"bg-muted text-muted-foreground"),children:q.isCompleted?"✓":Q}),B("div",{className:"flex-1 rounded-lg border bg-card p-3",children:[B("div",{className:"flex items-start justify-between gap-2",children:[B("div",{children:[_("p",{className:"font-medium",children:q.step.title}),_("p",{className:"mt-0.5 text-muted-foreground text-sm",children:q.step.description})]}),q.step.xpReward&&B("span",{className:x("shrink-0 font-medium text-xs",q.isCompleted?"text-green-500":"text-muted-foreground"),children:["+",q.step.xpReward," XP"]})]}),_("div",{className:"mt-2 flex items-center gap-2 text-muted-foreground text-xs",children:q.isCompleted?B("span",{className:"text-green-500",children:["✓ Completed",q.completedAt&&` • ${q.completedAt}`]}):_("span",{children:"Pending action"})})]})]},q.step.id)})})]})}import{Card as k,CardContent as g,CardHeader as r,CardTitle as t}from"@contractspec/lib.ui-kit-web/ui/card";import{jsx as K,jsxs as L}from"react/jsx-runtime";function e({track:z,progress:q}){let R=z.steps.map((U)=>({step:U,isCompleted:q.completedStepIds.includes(U.id),completedAt:q.completedStepIds.includes(U.id)?"Recently":void 0})).sort((U,Z)=>{if(U.isCompleted&&!Z.isCompleted)return-1;if(!U.isCompleted&&Z.isCompleted)return 1;return 0}),Q=R.filter((U)=>U.isCompleted).length,y=R.length-Q;return L("div",{className:"space-y-6",children:[L("div",{className:"text-center",children:[K("h2",{className:"font-bold text-xl",children:"Activity Timeline"}),K("p",{className:"text-muted-foreground",children:"Your coaching journey and tip history"})]}),L("div",{className:"grid grid-cols-2 gap-4",children:[K(k,{children:L(g,{className:"p-4 text-center",children:[K("div",{className:"font-bold text-2xl text-green-500",children:Q}),K("div",{className:"text-muted-foreground text-sm",children:"Tips Actioned"})]})}),K(k,{children:L(g,{className:"p-4 text-center",children:[K("div",{className:"font-bold text-2xl text-amber-500",children:y}),K("div",{className:"text-muted-foreground text-sm",children:"Tips Pending"})]})})]}),L(k,{children:[K(r,{children:L(t,{className:"flex items-center gap-2",children:[K("span",{children:"\uD83D\uDCDD"}),K("span",{children:"Coaching Feed"})]})}),K(g,{children:K(p,{items:R})})]}),L(k,{children:[K(r,{children:L(t,{className:"flex items-center gap-2",children:[K("span",{children:"\uD83D\uDCC8"}),K("span",{children:"Journey Stats"})]})}),K(g,{children:L("div",{className:"space-y-4",children:[L("div",{className:"flex items-center justify-between",children:[K("span",{className:"text-muted-foreground",children:"Total Tips"}),K("span",{className:"font-semibold",children:z.steps.length})]}),L("div",{className:"flex items-center justify-between",children:[K("span",{className:"text-muted-foreground",children:"Completed"}),K("span",{className:"font-semibold text-green-500",children:Q})]}),L("div",{className:"flex items-center justify-between",children:[K("span",{className:"text-muted-foreground",children:"XP Earned"}),K("span",{className:"font-semibold text-orange-500",children:q.xpEarned})]}),L("div",{className:"flex items-center justify-between",children:[K("span",{className:"text-muted-foreground",children:"Current Streak"}),K("span",{className:"font-semibold",children:q.streakDays>0?`\uD83D\uDD25 ${q.streakDays} days`:"Start today!"})]})]})})]})]})}import{useLearningProgress as Wq,ViewTabs as Yq}from"@contractspec/example.learning-journey-ui-shared";import{Card as Zq,CardContent as $q}from"@contractspec/lib.ui-kit-web/ui/card";import{useCallback as c,useState as yq}from"react";import{jsx as X,jsxs as Aq}from"react/jsx-runtime";function rq({track:z,progress:q,onStepComplete:R,onViewChange:Q,initialView:y="overview"}){let[U,Z]=yq(y),{progress:Y,completeStep:A}=Wq(z),W=q??Y,O=c((D)=>{Z(D),Q?.(D)},[Q]),s=c((D)=>{if(R)R(D);else A(D)},[R,A]),C=c(()=>{Z("steps"),Q?.("steps")},[Q]);return Aq("div",{className:"space-y-6",children:[X(Zq,{children:X($q,{className:"p-4",children:X(Yq,{currentView:U,onViewChange:O})})}),(()=>{let D={track:z,progress:W,onStepComplete:s};switch(U){case"overview":return X(l,{...D,onStart:C});case"steps":return X(o,{...D});case"progress":return X(j,{...D});case"timeline":return X(e,{...D});default:return X(l,{...D,onStart:C})}})()]})}export{rq as CoachingMiniApp};
|