@burdenoff/microfe-mybodyshield 2026.720.1 → 2026.720.3

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.
@@ -7,20 +7,20 @@ import { ErrorView as i, LoadingView as a } from "../../components/StateViews.js
7
7
  import { FilterTabs as o } from "../../components/FilterTabs.js";
8
8
  import { Pagination as s } from "../../components/Pagination.js";
9
9
  import "../../context/index.js";
10
- import { useMybPrograms as c, useMybSessions as l, useMybStartSession as re } from "../../hooks/useMyBodyShieldApi.js";
11
- import { useOffsetPager as ie } from "../../hooks/usePager.js";
12
- import { useMyBodyShieldAnalytics as u } from "../../hooks/useMyBodyShieldAnalytics.js";
10
+ import { useMybProgramWorkouts as c, useMybPrograms as l, useMybSessions as u, useMybStartSession as re } from "../../hooks/useMyBodyShieldApi.js";
11
+ import { useOffsetPager as d } from "../../hooks/usePager.js";
12
+ import { useMyBodyShieldAnalytics as f } from "../../hooks/useMyBodyShieldAnalytics.js";
13
13
  import "../../hooks/index.js";
14
14
  import "../../components/index.js";
15
- import { motion as d } from "../../../node_modules/framer-motion/dist/es/render/components/motion/proxy.js";
16
- import { useReducedMotion as ae } from "../../../node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js";
17
- import { IconChip as f, Meter as oe } from "../_shared/visuals.js";
18
- import { useState as p } from "react";
19
- import { CalendarClock as m, CheckCircle2 as h, Flame as g, Gauge as se, ListChecks as ce, PlayCircle as _, Plus as v, SkipForward as y } from "lucide-react";
20
- import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
21
- import { Button as C, GlassCard as le, Input as ue, Label as w, ResponsiveDialog as T, ResponsiveDialogContent as E, ResponsiveDialogDescription as D, ResponsiveDialogFooter as O, ResponsiveDialogHeader as k, ResponsiveDialogTitle as A, Select as j, SelectContent as M, SelectItem as N, SelectTrigger as P, SelectValue as F, Textarea as I } from "@burdenoff/fe-libs/ui";
15
+ import { motion as p } from "../../../node_modules/framer-motion/dist/es/render/components/motion/proxy.js";
16
+ import { useReducedMotion as m } from "../../../node_modules/framer-motion/dist/es/utils/reduced-motion/use-reduced-motion.js";
17
+ import { IconChip as h, Meter as ie } from "../_shared/visuals.js";
18
+ import { useState as g } from "react";
19
+ import { CalendarClock as _, CheckCircle2 as v, Flame as y, Gauge as ae, ListChecks as oe, PlayCircle as b, Plus as x, SkipForward as S } from "lucide-react";
20
+ import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
21
+ import { Button as E, GlassCard as D, Input as se, Label as O, ResponsiveDialog as ce, ResponsiveDialogContent as le, ResponsiveDialogDescription as ue, ResponsiveDialogFooter as de, ResponsiveDialogHeader as fe, ResponsiveDialogTitle as pe, Select as k, SelectContent as A, SelectItem as j, SelectTrigger as M, SelectValue as N, Textarea as P } from "@burdenoff/fe-libs/ui";
22
22
  //#region src/mybodyshield/pages/train/SessionsPage.tsx
