@burdenoff/microfe-atheletebridge 2026.1029.1 → 2026.1031.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/dist/atheletebridge/components/ai/AiModelPicker.d.ts.map +1 -1
  2. package/dist/atheletebridge/components/ai/AiModelPicker.js +17 -3
  3. package/dist/atheletebridge/components/ai/AiModelPicker.js.map +1 -1
  4. package/dist/atheletebridge/components/ai/DecisionCard.d.ts.map +1 -1
  5. package/dist/atheletebridge/components/ai/DecisionCard.js +217 -122
  6. package/dist/atheletebridge/components/ai/DecisionCard.js.map +1 -1
  7. package/dist/atheletebridge/components/ai/SubjectDecisions.d.ts +29 -0
  8. package/dist/atheletebridge/components/ai/SubjectDecisions.d.ts.map +1 -0
  9. package/dist/atheletebridge/components/ai/SubjectDecisions.js +69 -0
  10. package/dist/atheletebridge/components/ai/SubjectDecisions.js.map +1 -0
  11. package/dist/atheletebridge/components/ai/index.d.ts +2 -0
  12. package/dist/atheletebridge/components/ai/index.d.ts.map +1 -1
  13. package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts +10 -1
  14. package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts.map +1 -1
  15. package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +25 -16
  16. package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
  17. package/dist/atheletebridge/pages/athletes/AthleteProfilePage.d.ts.map +1 -1
  18. package/dist/atheletebridge/pages/athletes/AthleteProfilePage.js +135 -118
  19. package/dist/atheletebridge/pages/athletes/AthleteProfilePage.js.map +1 -1
  20. package/dist/atheletebridge/pages/programs/ProgramDetailPage.d.ts.map +1 -1
  21. package/dist/atheletebridge/pages/programs/ProgramDetailPage.js +42 -34
  22. package/dist/atheletebridge/pages/programs/ProgramDetailPage.js.map +1 -1
  23. package/dist/atheletebridge/pages/teams/TeamDetailPage.d.ts.map +1 -1
  24. package/dist/atheletebridge/pages/teams/TeamDetailPage.js +65 -57
  25. package/dist/atheletebridge/pages/teams/TeamDetailPage.js.map +1 -1
  26. package/dist/atheletebridge/types/index.d.ts +6 -0
  27. package/dist/atheletebridge/types/index.d.ts.map +1 -1
  28. package/dist/atheletebridge/utils/aiDecision.d.ts +12 -0
  29. package/dist/atheletebridge/utils/aiDecision.d.ts.map +1 -1
  30. package/dist/atheletebridge/utils/aiDecision.js +11 -1
  31. package/dist/atheletebridge/utils/aiDecision.js.map +1 -1
  32. package/package.json +1 -1
@@ -6,18 +6,19 @@ import { RatingStars as i } from "../../components/viz/RatingStars.js";
6
6
  import "../../components/viz/index.js";
7
7
  import { StatusBadge as a } from "../../components/StatusBadge.js";
8
8
  import { MEMBER_ROLE_LABELS as o, METRIC_TYPE_LABELS as s, SPORT_LABELS as ee } from "../../components/domain.js";
9
- import { Crest as c } from "../../components/Crest.js";
10
- import { formatDate as l, formatDuration as te } from "../../utils/formatters.js";
11
- import { UserAvatar as ne } from "../../components/UserAvatar.js";
12
- import { SessionCard as u } from "../../components/SessionCard.js";
13
- import { EmptyState as d } from "../../components/EmptyState.js";
14
- import { ErrorState as f, LoadingState as re } from "../../components/LoadingState.js";
15
- import { useAthleteProfile as ie, useTeam as ae } from "../../hooks/useAthleteBridgeApi.js";
16
- import { useMemo as p, useState as oe } from "react";
17
- import { ArrowLeft as m, CalendarClock as h, Dumbbell as g, Gauge as _, LineChart as v, Ruler as y, Star as se, Users as ce, Weight as le } from "lucide-react";
18
- import { useParams as b } from "react-router";
19
- import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
20
- import { Badge as w, GlassCard as T, GradientText as E, ResponsiveTable as D, Tabs as O, TabsContent as k, TabsList as ue, TabsTrigger as A } from "@burdenoff/fe-libs/ui";
9
+ import { Crest as te } from "../../components/Crest.js";
10
+ import { formatDate as c, formatDuration as l } from "../../utils/formatters.js";
11
+ import { UserAvatar as u } from "../../components/UserAvatar.js";
12
+ import { SessionCard as d } from "../../components/SessionCard.js";
13
+ import { EmptyState as f } from "../../components/EmptyState.js";
14
+ import { ErrorState as ne, LoadingState as p } from "../../components/LoadingState.js";
15
+ import { useAthleteProfile as m, useTeam as h } from "../../hooks/useAthleteBridgeApi.js";
16
+ import { SubjectDecisions as g } from "../../components/ai/SubjectDecisions.js";
17
+ import { useMemo as _, useState as re } from "react";
18
+ import { ArrowLeft as ie, CalendarClock as v, Dumbbell as y, Gauge as ae, LineChart as oe, Ruler as se, Sparkles as ce, Star as b, Users as x, Weight as S } from "lucide-react";
19
+ import { useParams as C } from "react-router";
20
+ import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
21
+ import { Badge as D, GlassCard as O, GradientText as le, ResponsiveTable as ue, Tabs as de, TabsContent as k, TabsList as fe, TabsTrigger as A } from "@burdenoff/fe-libs/ui";
21
22
  //#region src/atheletebridge/pages/athletes/AthleteProfilePage.tsx