23
- var L = [
23
+ var F = [
24
24
  {
25
25
  value: "ALL",
26
26
  label: "All"
@@ -37,41 +37,42 @@ var L = [
37
37
  value: "COMPLETED",
38
38
  label: "Completed"
39
39
  }
40
- ], R = 24, z = [
40
+ ], I = 24, L = [
41
41
  .16,
42
42
  1,
43
43
  .3,
44
44
  1
45
- ], B = "__none__", V = {
46
- programId: B,
45
+ ], R = "__none__", z = "__none__", B = {
46
+ programId: R,
47
+ workoutId: z,
47
48
  scheduledFor: "",
48
49
  notes: ""
49
50
  };
50
- function H(e) {
51
+ function me(e) {
51
52
  switch (e.status) {
52
53
  case "IN_PROGRESS": return {
53
- icon: _,
54
+ icon: b,
54
55
  tint: "var(--color-accent-teal)",
55
56
  title: "Live workout in progress",
56
57
  stampLabel: "Started",
57
58
  stamp: e.startedAt ?? e.createdAt
58
59
  };
59
60
  case "COMPLETED": return {
60
- icon: h,
61
+ icon: v,
61
62
  tint: "var(--color-status-success-text)",
62
63
  title: e.caloriesBurned > 0 ? `${n(e.caloriesBurned)} burned` : "Workout completed",
63
64
  stampLabel: "Completed",
64
65
  stamp: e.completedAt ?? e.startedAt ?? e.createdAt
65
66
  };
66
67
  case "SKIPPED": return {
67
- icon: y,
68
+ icon: S,
68
69
  tint: "var(--color-text-secondary)",
69
70
  title: "Skipped session",
70
71
  stampLabel: "Scheduled",
71
72
  stamp: e.scheduledFor ?? e.createdAt
72
73
  };
73
74
  default: return {
74
- icon: m,
75
+ icon: _,
75
76
  tint: "var(--color-accent-primary)",
76
77
  title: "Scheduled session",
77
78
  stampLabel: "Scheduled",
@@ -79,58 +80,58 @@ function H(e) {
79
80
  };
80
81
  }
81
82
  }
82
- function U() {
83
- let { navigateTo: m, workspaceId: h } = e(), _ = ae(), y = u(), [U, de] = p("ALL"), W = ie(R), G = l({
84
- status: U === "ALL" ? void 0 : U,
83
+ function V() {
84
+ let { navigateTo: _, workspaceId: v } = e(), b = m(), S = f(), [V, he] = g("ALL"), H = d(I), U = u({
85
+ status: V === "ALL" ? void 0 : V,
85
86
  pagination: {
86
- limit: R,
87
- offset: W.offset
87
+ limit: I,
88
+ offset: H.offset
88
89
  }
89
- }), fe = c({
90
+ }), ge = l({
90
91
  status: "ACTIVE",
91
92
  pagination: { limit: 50 }
92
- }).data?.items ?? [], K = re(), [pe, q] = p(!1), [J, Y] = p(V), [X, Z] = p(null), Q = G.data?.items ?? [], me = G.data?.pageInfo?.hasMore ?? !1, he = (e) => {
93
- de(e), W.reset();
93
+ }).data?.items ?? [], W = re(), [_e, G] = g(!1), [K, q] = g(B), [J, Y] = g(null), X = K.programId === R ? void 0 : K.programId, Z = c(X).data ?? [], Q = U.data?.items ?? [], ve = U.data?.pageInfo?.hasMore ?? !1, ye = (e) => {
94
+ he(e), H.reset();
94
95
  }, $ = () => {
95
- Y(V), Z(null), q(!0), y.emitIntent("session", "create", { workspaceId: h });
96
+ q(B), Y(null), G(!0), S.emitIntent("session", "create", { workspaceId: v });
96
97
  };
97
- return /* @__PURE__ */ S(t, {
98
+ return /* @__PURE__ */ T(t, {
98
99
  title: "Train",
99
100
  description: "Live workout sessions — start, log sets, and complete.",
100
- actions: /* @__PURE__ */ S(C, {
101
+ actions: /* @__PURE__ */ T(E, {
101
102
  onClick: $,
102
- children: [/* @__PURE__ */ x(v, { className: "h-4 w-4" }), " Start session"]
103
+ children: [/* @__PURE__ */ w(x, { className: "h-4 w-4" }), " Start session"]
103
104
  }),
104
105
  children: [
105
- /* @__PURE__ */ x("div", {
106
+ /* @__PURE__ */ w("div", {
106
107
  className: "mb-6",
107
- children: /* @__PURE__ */ x(o, {
108
- options: L,
109
- value: U,
110
- onChange: he
108
+ children: /* @__PURE__ */ w(o, {
109
+ options: F,
110
+ value: V,
111
+ onChange: ye
111
112
  })
112
113
  }),
113
- G.isLoading ? /* @__PURE__ */ x(a, { label: "Loading your sessions…" }) : G.isError ? /* @__PURE__ */ x(i, {
114
+ U.isLoading ? /* @__PURE__ */ w(a, { label: "Loading your sessions…" }) : U.isError ? /* @__PURE__ */ w(i, {
114
115
  message: "We couldn't load your workout sessions.",
115
- onRetry: () => G.refetch()
116
- }) : Q.length === 0 ? /* @__PURE__ */ x(r, {
116
+ onRetry: () => U.refetch()
117
+ }) : Q.length === 0 ? /* @__PURE__ */ w(r, {
117
118
  illustration: "empty-data",
118
- icon: /* @__PURE__ */ x(g, { className: "h-10 w-10" }),
119
- title: U === "ALL" ? "No sessions yet" : "No sessions in this state",
120
- description: U === "ALL" ? "Start a workout session to begin logging sets and tracking your training." : "Try a different filter, or start a new workout session.",
121
- action: /* @__PURE__ */ S(C, {
119
+ icon: /* @__PURE__ */ w(y, { className: "h-10 w-10" }),
120
+ title: V === "ALL" ? "No sessions yet" : "No sessions in this state",
121
+ description: V === "ALL" ? "Start a workout session to begin logging sets and tracking your training." : "Try a different filter, or start a new workout session.",
122
+ action: /* @__PURE__ */ T(E, {
122
123
  onClick: $,
123
- children: [/* @__PURE__ */ x(v, { className: "h-4 w-4" }), " Start session"]
124
+ children: [/* @__PURE__ */ w(x, { className: "h-4 w-4" }), " Start session"]
124
125
  })
125
- }) : /* @__PURE__ */ S(b, { children: [/* @__PURE__ */ x("div", {
126
+ }) : /* @__PURE__ */ T(C, { children: [/* @__PURE__ */ w("div", {
126
127
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
127
128
  children: Q.map((e, t) => {
128
- let r = H(e), i = r.icon, a = e.status === "IN_PROGRESS", o = e.sets?.length, s = e.perceivedExertion;
129
- return /* @__PURE__ */ x(d.button, {
129
+ let r = me(e), i = r.icon, a = e.status === "IN_PROGRESS", o = e.sets?.length, s = e.perceivedExertion;
130
+ return /* @__PURE__ */ w(p.button, {
130
131
  type: "button",
131
- onClick: () => m(`train/${e.id}`),
132
+ onClick: () => _(`train/${e.id}`),
132
133
  className: "block w-full text-left",
133
- initial: _ ? !1 : {
134
+ initial: b ? !1 : {
134
135
  opacity: 0,
135
136
  y: 12
136
137
  },
@@ -138,30 +139,30 @@ function U() {
138
139
  opacity: 1,
139
140
  y: 0
140
141
  },
141
- transition: _ ? { duration: 0 } : {
142
+ transition: b ? { duration: 0 } : {
142
143
  duration: .35,
143
144
  delay: Math.min(t, 8) * .05,
144
- ease: z
145
+ ease: L
145
146
  },
146
- whileHover: _ ? void 0 : { y: -3 },
147
- whileTap: _ ? void 0 : { scale: .995 },
148
- children: /* @__PURE__ */ S(le, {
147
+ whileHover: b ? void 0 : { y: -3 },
148
+ whileTap: b ? void 0 : { scale: .995 },
149
+ children: /* @__PURE__ */ T(D, {
149
150
  treatment: "plain",
150
151
  glow: a,
151
152
  className: "h-full p-4 transition-shadow hover:shadow-float" + (a ? " ring-1 ring-inset ring-[color-mix(in_oklab,var(--color-action-primary-bg)_45%,transparent)]" : ""),
152
153
  children: [
153
- /* @__PURE__ */ S("div", {
154
+ /* @__PURE__ */ T("div", {
154
155
  className: "flex items-center justify-between gap-2",
155
- children: [/* @__PURE__ */ x(f, {
156
- icon: /* @__PURE__ */ x(i, { className: "h-4 w-4" }),
156
+ children: [/* @__PURE__ */ w(h, {
157
+ icon: /* @__PURE__ */ w(i, { className: "h-4 w-4" }),
157
158
  tint: r.tint
158
- }), /* @__PURE__ */ x(ne, { status: e.status })]
159
+ }), /* @__PURE__ */ w(ne, { status: e.status })]
159
160
  }),
160
- /* @__PURE__ */ x("p", {
161
+ /* @__PURE__ */ w("p", {
161
162
  className: "mt-3 text-base font-semibold text-text-primary",
162
163
  children: r.title
163
164
  }),
164
- /* @__PURE__ */ S("p", {
165
+ /* @__PURE__ */ T("p", {
165
166
  className: "mt-0.5 text-xs text-text-tertiary",
166
167
  children: [
167
168
  r.stampLabel,
@@ -169,46 +170,46 @@ function U() {
169
170
  te(r.stamp)
170
171
  ]
171
172
  }),
172
- /* @__PURE__ */ S("div", {
173
+ /* @__PURE__ */ T("div", {
173
174
  className: "mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary",
174
175
  children: [
175
- e.caloriesBurned > 0 && /* @__PURE__ */ S("span", {
176
+ e.caloriesBurned > 0 && /* @__PURE__ */ T("span", {
176
177
  className: "inline-flex items-center gap-1 tabular-nums",
177
- children: [/* @__PURE__ */ x(g, { className: "h-3.5 w-3.5 text-status-warning-text" }), n(e.caloriesBurned)]
178
+ children: [/* @__PURE__ */ w(y, { className: "h-3.5 w-3.5 text-status-warning-text" }), n(e.caloriesBurned)]
178
179
  }),
179
- s != null && /* @__PURE__ */ S("span", {
180
+ s != null && /* @__PURE__ */ T("span", {
180
181
  className: "inline-flex items-center gap-1 tabular-nums",
181
182
  children: [
182
- /* @__PURE__ */ x(se, { className: "h-3.5 w-3.5 text-accent" }),
183
+ /* @__PURE__ */ w(ae, { className: "h-3.5 w-3.5 text-accent" }),
183
184
  "RPE ",
184
185
  s,
185
186
  "/10"
186
187
  ]
187
188
  }),
188
- o != null && o > 0 && /* @__PURE__ */ S("span", {
189
+ o != null && o > 0 && /* @__PURE__ */ T("span", {
189
190
  className: "inline-flex items-center gap-1 tabular-nums",
190
191
  children: [
191
- /* @__PURE__ */ x(ce, { className: "h-3.5 w-3.5 text-accent" }),
192
+ /* @__PURE__ */ w(oe, { className: "h-3.5 w-3.5 text-accent" }),
192
193
  ee(o),
193
194
  " sets"
194
195
  ]
195
196
  })
196
197
  ]
197
198
  }),
198
- s != null && /* @__PURE__ */ S("div", {
199
+ s != null && /* @__PURE__ */ T("div", {
199
200
  className: "mt-3",
200
- children: [/* @__PURE__ */ S("div", {
201
+ children: [/* @__PURE__ */ T("div", {
201
202
  className: "mb-1 flex items-center justify-between text-[11px] text-text-tertiary",
202
- children: [/* @__PURE__ */ x("span", { children: "RPE intensity" }), /* @__PURE__ */ S("span", {
203
+ children: [/* @__PURE__ */ w("span", { children: "RPE intensity" }), /* @__PURE__ */ T("span", {
203
204
  className: "tabular-nums",
204
205
  children: [s, "/10"]
205
206
  })]
206
- }), /* @__PURE__ */ x(oe, {
207
+ }), /* @__PURE__ */ w(ie, {
207
208
  value: s * 10,
208
209
  height: 6
209
210
  })]
210
211
  }),
211
- a && /* @__PURE__ */ x("p", {
212
+ a && /* @__PURE__ */ w("p", {
212
213
  className: "mt-3 inline-flex items-center gap-1 text-xs font-semibold text-action-primary-bg",
213
214
  children: "In progress — Resume →"
214
215
  })
@@ -216,112 +217,150 @@ function U() {
216
217
  })
217
218
  }, e.id);
218
219
  })
219
- }), /* @__PURE__ */ x(s, {
220
- page: W.page,
221
- pageSize: R,
220
+ }), /* @__PURE__ */ w(s, {
221
+ page: H.page,
222
+ pageSize: I,
222
223
  itemCount: Q.length,
223
- hasMore: me,
224
- onPageChange: (e) => W.onPageChange(e)
224
+ hasMore: ve,
225
+ onPageChange: (e) => H.onPageChange(e)
225
226
  })] }),
226
- /* @__PURE__ */ x(T, {
227
- open: pe,
228
- onOpenChange: q,
229
- children: /* @__PURE__ */ S(E, { children: [
230
- /* @__PURE__ */ S(k, { children: [/* @__PURE__ */ x(A, { children: "Start a workout session" }), /* @__PURE__ */ x(D, { children: "Begin a live session now, or schedule one for later. Attach an active program to keep your training organised." })] }),
231
- /* @__PURE__ */ S("div", {
227
+ /* @__PURE__ */ w(ce, {
228
+ open: _e,
229
+ onOpenChange: G,
230
+ children: /* @__PURE__ */ T(le, { children: [
231
+ /* @__PURE__ */ T(fe, { children: [/* @__PURE__ */ w(pe, { children: "Start a workout session" }), /* @__PURE__ */ w(ue, { children: "Begin a live session now, or schedule one for later. Attach an active program to keep your training organised." })] }),
232
+ /* @__PURE__ */ T("div", {
232
233
  className: "space-y-4 px-1",
233
234
  children: [
234
- /* @__PURE__ */ S("div", {
235
+ /* @__PURE__ */ T("div", {
235
236
  className: "space-y-1.5",
236
- children: [/* @__PURE__ */ x(w, {
237
+ children: [/* @__PURE__ */ w(O, {
237
238
  htmlFor: "myb-start-program",
238
239
  children: "Program (optional)"
239
- }), /* @__PURE__ */ S(j, {
240
- value: J.programId,
241
- onValueChange: (e) => Y((t) => ({
240
+ }), /* @__PURE__ */ T(k, {
241
+ value: K.programId,
242
+ onValueChange: (e) => q((t) => ({
242
243
  ...t,
243
- programId: e
244
+ programId: e,
245
+ workoutId: z
244
246
  })),
245
- children: [/* @__PURE__ */ x(P, {
247
+ children: [/* @__PURE__ */ w(M, {
246
248
  id: "myb-start-program",
247
- children: /* @__PURE__ */ x(F, { placeholder: "No program" })
248
- }), /* @__PURE__ */ S(M, { children: [/* @__PURE__ */ x(N, {
249
- value: B,
249
+ children: /* @__PURE__ */ w(N, { placeholder: "No program" })
250
+ }), /* @__PURE__ */ T(A, { children: [/* @__PURE__ */ w(j, {
251
+ value: R,
250
252
  children: "No program"
251
- }), fe.map((e) => /* @__PURE__ */ x(N, {
253
+ }), ge.map((e) => /* @__PURE__ */ w(j, {
252
254
  value: e.id,
253
255
  children: e.name
254
256
  }, e.id))] })]
255
257
  })]
256
258
  }),
257
- /* @__PURE__ */ S("div", {
259
+ X && Z.length > 0 && /* @__PURE__ */ T("div", {
260
+ className: "space-y-1.5",
261
+ children: [
262
+ /* @__PURE__ */ w(O, {
263
+ htmlFor: "myb-start-workout",
264
+ children: "Workout (optional)"
265
+ }),
266
+ /* @__PURE__ */ T(k, {
267
+ value: K.workoutId,
268
+ onValueChange: (e) => q((t) => ({
269
+ ...t,
270
+ workoutId: e
271
+ })),
272
+ children: [/* @__PURE__ */ w(M, {
273
+ id: "myb-start-workout",
274
+ children: /* @__PURE__ */ w(N, { placeholder: "No specific workout" })
275
+ }), /* @__PURE__ */ T(A, { children: [/* @__PURE__ */ w(j, {
276
+ value: z,
277
+ children: "No specific workout"
278
+ }), Z.map((e) => /* @__PURE__ */ T(j, {
279
+ value: e.id,
280
+ children: [
281
+ e.name,
282
+ " — Week ",
283
+ e.weekNumber,
284
+ ", Day ",
285
+ e.dayOfWeek
286
+ ]
287
+ }, e.id))] })]
288
+ }),
289
+ /* @__PURE__ */ w("p", {
290
+ className: "text-xs text-text-tertiary",
291
+ children: "Attach a planned workout to guide this session exercise-by-exercise."
292
+ })
293
+ ]
294
+ }),
295
+ /* @__PURE__ */ T("div", {
258
296
  className: "space-y-1.5",
259
297
  children: [
260
- /* @__PURE__ */ x(w, {
298
+ /* @__PURE__ */ w(O, {
261
299
  htmlFor: "myb-start-scheduled",
262
300
  children: "Scheduled for (optional)"
263
301
  }),
264
- /* @__PURE__ */ x(ue, {
302
+ /* @__PURE__ */ w(se, {
265
303
  id: "myb-start-scheduled",
266
304
  type: "datetime-local",
267
- value: J.scheduledFor,
268
- onChange: (e) => Y((t) => ({
305
+ value: K.scheduledFor,
306
+ onChange: (e) => q((t) => ({
269
307
  ...t,
270
308
  scheduledFor: e.target.value
271
309
  }))
272
310
  }),
273
- /* @__PURE__ */ x("p", {
311
+ /* @__PURE__ */ w("p", {
274
312
  className: "text-xs text-text-tertiary",
275
313
  children: "Leave empty to start a live session right now."
276
314
  })
277
315
  ]
278
316
  }),
279
- /* @__PURE__ */ S("div", {
317
+ /* @__PURE__ */ T("div", {
280
318
  className: "space-y-1.5",
281
- children: [/* @__PURE__ */ x(w, {
319
+ children: [/* @__PURE__ */ w(O, {
282
320
  htmlFor: "myb-start-notes",
283
321
  children: "Notes (optional)"
284
- }), /* @__PURE__ */ x(I, {
322
+ }), /* @__PURE__ */ w(P, {
285
323
  id: "myb-start-notes",
286
324
  rows: 3,
287
- value: J.notes,
288
- onChange: (e) => Y((t) => ({
325
+ value: K.notes,
326
+ onChange: (e) => q((t) => ({
289
327
  ...t,
290
328
  notes: e.target.value
291
329
  })),
292
330
  placeholder: "Focus, target lifts, how you're feeling…"
293
331
  })]
294
332
  }),
295
- X && /* @__PURE__ */ x("p", {
333
+ J && /* @__PURE__ */ w("p", {
296
334
  className: "text-sm text-status-error-text",
297
- children: X
335
+ children: J
298
336
  })
299
337
  ]
300
338
  }),
301
- /* @__PURE__ */ S(O, { children: [/* @__PURE__ */ x(C, {
339
+ /* @__PURE__ */ T(de, { children: [/* @__PURE__ */ w(E, {
302
340
  variant: "outline",
303
- onClick: () => q(!1),
304
- disabled: K.isPending,
341
+ onClick: () => G(!1),
342
+ disabled: W.isPending,
305
343
  children: "Cancel"
306
- }), /* @__PURE__ */ x(C, {
344
+ }), /* @__PURE__ */ w(E, {
307
345
  onClick: async () => {
308
- Z(null);
346
+ Y(null);
309
347
  try {
310
- let e = await K.mutateAsync({
311
- programId: J.programId === B ? void 0 : J.programId,
312
- scheduledFor: J.scheduledFor ? new Date(J.scheduledFor).toISOString() : void 0,
313
- notes: J.notes.trim() ? J.notes.trim() : void 0
348
+ let e = await W.mutateAsync({
349
+ programId: X,
350
+ workoutId: K.workoutId === z ? void 0 : K.workoutId,
351
+ scheduledFor: K.scheduledFor ? new Date(K.scheduledFor).toISOString() : void 0,
352
+ notes: K.notes.trim() ? K.notes.trim() : void 0
314
353
  });
315
- y.emitFact("session", "started", {
316
- workspaceId: h,
354
+ S.emitFact("session", "started", {
355
+ workspaceId: v,
317
356
  entityId: e.id
318
- }), q(!1), m(`train/${e.id}`);
357
+ }), G(!1), _(`train/${e.id}`);
319
358
  } catch (e) {
320
- Z(e instanceof Error ? e.message : "Failed to start the session.");
359
+ Y(e instanceof Error ? e.message : "Failed to start the session.");
321
360
  }
322
361
  },
323
- disabled: K.isPending,
324
- children: K.isPending ? "Starting…" : "Start session"
362
+ disabled: W.isPending,
363
+ children: W.isPending ? "Starting…" : "Start session"
325
364
  })] })
326
365
  ] })
327
366
  })
@@ -329,6 +368,6 @@ function U() {
329
368
  });
330
369
  }
331
370
  //#endregion
332
- export { U as SessionsPage };
371
+ export { V as SessionsPage };
333
372
 
334
373
  //# sourceMappingURL=SessionsPage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"SessionsPage.js","names":[],"sources":["../../../../src/mybodyshield/pages/train/SessionsPage.tsx"],"sourcesContent":["/**\n * Train — live workout sessions.\n * @module mybodyshield/pages/train\n *\n * Lists the member's workout sessions (real `mybListSessions`) filtered by\n * status, and lets you start a new live session (optionally attached to an\n * active program). In-progress sessions are highlighted with an accent ring and\n * a \"Resume\" affordance. No mock data — everything comes from the myb* hooks.\n */\n\nimport { useState } from 'react';\nimport { motion, useReducedMotion } from 'framer-motion';\nimport {\n Plus,\n Flame,\n CheckCircle2,\n CalendarClock,\n PlayCircle,\n SkipForward,\n Gauge,\n ListChecks,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Label,\n Textarea,\n Input,\n Select,\n SelectTrigger,\n SelectContent,\n SelectItem,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n StatusBadge,\n FilterTabs,\n Pagination,\n LoadingView,\n ErrorView,\n EmptyState,\n type FilterOption,\n} from '../../components';\nimport { IconChip, Meter } from '../_shared/visuals';\nimport { useMyBodyShield } from '../../context';\nimport {\n useMybSessions,\n useMybStartSession,\n useMybPrograms,\n useOffsetPager,\n useMyBodyShieldAnalytics,\n} from '../../hooks';\nimport { formatRelativeTime, formatKcal, formatNumber } from '../../utils/formatters';\nimport type { MybSessionStatus, MybWorkoutSession } from '../../types';\n\ntype SessionFilterValue = MybSessionStatus | 'ALL';\n\n// Only statuses a control can actually reach are offered as filters: start →\n// IN_PROGRESS / SCHEDULED, complete → COMPLETED. Nothing moves a session to\n// SKIPPED, so that tab would always be empty. sessionMeta still handles the\n// SKIPPED case for display safety.\nconst STATUS_TABS: FilterOption<SessionFilterValue>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'IN_PROGRESS', label: 'Live' },\n { value: 'COMPLETED', label: 'Completed' },\n];\n\nconst PAGE_SIZE = 24;\n\n/** Shared entrance easing — a soft, decelerating cubic-bezier. */\nconst MOTION_EASE: [number, number, number, number] = [0.16, 1, 0.3, 1];\n\n/** Sentinel for the optional program picker (Radix Select forbids an empty value). */\nconst NO_PROGRAM = '__none__';\n\ninterface StartForm {\n programId: string;\n scheduledFor: string;\n notes: string;\n}\n\nconst EMPTY_START_FORM: StartForm = { programId: NO_PROGRAM, scheduledFor: '', notes: '' };\n\ninterface SessionMeta {\n icon: typeof Flame;\n tint: string;\n title: string;\n stampLabel: string;\n stamp?: string | null;\n}\n\nfunction sessionMeta(s: MybWorkoutSession): SessionMeta {\n switch (s.status) {\n case 'IN_PROGRESS':\n return {\n icon: PlayCircle,\n tint: 'var(--color-accent-teal)',\n title: 'Live workout in progress',\n stampLabel: 'Started',\n stamp: s.startedAt ?? s.createdAt,\n };\n case 'COMPLETED':\n return {\n icon: CheckCircle2,\n tint: 'var(--color-status-success-text)',\n title:\n s.caloriesBurned > 0 ? `${formatKcal(s.caloriesBurned)} burned` : 'Workout completed',\n stampLabel: 'Completed',\n stamp: s.completedAt ?? s.startedAt ?? s.createdAt,\n };\n case 'SKIPPED':\n return {\n icon: SkipForward,\n tint: 'var(--color-text-secondary)',\n title: 'Skipped session',\n stampLabel: 'Scheduled',\n stamp: s.scheduledFor ?? s.createdAt,\n };\n case 'SCHEDULED':\n default:\n return {\n icon: CalendarClock,\n tint: 'var(--color-accent-primary)',\n title: 'Scheduled session',\n stampLabel: 'Scheduled',\n stamp: s.scheduledFor ?? s.createdAt,\n };\n }\n}\n\nexport function SessionsPage() {\n const { navigateTo, workspaceId } = useMyBodyShield();\n const reduce = useReducedMotion();\n const analytics = useMyBodyShieldAnalytics();\n\n const [filter, setFilter] = useState<SessionFilterValue>('ALL');\n const pager = useOffsetPager(PAGE_SIZE);\n\n const sessions = useMybSessions({\n status: filter === 'ALL' ? undefined : filter,\n pagination: { limit: PAGE_SIZE, offset: pager.offset },\n });\n\n const programs = useMybPrograms({ status: 'ACTIVE', pagination: { limit: 50 } });\n const activePrograms = programs.data?.items ?? [];\n\n const startSession = useMybStartSession();\n\n const [startOpen, setStartOpen] = useState(false);\n const [form, setForm] = useState<StartForm>(EMPTY_START_FORM);\n const [formError, setFormError] = useState<string | null>(null);\n\n const rows = sessions.data?.items ?? [];\n const hasMore = sessions.data?.pageInfo?.hasMore ?? false;\n\n const onFilterChange = (value: SessionFilterValue) => {\n setFilter(value);\n pager.reset();\n };\n\n const openStart = () => {\n setForm(EMPTY_START_FORM);\n setFormError(null);\n setStartOpen(true);\n analytics.emitIntent('session', 'create', { workspaceId });\n };\n\n const submitStart = async () => {\n setFormError(null);\n try {\n const created = await startSession.mutateAsync({\n programId: form.programId === NO_PROGRAM ? undefined : form.programId,\n scheduledFor: form.scheduledFor ? new Date(form.scheduledFor).toISOString() : undefined,\n notes: form.notes.trim() ? form.notes.trim() : undefined,\n });\n analytics.emitFact('session', 'started', { workspaceId, entityId: created.id });\n setStartOpen(false);\n navigateTo(`train/${created.id}`);\n } catch (e) {\n setFormError(e instanceof Error ? e.message : 'Failed to start the session.');\n }\n };\n\n return (\n <PageLayout\n title=\"Train\"\n description=\"Live workout sessions — start, log sets, and complete.\"\n actions={\n <Button onClick={openStart}>\n <Plus className=\"h-4 w-4\" /> Start session\n </Button>\n }\n >\n <div className=\"mb-6\">\n <FilterTabs options={STATUS_TABS} value={filter} onChange={onFilterChange} />\n </div>\n\n {sessions.isLoading ? (\n <LoadingView label=\"Loading your sessions…\" />\n ) : sessions.isError ? (\n <ErrorView\n message=\"We couldn't load your workout sessions.\"\n onRetry={() => sessions.refetch()}\n />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Flame className=\"h-10 w-10\" />}\n title={filter === 'ALL' ? 'No sessions yet' : 'No sessions in this state'}\n description={\n filter === 'ALL'\n ? 'Start a workout session to begin logging sets and tracking your training.'\n : 'Try a different filter, or start a new workout session.'\n }\n action={\n <Button onClick={openStart}>\n <Plus className=\"h-4 w-4\" /> Start session\n </Button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {rows.map((s, i) => {\n const meta = sessionMeta(s);\n const Icon = meta.icon;\n const isLive = s.status === 'IN_PROGRESS';\n const setCount = s.sets?.length;\n const rpe = s.perceivedExertion;\n return (\n <motion.button\n key={s.id}\n type=\"button\"\n onClick={() => navigateTo(`train/${s.id}`)}\n className=\"block w-full text-left\"\n initial={reduce ? false : { opacity: 0, y: 12 }}\n animate={{ opacity: 1, y: 0 }}\n transition={\n reduce\n ? { duration: 0 }\n : { duration: 0.35, delay: Math.min(i, 8) * 0.05, ease: MOTION_EASE }\n }\n whileHover={reduce ? undefined : { y: -3 }}\n whileTap={reduce ? undefined : { scale: 0.995 }}\n >\n <GlassCard\n treatment=\"plain\"\n glow={isLive}\n className={\n 'h-full p-4 transition-shadow hover:shadow-float' +\n (isLive\n ? ' ring-1 ring-inset ring-[color-mix(in_oklab,var(--color-action-primary-bg)_45%,transparent)]'\n : '')\n }\n >\n <div className=\"flex items-center justify-between gap-2\">\n <IconChip icon={<Icon className=\"h-4 w-4\" />} tint={meta.tint} />\n <StatusBadge status={s.status} />\n </div>\n <p className=\"mt-3 text-base font-semibold text-text-primary\">{meta.title}</p>\n <p className=\"mt-0.5 text-xs text-text-tertiary\">\n {meta.stampLabel} {formatRelativeTime(meta.stamp)}\n </p>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary\">\n {s.caloriesBurned > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Flame className=\"h-3.5 w-3.5 text-status-warning-text\" />\n {formatKcal(s.caloriesBurned)}\n </span>\n )}\n {rpe != null && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Gauge className=\"h-3.5 w-3.5 text-accent\" />\n RPE {rpe}/10\n </span>\n )}\n {setCount != null && setCount > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <ListChecks className=\"h-3.5 w-3.5 text-accent\" />\n {formatNumber(setCount)} sets\n </span>\n )}\n </div>\n\n {rpe != null && (\n <div className=\"mt-3\">\n <div className=\"mb-1 flex items-center justify-between text-[11px] text-text-tertiary\">\n <span>RPE intensity</span>\n <span className=\"tabular-nums\">{rpe}/10</span>\n </div>\n <Meter value={rpe * 10} height={6} />\n </div>\n )}\n\n {isLive && (\n <p className=\"mt-3 inline-flex items-center gap-1 text-xs font-semibold text-action-primary-bg\">\n In progress — Resume →\n </p>\n )}\n </GlassCard>\n </motion.button>\n );\n })}\n </div>\n\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={hasMore}\n onPageChange={(t) => pager.onPageChange(t)}\n />\n </>\n )}\n\n {/* Start session dialog */}\n <ResponsiveDialog open={startOpen} onOpenChange={setStartOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Start a workout session</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Begin a live session now, or schedule one for later. Attach an active program to keep\n your training organised.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"space-y-4 px-1\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-program\">Program (optional)</Label>\n <Select\n value={form.programId}\n onValueChange={(v) => setForm((f) => ({ ...f, programId: v }))}\n >\n <SelectTrigger id=\"myb-start-program\">\n <SelectValue placeholder=\"No program\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NO_PROGRAM}>No program</SelectItem>\n {activePrograms.map((p) => (\n <SelectItem key={p.id} value={p.id}>\n {p.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-scheduled\">Scheduled for (optional)</Label>\n <Input\n id=\"myb-start-scheduled\"\n type=\"datetime-local\"\n value={form.scheduledFor}\n onChange={(e) => setForm((f) => ({ ...f, scheduledFor: e.target.value }))}\n />\n <p className=\"text-xs text-text-tertiary\">\n Leave empty to start a live session right now.\n </p>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-notes\">Notes (optional)</Label>\n <Textarea\n id=\"myb-start-notes\"\n rows={3}\n value={form.notes}\n onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))}\n placeholder=\"Focus, target lifts, how you're feeling…\"\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => setStartOpen(false)}\n disabled={startSession.isPending}\n >\n Cancel\n </Button>\n <Button onClick={submitStart} disabled={startSession.isPending}>\n {startSession.isPending ? 'Starting…' : 'Start session'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"SessionsPage.js","names":[],"sources":["../../../../src/mybodyshield/pages/train/SessionsPage.tsx"],"sourcesContent":["/**\n * Train — live workout sessions.\n * @module mybodyshield/pages/train\n *\n * Lists the member's workout sessions (real `mybListSessions`) filtered by\n * status, and lets you start a new live session (optionally attached to an\n * active program). In-progress sessions are highlighted with an accent ring and\n * a \"Resume\" affordance. No mock data — everything comes from the myb* hooks.\n */\n\nimport { useState } from 'react';\nimport { motion, useReducedMotion } from 'framer-motion';\nimport {\n Plus,\n Flame,\n CheckCircle2,\n CalendarClock,\n PlayCircle,\n SkipForward,\n Gauge,\n ListChecks,\n} from 'lucide-react';\nimport {\n Button,\n GlassCard,\n Label,\n Textarea,\n Input,\n Select,\n SelectTrigger,\n SelectContent,\n SelectItem,\n SelectValue,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport {\n PageLayout,\n StatusBadge,\n FilterTabs,\n Pagination,\n LoadingView,\n ErrorView,\n EmptyState,\n type FilterOption,\n} from '../../components';\nimport { IconChip, Meter } from '../_shared/visuals';\nimport { useMyBodyShield } from '../../context';\nimport {\n useMybSessions,\n useMybStartSession,\n useMybPrograms,\n useMybProgramWorkouts,\n useOffsetPager,\n useMyBodyShieldAnalytics,\n} from '../../hooks';\nimport { formatRelativeTime, formatKcal, formatNumber } from '../../utils/formatters';\nimport type { MybSessionStatus, MybWorkoutSession } from '../../types';\n\ntype SessionFilterValue = MybSessionStatus | 'ALL';\n\n// Only statuses a control can actually reach are offered as filters: start →\n// IN_PROGRESS / SCHEDULED, complete → COMPLETED. Nothing moves a session to\n// SKIPPED, so that tab would always be empty. sessionMeta still handles the\n// SKIPPED case for display safety.\nconst STATUS_TABS: FilterOption<SessionFilterValue>[] = [\n { value: 'ALL', label: 'All' },\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'IN_PROGRESS', label: 'Live' },\n { value: 'COMPLETED', label: 'Completed' },\n];\n\nconst PAGE_SIZE = 24;\n\n/** Shared entrance easing — a soft, decelerating cubic-bezier. */\nconst MOTION_EASE: [number, number, number, number] = [0.16, 1, 0.3, 1];\n\n/** Sentinel for the optional program/workout pickers (Radix Select forbids an empty value). */\nconst NO_PROGRAM = '__none__';\nconst NO_WORKOUT = '__none__';\n\ninterface StartForm {\n programId: string;\n workoutId: string;\n scheduledFor: string;\n notes: string;\n}\n\nconst EMPTY_START_FORM: StartForm = {\n programId: NO_PROGRAM,\n workoutId: NO_WORKOUT,\n scheduledFor: '',\n notes: '',\n};\n\ninterface SessionMeta {\n icon: typeof Flame;\n tint: string;\n title: string;\n stampLabel: string;\n stamp?: string | null;\n}\n\nfunction sessionMeta(s: MybWorkoutSession): SessionMeta {\n switch (s.status) {\n case 'IN_PROGRESS':\n return {\n icon: PlayCircle,\n tint: 'var(--color-accent-teal)',\n title: 'Live workout in progress',\n stampLabel: 'Started',\n stamp: s.startedAt ?? s.createdAt,\n };\n case 'COMPLETED':\n return {\n icon: CheckCircle2,\n tint: 'var(--color-status-success-text)',\n title:\n s.caloriesBurned > 0 ? `${formatKcal(s.caloriesBurned)} burned` : 'Workout completed',\n stampLabel: 'Completed',\n stamp: s.completedAt ?? s.startedAt ?? s.createdAt,\n };\n case 'SKIPPED':\n return {\n icon: SkipForward,\n tint: 'var(--color-text-secondary)',\n title: 'Skipped session',\n stampLabel: 'Scheduled',\n stamp: s.scheduledFor ?? s.createdAt,\n };\n case 'SCHEDULED':\n default:\n return {\n icon: CalendarClock,\n tint: 'var(--color-accent-primary)',\n title: 'Scheduled session',\n stampLabel: 'Scheduled',\n stamp: s.scheduledFor ?? s.createdAt,\n };\n }\n}\n\nexport function SessionsPage() {\n const { navigateTo, workspaceId } = useMyBodyShield();\n const reduce = useReducedMotion();\n const analytics = useMyBodyShieldAnalytics();\n\n const [filter, setFilter] = useState<SessionFilterValue>('ALL');\n const pager = useOffsetPager(PAGE_SIZE);\n\n const sessions = useMybSessions({\n status: filter === 'ALL' ? undefined : filter,\n pagination: { limit: PAGE_SIZE, offset: pager.offset },\n });\n\n const programs = useMybPrograms({ status: 'ACTIVE', pagination: { limit: 50 } });\n const activePrograms = programs.data?.items ?? [];\n\n const startSession = useMybStartSession();\n\n const [startOpen, setStartOpen] = useState(false);\n const [form, setForm] = useState<StartForm>(EMPTY_START_FORM);\n const [formError, setFormError] = useState<string | null>(null);\n\n // Workouts for the selected program, so a session can be tied to a specific\n // planned workout — required for the guided next-exercise stepper on\n // SessionDetailPage (BOFF-4096) to have anything to walk through.\n const selectedProgramId = form.programId === NO_PROGRAM ? undefined : form.programId;\n const programWorkouts = useMybProgramWorkouts(selectedProgramId);\n const workoutOptions = programWorkouts.data ?? [];\n\n const rows = sessions.data?.items ?? [];\n const hasMore = sessions.data?.pageInfo?.hasMore ?? false;\n\n const onFilterChange = (value: SessionFilterValue) => {\n setFilter(value);\n pager.reset();\n };\n\n const openStart = () => {\n setForm(EMPTY_START_FORM);\n setFormError(null);\n setStartOpen(true);\n analytics.emitIntent('session', 'create', { workspaceId });\n };\n\n const submitStart = async () => {\n setFormError(null);\n try {\n const created = await startSession.mutateAsync({\n programId: selectedProgramId,\n workoutId: form.workoutId === NO_WORKOUT ? undefined : form.workoutId,\n scheduledFor: form.scheduledFor ? new Date(form.scheduledFor).toISOString() : undefined,\n notes: form.notes.trim() ? form.notes.trim() : undefined,\n });\n analytics.emitFact('session', 'started', { workspaceId, entityId: created.id });\n setStartOpen(false);\n navigateTo(`train/${created.id}`);\n } catch (e) {\n setFormError(e instanceof Error ? e.message : 'Failed to start the session.');\n }\n };\n\n return (\n <PageLayout\n title=\"Train\"\n description=\"Live workout sessions — start, log sets, and complete.\"\n actions={\n <Button onClick={openStart}>\n <Plus className=\"h-4 w-4\" /> Start session\n </Button>\n }\n >\n <div className=\"mb-6\">\n <FilterTabs options={STATUS_TABS} value={filter} onChange={onFilterChange} />\n </div>\n\n {sessions.isLoading ? (\n <LoadingView label=\"Loading your sessions…\" />\n ) : sessions.isError ? (\n <ErrorView\n message=\"We couldn't load your workout sessions.\"\n onRetry={() => sessions.refetch()}\n />\n ) : rows.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Flame className=\"h-10 w-10\" />}\n title={filter === 'ALL' ? 'No sessions yet' : 'No sessions in this state'}\n description={\n filter === 'ALL'\n ? 'Start a workout session to begin logging sets and tracking your training.'\n : 'Try a different filter, or start a new workout session.'\n }\n action={\n <Button onClick={openStart}>\n <Plus className=\"h-4 w-4\" /> Start session\n </Button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3\">\n {rows.map((s, i) => {\n const meta = sessionMeta(s);\n const Icon = meta.icon;\n const isLive = s.status === 'IN_PROGRESS';\n const setCount = s.sets?.length;\n const rpe = s.perceivedExertion;\n return (\n <motion.button\n key={s.id}\n type=\"button\"\n onClick={() => navigateTo(`train/${s.id}`)}\n className=\"block w-full text-left\"\n initial={reduce ? false : { opacity: 0, y: 12 }}\n animate={{ opacity: 1, y: 0 }}\n transition={\n reduce\n ? { duration: 0 }\n : { duration: 0.35, delay: Math.min(i, 8) * 0.05, ease: MOTION_EASE }\n }\n whileHover={reduce ? undefined : { y: -3 }}\n whileTap={reduce ? undefined : { scale: 0.995 }}\n >\n <GlassCard\n treatment=\"plain\"\n glow={isLive}\n className={\n 'h-full p-4 transition-shadow hover:shadow-float' +\n (isLive\n ? ' ring-1 ring-inset ring-[color-mix(in_oklab,var(--color-action-primary-bg)_45%,transparent)]'\n : '')\n }\n >\n <div className=\"flex items-center justify-between gap-2\">\n <IconChip icon={<Icon className=\"h-4 w-4\" />} tint={meta.tint} />\n <StatusBadge status={s.status} />\n </div>\n <p className=\"mt-3 text-base font-semibold text-text-primary\">{meta.title}</p>\n <p className=\"mt-0.5 text-xs text-text-tertiary\">\n {meta.stampLabel} {formatRelativeTime(meta.stamp)}\n </p>\n\n <div className=\"mt-3 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary\">\n {s.caloriesBurned > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Flame className=\"h-3.5 w-3.5 text-status-warning-text\" />\n {formatKcal(s.caloriesBurned)}\n </span>\n )}\n {rpe != null && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <Gauge className=\"h-3.5 w-3.5 text-accent\" />\n RPE {rpe}/10\n </span>\n )}\n {setCount != null && setCount > 0 && (\n <span className=\"inline-flex items-center gap-1 tabular-nums\">\n <ListChecks className=\"h-3.5 w-3.5 text-accent\" />\n {formatNumber(setCount)} sets\n </span>\n )}\n </div>\n\n {rpe != null && (\n <div className=\"mt-3\">\n <div className=\"mb-1 flex items-center justify-between text-[11px] text-text-tertiary\">\n <span>RPE intensity</span>\n <span className=\"tabular-nums\">{rpe}/10</span>\n </div>\n <Meter value={rpe * 10} height={6} />\n </div>\n )}\n\n {isLive && (\n <p className=\"mt-3 inline-flex items-center gap-1 text-xs font-semibold text-action-primary-bg\">\n In progress — Resume →\n </p>\n )}\n </GlassCard>\n </motion.button>\n );\n })}\n </div>\n\n <Pagination\n page={pager.page}\n pageSize={PAGE_SIZE}\n itemCount={rows.length}\n hasMore={hasMore}\n onPageChange={(t) => pager.onPageChange(t)}\n />\n </>\n )}\n\n {/* Start session dialog */}\n <ResponsiveDialog open={startOpen} onOpenChange={setStartOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Start a workout session</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Begin a live session now, or schedule one for later. Attach an active program to keep\n your training organised.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"space-y-4 px-1\">\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-program\">Program (optional)</Label>\n <Select\n value={form.programId}\n onValueChange={(v) =>\n // Reset the workout choice too — the previous selection almost\n // certainly doesn't belong to the newly-picked program.\n setForm((f) => ({ ...f, programId: v, workoutId: NO_WORKOUT }))\n }\n >\n <SelectTrigger id=\"myb-start-program\">\n <SelectValue placeholder=\"No program\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NO_PROGRAM}>No program</SelectItem>\n {activePrograms.map((p) => (\n <SelectItem key={p.id} value={p.id}>\n {p.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {selectedProgramId && workoutOptions.length > 0 && (\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-workout\">Workout (optional)</Label>\n <Select\n value={form.workoutId}\n onValueChange={(v) => setForm((f) => ({ ...f, workoutId: v }))}\n >\n <SelectTrigger id=\"myb-start-workout\">\n <SelectValue placeholder=\"No specific workout\" />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NO_WORKOUT}>No specific workout</SelectItem>\n {workoutOptions.map((w) => (\n <SelectItem key={w.id} value={w.id}>\n {w.name} — Week {w.weekNumber}, Day {w.dayOfWeek}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <p className=\"text-xs text-text-tertiary\">\n Attach a planned workout to guide this session exercise-by-exercise.\n </p>\n </div>\n )}\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-scheduled\">Scheduled for (optional)</Label>\n <Input\n id=\"myb-start-scheduled\"\n type=\"datetime-local\"\n value={form.scheduledFor}\n onChange={(e) => setForm((f) => ({ ...f, scheduledFor: e.target.value }))}\n />\n <p className=\"text-xs text-text-tertiary\">\n Leave empty to start a live session right now.\n </p>\n </div>\n\n <div className=\"space-y-1.5\">\n <Label htmlFor=\"myb-start-notes\">Notes (optional)</Label>\n <Textarea\n id=\"myb-start-notes\"\n rows={3}\n value={form.notes}\n onChange={(e) => setForm((f) => ({ ...f, notes: e.target.value }))}\n placeholder=\"Focus, target lifts, how you're feeling…\"\n />\n </div>\n\n {formError && <p className=\"text-sm text-status-error-text\">{formError}</p>}\n </div>\n\n <ResponsiveDialogFooter>\n <Button\n variant=\"outline\"\n onClick={() => setStartOpen(false)}\n disabled={startSession.isPending}\n >\n Cancel\n </Button>\n <Button onClick={submitStart} disabled={startSession.isPending}>\n {startSession.isPending ? 'Starting…' : 'Start session'}\n </Button>\n </ResponsiveDialogFooter>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"assistant.d.ts","sourceRoot":"","sources":["../../../src/mybodyshield/types/assistant.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc,GAAG,WAAW,CAAC;AAEnF,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAEhG,MAAM,MAAM,2BAA2B,GACnC,MAAM,GACN,cAAc,GACd,YAAY,GACZ,WAAW,GACX,UAAU,GACV,OAAO,CAAC;AAEZ,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,QAAQ,CAAC,EAAE,wBAAwB,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,sBAAsB,CAAC;CAChC;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,2BAA2B,CAAC;IACpC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"assistant.d.ts","sourceRoot":"","sources":["../../../src/mybodyshield/types/assistant.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,WAAW,GAAG,cAAc,GAAG,WAAW,CAAC;AAEnF,MAAM,MAAM,sBAAsB,GAAG,MAAM,GAAG,cAAc,GAAG,SAAS,GAAG,UAAU,GAAG,OAAO,CAAC;AAEhG,MAAM,MAAM,2BAA2B,GACrC,MAAM,GAAG,cAAc,GAAG,YAAY,GAAG,WAAW,GAAG,UAAU,GAAG,OAAO,CAAC;AAE9E,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,WAAW,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,wBAAwB;IACvC,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAChC,IAAI,CAAC,EAAE,aAAa,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,GAAG,WAAW,GAAG,QAAQ,CAAC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,QAAQ,CAAC,EAAE,wBAAwB,CAAC;CACrC;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,aAAa,CAAC;IACpB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,uBAAuB;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,sBAAsB,CAAC;CAChC;AAED,MAAM,WAAW,+BAA+B;IAC9C,MAAM,EAAE,2BAA2B,CAAC;IACpC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB"}