22
23
  var j = [
23
24
  "1M",
@@ -71,14 +72,14 @@ function F(e, t) {
71
72
  }).sort((e, t) => t.points.length - e.points.length);
72
73
  }
73
74
  function I() {
74
- let { teamId: j, memberId: M } = b(), { navigateTo: I } = e(), z = ie(j, M), B = ae(j), [V, H] = oe("6M"), U = p(() => N(V), [V]), W = p(() => F(z.metrics, U), [z.metrics, U]), G = p(() => F(z.metrics, 0), [z.metrics]), K = p(() => z.sessions.filter((e) => e.rating !== null), [z.sessions]), q = p(() => K.length > 0 ? K.reduce((e, t) => e + (t.rating ?? 0), 0) / K.length : null, [K]), J = p(() => z.sessions.filter((e) => e.status === "REQUESTED" || e.status === "CONFIRMED").sort((e, t) => new Date(e.scheduledAt).getTime() - new Date(t.scheduledAt).getTime()), [z.sessions]), Y = p(() => [...z.workouts].sort((e, t) => new Date(t.performedAt).getTime() - new Date(e.performedAt).getTime()), [z.workouts]), de = p(() => z.sessions.filter((e) => e.status === "COMPLETED").length, [z.sessions]);
75
- if (z.isLoading) return /* @__PURE__ */ S(t, {
75
+ let { teamId: j, memberId: M } = C(), { navigateTo: I } = e(), z = m(j, M), B = h(j), [V, H] = re("6M"), U = _(() => N(V), [V]), W = _(() => F(z.metrics, U), [z.metrics, U]), G = _(() => F(z.metrics, 0), [z.metrics]), K = _(() => z.sessions.filter((e) => e.rating !== null), [z.sessions]), q = _(() => K.length > 0 ? K.reduce((e, t) => e + (t.rating ?? 0), 0) / K.length : null, [K]), J = _(() => z.sessions.filter((e) => e.status === "REQUESTED" || e.status === "CONFIRMED").sort((e, t) => new Date(e.scheduledAt).getTime() - new Date(t.scheduledAt).getTime()), [z.sessions]), Y = _(() => [...z.workouts].sort((e, t) => new Date(t.performedAt).getTime() - new Date(e.performedAt).getTime()), [z.workouts]), pe = _(() => z.sessions.filter((e) => e.status === "COMPLETED").length, [z.sessions]);
76
+ if (z.isLoading) return /* @__PURE__ */ T(t, {
76
77
  title: "Athlete",
77
- children: /* @__PURE__ */ S(re, { label: "Loading athlete profile…" })
78
+ children: /* @__PURE__ */ T(p, { label: "Loading athlete profile…" })
78
79
  });
79
- if (z.isError || !z.member) return /* @__PURE__ */ S(t, {
80
+ if (z.isError || !z.member) return /* @__PURE__ */ T(t, {
80
81
  title: "Athlete",
81
- children: /* @__PURE__ */ S(f, {
82
+ children: /* @__PURE__ */ T(ne, {
82
83
  title: "Athlete not found",
83
84
  message: "This athlete is not on the roster, or you do not have access.",
84
85
  onRetry: () => I(j ? `/teams/${j}` : "/teams")
@@ -86,89 +87,89 @@ function I() {
86
87
  });
87
88
  let X = z.member, Z = B.data?.name ?? null, Q = B.data?.sport, $ = [];
88
89
  X.height != null && $.push({
89
- icon: /* @__PURE__ */ S(y, { className: "h-4 w-4" }),
90
+ icon: /* @__PURE__ */ T(se, { className: "h-4 w-4" }),
90
91
  label: "Height",
91
92
  value: String(X.height)
92
93
  }), X.weight != null && $.push({
93
- icon: /* @__PURE__ */ S(le, { className: "h-4 w-4" }),
94
+ icon: /* @__PURE__ */ T(S, { className: "h-4 w-4" }),
94
95
  label: "Weight",
95
96
  value: String(X.weight)
96
97
  }), X.dominantSide && $.push({
97
- icon: /* @__PURE__ */ S(_, { className: "h-4 w-4" }),
98
+ icon: /* @__PURE__ */ T(ae, { className: "h-4 w-4" }),
98
99
  label: "Dominant side",
99
100
  value: X.dominantSide
100
101
  }), X.position && $.push({
101
- icon: /* @__PURE__ */ S(ce, { className: "h-4 w-4" }),
102
+ icon: /* @__PURE__ */ T(x, { className: "h-4 w-4" }),
102
103
  label: "Position",
103
104
  value: X.position
104
105
  }), X.joinedAt && $.push({
105
- icon: /* @__PURE__ */ S(h, { className: "h-4 w-4" }),
106
+ icon: /* @__PURE__ */ T(v, { className: "h-4 w-4" }),
106
107
  label: "Joined",
107
- value: l(X.joinedAt)
108
+ value: c(X.joinedAt)
108
109
  });
109
- let fe = W[0] ?? null;
110
- return /* @__PURE__ */ C(t, {
111
- title: /* @__PURE__ */ S(E, { children: X.displayName }),
110
+ let me = W[0] ?? null;
111
+ return /* @__PURE__ */ E(t, {
112
+ title: /* @__PURE__ */ T(le, { children: X.displayName }),
112
113
  description: Z ? `${Z}${Q ? ` · ${ee[Q]}` : ""}` : void 0,
113
- actions: /* @__PURE__ */ C("button", {
114
+ actions: /* @__PURE__ */ E("button", {
114
115
  type: "button",
115
116
  onClick: () => I(j ? `/teams/${j}` : "/teams"),
116
117
  className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
117
- children: [/* @__PURE__ */ S(m, { className: "h-4 w-4" }), " Back to team"]
118
+ children: [/* @__PURE__ */ T(ie, { className: "h-4 w-4" }), " Back to team"]
118
119
  }),
119
- children: [/* @__PURE__ */ S(T, {
120
+ children: [/* @__PURE__ */ T(O, {
120
121
  treatment: "insight",
121
122
  className: "mb-8 p-6",
122
- children: /* @__PURE__ */ C("div", {
123
+ children: /* @__PURE__ */ E("div", {
123
124
  className: "flex flex-col gap-6 md:flex-row md:items-start",
124
- children: [/* @__PURE__ */ S(ne, {
125
+ children: [/* @__PURE__ */ T(u, {
125
126
  name: X.displayName,
126
127
  id: X.userId,
127
128
  jersey: X.jerseyNumber,
128
129
  size: "xl",
129
130
  ring: !0,
130
131
  className: "shrink-0"
131
- }), /* @__PURE__ */ C("div", {
132
+ }), /* @__PURE__ */ E("div", {
132
133
  className: "min-w-0 flex-1",
133
- children: [/* @__PURE__ */ C("div", {
134
+ children: [/* @__PURE__ */ E("div", {
134
135
  className: "flex flex-wrap items-center gap-2",
135
136
  children: [
136
- /* @__PURE__ */ S(w, {
137
+ /* @__PURE__ */ T(D, {
137
138
  variant: "default",
138
139
  children: o[X.role]
139
140
  }),
140
- X.position ? /* @__PURE__ */ S(w, {
141
+ X.position ? /* @__PURE__ */ T(D, {
141
142
  variant: "secondary",
142
143
  children: X.position
143
144
  }) : null,
144
- X.jerseyNumber == null ? null : /* @__PURE__ */ C(w, {
145
+ X.jerseyNumber == null ? null : /* @__PURE__ */ E(D, {
145
146
  variant: "outline",
146
147
  className: "tabular-nums",
147
148
  children: ["#", X.jerseyNumber]
148
149
  }),
149
- Z ? /* @__PURE__ */ C(w, {
150
+ Z ? /* @__PURE__ */ E(D, {
150
151
  variant: "secondary",
151
152
  className: "gap-1.5",
152
- children: [/* @__PURE__ */ S(c, {
153
+ children: [/* @__PURE__ */ T(te, {
153
154
  name: Z,
154
155
  sport: Q,
155
156
  size: 16,
156
157
  showSportGlyph: !1
157
158
  }), Z]
158
159
  }) : null,
159
- /* @__PURE__ */ S(a, { status: X.status })
160
+ /* @__PURE__ */ T(a, { status: X.status })
160
161
  ]
161
- }), $.length > 0 ? /* @__PURE__ */ S("dl", {
162
+ }), $.length > 0 ? /* @__PURE__ */ T("dl", {
162
163
  className: "mt-5 grid grid-cols-2 gap-x-6 gap-y-4 sm:grid-cols-3 lg:grid-cols-5",
163
- children: $.map((e) => /* @__PURE__ */ C("div", {
164
+ children: $.map((e) => /* @__PURE__ */ E("div", {
164
165
  className: "min-w-0",
165
- children: [/* @__PURE__ */ C("dt", {
166
+ children: [/* @__PURE__ */ E("dt", {
166
167
  className: "flex items-center gap-1.5 text-xs font-medium text-text-secondary",
167
- children: [/* @__PURE__ */ S("span", {
168
+ children: [/* @__PURE__ */ T("span", {
168
169
  className: "text-text-muted",
169
170
  children: e.icon
170
171
  }), e.label]
171
- }), /* @__PURE__ */ S("dd", {
172
+ }), /* @__PURE__ */ T("dd", {
172
173
  className: "mt-1 truncate text-lg font-semibold text-text-primary",
173
174
  children: e.value
174
175
  })]
@@ -176,47 +177,51 @@ function I() {
176
177
  }) : null]
177
178
  })]
178
179
  })
179
- }), /* @__PURE__ */ C(O, {
180
+ }), /* @__PURE__ */ E(de, {
180
181
  defaultValue: "overview",
181
182
  children: [
182
- /* @__PURE__ */ C(ue, {
183
+ /* @__PURE__ */ E(fe, {
183
184
  className: "mb-6 flex-wrap",
184
185
  children: [
185
- /* @__PURE__ */ S(A, {
186
+ /* @__PURE__ */ T(A, {
186
187
  value: "overview",
187
188
  children: "Overview"
188
189
  }),
189
- /* @__PURE__ */ S(A, {
190
+ /* @__PURE__ */ T(A, {
190
191
  value: "metrics",
191
192
  children: "Metrics"
192
193
  }),
193
- /* @__PURE__ */ S(A, {
194
+ /* @__PURE__ */ T(A, {
194
195
  value: "workouts",
195
196
  children: "Workouts"
196
197
  }),
197
- /* @__PURE__ */ S(A, {
198
+ /* @__PURE__ */ T(A, {
198
199
  value: "sessions",
199
200
  children: "Sessions"
201
+ }),
202
+ /* @__PURE__ */ T(A, {
203
+ value: "ai",
204
+ children: "AI decisions"
200
205
  })
201
206
  ]
202
207
  }),
203
- /* @__PURE__ */ C(k, {
208
+ /* @__PURE__ */ E(k, {
204
209
  value: "overview",
205
210
  className: "space-y-8",
206
211
  children: [
207
- /* @__PURE__ */ C("div", {
212
+ /* @__PURE__ */ E("div", {
208
213
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
209
214
  children: [
210
- /* @__PURE__ */ C(T, {
215
+ /* @__PURE__ */ E(O, {
211
216
  treatment: "metric",
212
217
  className: "flex flex-col gap-2 p-5",
213
- children: [/* @__PURE__ */ S("span", {
218
+ children: [/* @__PURE__ */ T("span", {
214
219
  className: "text-sm font-medium text-text-secondary",
215
220
  children: "Avg session rating"
216
- }), q == null ? /* @__PURE__ */ S("span", {
221
+ }), q == null ? /* @__PURE__ */ T("span", {
217
222
  className: "text-sm text-text-muted",
218
223
  children: "No rated sessions yet"
219
- }) : /* @__PURE__ */ S(x, { children: /* @__PURE__ */ S(i, {
224
+ }) : /* @__PURE__ */ T(w, { children: /* @__PURE__ */ T(i, {
220
225
  value: q,
221
226
  max: 5,
222
227
  size: 20,
@@ -224,29 +229,29 @@ function I() {
224
229
  count: K.length
225
230
  }) })]
226
231
  }),
227
- /* @__PURE__ */ S(r, {
232
+ /* @__PURE__ */ T(r, {
228
233
  label: "Sessions",
229
234
  value: z.sessions.length,
230
- icon: /* @__PURE__ */ S(h, { className: "h-4 w-4" })
235
+ icon: /* @__PURE__ */ T(v, { className: "h-4 w-4" })
231
236
  }),
232
- /* @__PURE__ */ S(r, {
237
+ /* @__PURE__ */ T(r, {
233
238
  label: "Completed",
234
- value: de,
235
- icon: /* @__PURE__ */ S(se, { className: "h-4 w-4" })
239
+ value: pe,
240
+ icon: /* @__PURE__ */ T(b, { className: "h-4 w-4" })
236
241
  }),
237
- /* @__PURE__ */ S(r, {
242
+ /* @__PURE__ */ T(r, {
238
243
  label: "Workouts logged",
239
244
  value: z.workouts.length,
240
- icon: /* @__PURE__ */ S(g, { className: "h-4 w-4" })
245
+ icon: /* @__PURE__ */ T(y, { className: "h-4 w-4" })
241
246
  })
242
247
  ]
243
248
  }),
244
- G.some((e) => e.deltaPct != null) ? /* @__PURE__ */ C("section", { children: [/* @__PURE__ */ S("h2", {
249
+ G.some((e) => e.deltaPct != null) ? /* @__PURE__ */ E("section", { children: [/* @__PURE__ */ T("h2", {
245
250
  className: "mb-4 text-lg font-semibold text-text-primary",
246
251
  children: "Improvement"
247
- }), /* @__PURE__ */ S("div", {
252
+ }), /* @__PURE__ */ T("div", {
248
253
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4",
249
- children: G.filter((e) => e.deltaPct != null).slice(0, 4).map((e) => /* @__PURE__ */ S(r, {
254
+ children: G.filter((e) => e.deltaPct != null).slice(0, 4).map((e) => /* @__PURE__ */ T(r, {
250
255
  label: `${s[e.type]}${e.unit ? ` (${e.unit})` : ""}`,
251
256
  value: e.last.toLocaleString(),
252
257
  delta: e.deltaPct ?? void 0,
@@ -254,28 +259,28 @@ function I() {
254
259
  sparkline: e.points.map((e) => e.value)
255
260
  }, e.type))
256
261
  })] }) : null,
257
- /* @__PURE__ */ S(R, {
262
+ /* @__PURE__ */ T(R, {
258
263
  title: "Performance trend",
259
264
  groups: W,
260
- primary: fe,
265
+ primary: me,
261
266
  range: V,
262
267
  onRangeChange: H
263
268
  }),
264
- /* @__PURE__ */ C("section", { children: [/* @__PURE__ */ C("h2", {
269
+ /* @__PURE__ */ E("section", { children: [/* @__PURE__ */ E("h2", {
265
270
  className: "mb-4 text-lg font-semibold text-text-primary",
266
271
  children: [
267
272
  "Upcoming sessions (",
268
273
  J.length,
269
274
  ")"
270
275
  ]
271
- }), J.length === 0 ? /* @__PURE__ */ S(d, {
276
+ }), J.length === 0 ? /* @__PURE__ */ T(f, {
272
277
  illustration: "empty-calendar",
273
- icon: /* @__PURE__ */ S(h, { className: "h-10 w-10" }),
278
+ icon: /* @__PURE__ */ T(v, { className: "h-10 w-10" }),
274
279
  title: "No upcoming sessions",
275
280
  description: "Confirmed and requested coaching sessions for this athlete appear here."
276
- }) : /* @__PURE__ */ S("div", {
281
+ }) : /* @__PURE__ */ T("div", {
277
282
  className: "grid grid-cols-1 gap-4 md:grid-cols-2",
278
- children: J.slice(0, 6).map((e) => /* @__PURE__ */ S(u, {
283
+ children: J.slice(0, 6).map((e) => /* @__PURE__ */ T(d, {
279
284
  session: e,
280
285
  athleteName: X.displayName,
281
286
  onClick: () => I(`/sessions/${e.id}`)
@@ -283,41 +288,41 @@ function I() {
283
288
  })] })
284
289
  ]
285
290
  }),
286
- /* @__PURE__ */ C(k, {
291
+ /* @__PURE__ */ E(k, {
287
292
  value: "metrics",
288
293
  className: "space-y-8",
289
- children: [/* @__PURE__ */ C("div", {
294
+ children: [/* @__PURE__ */ E("div", {
290
295
  className: "flex flex-wrap items-center justify-between gap-3",
291
- children: [/* @__PURE__ */ S("h2", {
296
+ children: [/* @__PURE__ */ T("h2", {
292
297
  className: "text-lg font-semibold text-text-primary",
293
298
  children: "Performance metrics"
294
- }), /* @__PURE__ */ S(L, {
299
+ }), /* @__PURE__ */ T(L, {
295
300
  value: V,
296
301
  onChange: H
297
302
  })]
298
- }), W.length === 0 ? /* @__PURE__ */ S(d, {
303
+ }), W.length === 0 ? /* @__PURE__ */ T(f, {
299
304
  illustration: "empty-data",
300
- icon: /* @__PURE__ */ S(v, { className: "h-10 w-10" }),
305
+ icon: /* @__PURE__ */ T(oe, { className: "h-10 w-10" }),
301
306
  title: "No metrics in this range",
302
307
  description: "Record metrics for this athlete — speed, strength, endurance — to chart progress over time."
303
- }) : /* @__PURE__ */ S("div", {
308
+ }) : /* @__PURE__ */ T("div", {
304
309
  className: "grid grid-cols-1 gap-4 lg:grid-cols-2",
305
- children: W.map((e) => /* @__PURE__ */ C(T, {
310
+ children: W.map((e) => /* @__PURE__ */ E(O, {
306
311
  treatment: "metric",
307
312
  className: "p-5",
308
313
  children: [
309
- /* @__PURE__ */ C("div", {
314
+ /* @__PURE__ */ E("div", {
310
315
  className: "mb-3 flex items-start justify-between gap-3",
311
- children: [/* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("h3", {
316
+ children: [/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("h3", {
312
317
  className: "text-sm font-semibold uppercase tracking-wide text-text-secondary",
313
318
  children: s[e.type]
314
- }), /* @__PURE__ */ C("p", {
319
+ }), /* @__PURE__ */ E("p", {
315
320
  className: "mt-1 text-2xl font-semibold tabular-nums text-text-primary",
316
- children: [e.last.toLocaleString(), e.unit ? /* @__PURE__ */ S("span", {
321
+ children: [e.last.toLocaleString(), e.unit ? /* @__PURE__ */ T("span", {
317
322
  className: "ml-1 text-sm text-text-secondary",
318
323
  children: e.unit
319
324
  }) : null]
320
- })] }), e.deltaPct == null ? null : /* @__PURE__ */ C(w, {
325
+ })] }), e.deltaPct == null ? null : /* @__PURE__ */ E(D, {
321
326
  variant: e.deltaPct >= 0 ? "default" : "destructive",
322
327
  className: "tabular-nums",
323
328
  children: [
@@ -327,7 +332,7 @@ function I() {
327
332
  ]
328
333
  })]
329
334
  }),
330
- /* @__PURE__ */ S(n, {
335
+ /* @__PURE__ */ T(n, {
331
336
  series: e.points.map((e) => ({
332
337
  label: P(e.recordedAt),
333
338
  value: e.value
@@ -336,7 +341,7 @@ function I() {
336
341
  height: 160,
337
342
  valueFormatter: (t) => `${t.toLocaleString()}${e.unit ? ` ${e.unit}` : ""}`
338
343
  }),
339
- /* @__PURE__ */ C("p", {
344
+ /* @__PURE__ */ E("p", {
340
345
  className: "mt-2 text-xs text-text-muted tabular-nums",
341
346
  children: [
342
347
  "Peak ",
@@ -351,20 +356,20 @@ function I() {
351
356
  }, e.type))
352
357
  })]
353
358
  }),
354
- /* @__PURE__ */ S(k, {
359
+ /* @__PURE__ */ T(k, {
355
360
  value: "workouts",
356
- children: Y.length === 0 ? /* @__PURE__ */ S(d, {
361
+ children: Y.length === 0 ? /* @__PURE__ */ T(f, {
357
362
  illustration: "empty-data",
358
- icon: /* @__PURE__ */ S(g, { className: "h-10 w-10" }),
363
+ icon: /* @__PURE__ */ T(y, { className: "h-10 w-10" }),
359
364
  title: "No workouts logged",
360
365
  description: "This athlete's logged training sessions will appear here."
361
- }) : /* @__PURE__ */ S(D, {
366
+ }) : /* @__PURE__ */ T(ue, {
362
367
  columns: [
363
368
  {
364
369
  key: "title",
365
370
  header: "Workout",
366
371
  priority: "primary",
367
- cell: (e) => /* @__PURE__ */ S("span", {
372
+ cell: (e) => /* @__PURE__ */ T("span", {
368
373
  className: "font-medium text-text-primary",
369
374
  children: e.title
370
375
  })
@@ -373,16 +378,16 @@ function I() {
373
378
  key: "duration",
374
379
  header: "Duration",
375
380
  priority: "secondary",
376
- cell: (e) => /* @__PURE__ */ S("span", {
381
+ cell: (e) => /* @__PURE__ */ T("span", {
377
382
  className: "tabular-nums text-text-secondary",
378
- children: e.durationMin == null ? "—" : te(e.durationMin)
383
+ children: e.durationMin == null ? "—" : l(e.durationMin)
379
384
  })
380
385
  },
381
386
  {
382
387
  key: "load",
383
388
  header: "Load",
384
389
  priority: "hidden-on-mobile",
385
- cell: (e) => /* @__PURE__ */ S("span", {
390
+ cell: (e) => /* @__PURE__ */ T("span", {
386
391
  className: "tabular-nums text-text-secondary",
387
392
  children: e.totalLoad == null ? "—" : e.totalLoad.toLocaleString()
388
393
  })
@@ -391,7 +396,7 @@ function I() {
391
396
  key: "rpe",
392
397
  header: "RPE",
393
398
  priority: "hidden-on-mobile",
394
- cell: (e) => /* @__PURE__ */ S("span", {
399
+ cell: (e) => /* @__PURE__ */ T("span", {
395
400
  className: "tabular-nums text-text-secondary",
396
401
  children: e.rpe == null ? "—" : e.rpe
397
402
  })
@@ -400,15 +405,15 @@ function I() {
400
405
  key: "status",
401
406
  header: "Status",
402
407
  priority: "secondary",
403
- cell: (e) => /* @__PURE__ */ S(a, { status: e.status })
408
+ cell: (e) => /* @__PURE__ */ T(a, { status: e.status })
404
409
  },
405
410
  {
406
411
  key: "date",
407
412
  header: "Date",
408
413
  priority: "secondary",
409
- cell: (e) => /* @__PURE__ */ S("span", {
414
+ cell: (e) => /* @__PURE__ */ T("span", {
410
415
  className: "whitespace-nowrap text-text-secondary",
411
- children: l(e.performedAt)
416
+ children: c(e.performedAt)
412
417
  })
413
418
  }
414
419
  ],
@@ -416,34 +421,46 @@ function I() {
416
421
  rowKey: (e) => e.id
417
422
  })
418
423
  }),
419
- /* @__PURE__ */ S(k, {
424
+ /* @__PURE__ */ T(k, {
420
425
  value: "sessions",
421
- children: z.sessions.length === 0 ? /* @__PURE__ */ S(d, {
426
+ children: z.sessions.length === 0 ? /* @__PURE__ */ T(f, {
422
427
  illustration: "empty-calendar",
423
- icon: /* @__PURE__ */ S(h, { className: "h-10 w-10" }),
428
+ icon: /* @__PURE__ */ T(v, { className: "h-10 w-10" }),
424
429
  title: "No coaching sessions",
425
430
  description: "Booked, completed and cancelled sessions for this athlete will appear here."
426
- }) : /* @__PURE__ */ S("div", {
431
+ }) : /* @__PURE__ */ T("div", {
427
432
  className: "grid grid-cols-1 gap-4 md:grid-cols-2",
428
- children: [...z.sessions].sort((e, t) => new Date(t.scheduledAt).getTime() - new Date(e.scheduledAt).getTime()).map((e) => /* @__PURE__ */ S(u, {
433
+ children: [...z.sessions].sort((e, t) => new Date(t.scheduledAt).getTime() - new Date(e.scheduledAt).getTime()).map((e) => /* @__PURE__ */ T(d, {
429
434
  session: e,
430
435
  athleteName: X.displayName,
431
436
  onClick: () => I(`/sessions/${e.id}`)
432
437
  }, e.id))
433
438
  })
439
+ }),
440
+ /* @__PURE__ */ T(k, {
441
+ value: "ai",
442
+ children: X.userId ? /* @__PURE__ */ T(g, { subject: {
443
+ kind: "athlete",
444
+ athleteId: X.userId
445
+ } }) : /* @__PURE__ */ T(f, {
446
+ illustration: "empty-data",
447
+ icon: /* @__PURE__ */ T(ce, { className: "h-10 w-10" }),
448
+ title: "No AI decisions for this roster entry",
449
+ description: "AI assessments are keyed to an athlete's account. Link this roster entry to a user to see the decisions made about them."
450
+ })
434
451
  })
435
452
  ]
436
453
  })]
437
454
  });
438
455
  }
439
456
  function L({ value: e, onChange: t }) {
440
- return /* @__PURE__ */ S("div", {
457
+ return /* @__PURE__ */ T("div", {
441
458
  role: "group",
442
459
  "aria-label": "Trend range",
443
460
  className: "inline-flex items-center gap-1 rounded-lg border border-border-seam bg-bg-surface p-1",
444
461
  children: j.map((n) => {
445
462
  let r = n === e;
446
- return /* @__PURE__ */ S("button", {
463
+ return /* @__PURE__ */ T("button", {
447
464
  type: "button",
448
465
  "aria-pressed": r,
449
466
  onClick: () => t(n),
@@ -455,30 +472,30 @@ function L({ value: e, onChange: t }) {
455
472
  }
456
473
  function R({ title: e, groups: t, primary: r, range: i, onRangeChange: a }) {
457
474
  let o = t.find((e) => e.type !== r?.type) ?? null;
458
- return /* @__PURE__ */ C(T, {
475
+ return /* @__PURE__ */ E(O, {
459
476
  treatment: "metric",
460
477
  className: "p-5",
461
- children: [/* @__PURE__ */ C("div", {
478
+ children: [/* @__PURE__ */ E("div", {
462
479
  className: "mb-4 flex flex-wrap items-center justify-between gap-3",
463
- children: [/* @__PURE__ */ C("div", { children: [/* @__PURE__ */ S("h2", {
480
+ children: [/* @__PURE__ */ E("div", { children: [/* @__PURE__ */ T("h2", {
464
481
  className: "text-lg font-semibold text-text-primary",
465
482
  children: e
466
- }), r ? /* @__PURE__ */ C("div", {
483
+ }), r ? /* @__PURE__ */ E("div", {
467
484
  className: "mt-1 flex flex-wrap items-center gap-x-4 gap-y-1 text-xs text-text-secondary",
468
- children: [/* @__PURE__ */ C("span", {
485
+ children: [/* @__PURE__ */ E("span", {
469
486
  className: "inline-flex items-center gap-1.5",
470
487
  children: [
471
- /* @__PURE__ */ S("span", {
488
+ /* @__PURE__ */ T("span", {
472
489
  className: "h-2 w-2 rounded-full bg-[var(--color-accent-primary)]",
473
490
  "aria-hidden": "true"
474
491
  }),
475
492
  s[r.type],
476
493
  r.unit ? ` (${r.unit})` : ""
477
494
  ]
478
- }), o ? /* @__PURE__ */ C("span", {
495
+ }), o ? /* @__PURE__ */ E("span", {
479
496
  className: "inline-flex items-center gap-1.5",
480
497
  children: [
481
- /* @__PURE__ */ S("span", {
498
+ /* @__PURE__ */ T("span", {
482
499
  className: "h-2 w-2 rounded-full bg-[var(--color-accent-teal)]",
483
500
  "aria-hidden": "true"
484
501
  }),
@@ -486,11 +503,11 @@ function R({ title: e, groups: t, primary: r, range: i, onRangeChange: a }) {
486
503
  o.unit ? ` (${o.unit})` : ""
487
504
  ]
488
505
  }) : null]
489
- }) : null] }), /* @__PURE__ */ S(L, {
506
+ }) : null] }), /* @__PURE__ */ T(L, {
490
507
  value: i,
491
508
  onChange: a
492
509
  })]
493
- }), r ? /* @__PURE__ */ S(n, {
510
+ }), r ? /* @__PURE__ */ T(n, {
494
511
  series: r.points.map((e) => ({
495
512
  label: P(e.recordedAt),
496
513
  value: e.value
@@ -499,7 +516,7 @@ function R({ title: e, groups: t, primary: r, range: i, onRangeChange: a }) {
499
516
  seriesLabel: s[r.type],
500
517
  compareLabel: o ? s[o.type] : void 0,
501
518
  height: 240
502
- }) : /* @__PURE__ */ S("div", {
519
+ }) : /* @__PURE__ */ T("div", {
503
520
  className: "flex h-40 items-center justify-center text-sm text-text-muted",
504
521
  children: "No metric readings in this range."
505
522
  })]