@burdenoff/microfe-atheletebridge 2026.801.3 → 2026.827.1

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.
@@ -1,122 +1,193 @@
1
- import { cn as e } from "../../utils/cn.js";
2
- import { PageLayout as t } from "../../components/PageLayout.js";
3
- import { Sparkline as n } from "../../components/viz/Sparkline.js";
1
+ import { useAbTranslate as e } from "../../i18n.js";
2
+ import { cn as t } from "../../utils/cn.js";
3
+ import { PageLayout as n } from "../../components/PageLayout.js";
4
+ import { Sparkline as r } from "../../components/viz/Sparkline.js";
4
5
  import "../../components/viz/index.js";
5
- import { StatusBadge as r } from "../../components/StatusBadge.js";
6
- import { METRIC_TYPE_LABELS as i } from "../../components/domain.js";
7
- import { formatDate as a, formatDuration as o } from "../../utils/formatters.js";
8
- import { EmptyState as s } from "../../components/EmptyState.js";
9
- import { ErrorState as c, LoadingState as l } from "../../components/LoadingState.js";
10
- import { useLogWorkout as u, usePerformanceMetrics as d, useRecordMetric as f, useWorkoutLogs as p } from "../../hooks/useAthleteBridgeApi.js";
11
- import { CursorPager as m } from "../../components/CursorPager.js";
12
- import { FormField as h, fieldInputClass as g } from "../../components/form.js";
13
- import { AthleteSelect as _ } from "../../components/AthleteSelect.js";
14
- import { useMemo as v, useState as y } from "react";
15
- import { Activity as b, ArrowDown as x, ArrowUp as S, Dumbbell as C, Gauge as w, HeartPulse as T, Loader2 as E, Move as D, Plus as O, Save as k, Scale as A, Target as j, Users as M, Zap as N } from "lucide-react";
16
- import { Fragment as P, jsx as F, jsxs as I } from "react/jsx-runtime";
17
- import { GlassCard as L, ResponsiveDialog as R, ResponsiveDialogContent as z, ResponsiveDialogFooter as B, ResponsiveDialogHeader as V, ResponsiveDialogTitle as H, ResponsiveTable as U } from "@burdenoff/fe-libs/ui";
6
+ import { StatusBadge as i } from "../../components/StatusBadge.js";
7
+ import { METRIC_TYPE_LABELS as a } from "../../components/domain.js";
8
+ import { formatDate as o, formatDuration as s } from "../../utils/formatters.js";
9
+ import { EmptyState as c } from "../../components/EmptyState.js";
10
+ import { ErrorState as l, LoadingState as u } from "../../components/LoadingState.js";
11
+ import { useLogWorkout as d, usePerformanceMetrics as f, useRecordMetric as p, useWorkoutLogs as m } from "../../hooks/useAthleteBridgeApi.js";
12
+ import { CursorPager as h } from "../../components/CursorPager.js";
13
+ import { FilterSelect as g } from "../../components/FilterSelect.js";
14
+ import { FormField as _, fieldInputClass as v } from "../../components/form.js";
15
+ import { AthleteSelect as y } from "../../components/AthleteSelect.js";
16
+ import { useMemo as b, useState as x } from "react";
17
+ import { Activity as S, ArrowDown as C, ArrowUp as w, CalendarRange as T, Dumbbell as E, Gauge as D, HeartPulse as O, Loader2 as k, Move as A, Plus as j, Save as M, Scale as N, Target as P, Users as F, Zap as I } from "lucide-react";
18
+ import { Fragment as L, jsx as R, jsxs as z } from "react/jsx-runtime";
19
+ import { GlassCard as B, ResponsiveDialog as V, ResponsiveDialogContent as H, ResponsiveDialogFooter as U, ResponsiveDialogHeader as W, ResponsiveDialogTitle as G, ResponsiveTable as ee } from "@burdenoff/fe-libs/ui";
18
20
  //#region src/atheletebridge/pages/performance/PerformancePage.tsx
19
- var W = 10, G = [
21
+ var K = 10, q = [
20
22
  "COMPLETED",
21
23
  "PLANNED",
22
24
  "SKIPPED"
23
- ], K = Object.keys(i), q = "inline-flex items-center justify-center gap-1.5 rounded-lg px-4 py-2 text-sm font-semibold text-action-primary-text shadow-elevation-1 transition-[filter,box-shadow] hover:shadow-elevation-2 hover:brightness-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] bg-[linear-gradient(120deg,var(--color-action-primary-bg),color-mix(in_oklab,var(--color-action-primary-bg)_62%,var(--color-accent-purple)),var(--color-action-primary-bg))]", J = {
24
- SPEED: N,
25
- ENDURANCE: b,
26
- STRENGTH: C,
27
- AGILITY: D,
28
- ACCURACY: j,
29
- WEIGHT: A,
30
- HEART_RATE: T,
31
- CUSTOM: w
32
- }, Y = (e) => {
25
+ ], J = Object.keys(a), te = 100, ne = { limit: 100 }, re = [
26
+ "7d",
27
+ "28d",
28
+ "90d"
29
+ ], Y = {
30
+ "7d": 7,
31
+ "28d": 28,
32
+ "90d": 90
33
+ }, ie = (e) => {
34
+ let t = /* @__PURE__ */ new Date();
35
+ t.setHours(23, 59, 59, 999);
36
+ let n = new Date(t);
37
+ return n.setHours(0, 0, 0, 0), n.setDate(n.getDate() - (Y[e] - 1)), {
38
+ start: n.getTime(),
39
+ end: t.getTime()
40
+ };
41
+ }, X = (e) => new Date(e).getTime(), ae = (e) => o(new Date(e), {
42
+ hour: void 0,
43
+ minute: void 0,
44
+ hour12: void 0
45
+ }), oe = (e) => `${ae(e.start)} – ${ae(e.end)}`, se = (e, t) => {
46
+ switch (e) {
47
+ case "7d": return t("atheletebridge.pages.performance.window.last7", "Last 7 days");
48
+ case "28d": return t("atheletebridge.pages.performance.window.last28", "Last 28 days");
49
+ case "90d": return t("atheletebridge.pages.performance.window.last90", "Last 90 days");
50
+ }
51
+ }, ce = (e, t) => {
52
+ switch (e) {
53
+ case "7d": return t("atheletebridge.pages.performance.window.vsLast7", "vs previous 7 days");
54
+ case "28d": return t("atheletebridge.pages.performance.window.vsLast28", "vs previous 28 days");
55
+ case "90d": return t("atheletebridge.pages.performance.window.vsLast90", "vs previous 90 days");
56
+ }
57
+ }, le = (e, t) => {
58
+ switch (e) {
59
+ case "7d": return t("atheletebridge.pages.performance.window.noPrior7", "No reading in the previous 7 days");
60
+ case "28d": return t("atheletebridge.pages.performance.window.noPrior28", "No reading in the previous 28 days");
61
+ case "90d": return t("atheletebridge.pages.performance.window.noPrior90", "No reading in the previous 90 days");
62
+ }
63
+ }, Z = "inline-flex items-center justify-center gap-1.5 rounded-lg px-4 py-2 text-sm font-semibold text-action-primary-text shadow-elevation-1 transition-[filter,box-shadow] hover:shadow-elevation-2 hover:brightness-110 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--color-focus-ring)] bg-[linear-gradient(120deg,var(--color-action-primary-bg),color-mix(in_oklab,var(--color-action-primary-bg)_62%,var(--color-accent-purple)),var(--color-action-primary-bg))]", ue = {
64
+ SPEED: I,
65
+ ENDURANCE: S,
66
+ STRENGTH: E,
67
+ AGILITY: A,
68
+ ACCURACY: P,
69
+ WEIGHT: N,
70
+ HEART_RATE: O,
71
+ CUSTOM: D
72
+ }, de = (e) => {
33
73
  let t = e.trim();
34
74
  if (!t) return;
35
75
  let n = Number.parseInt(t, 10);
36
76
  return Number.isNaN(n) ? void 0 : n;
37
- }, X = (e) => {
77
+ }, fe = (e) => {
38
78
  let t = e.trim();
39
79
  if (!t) return;
40
80
  let n = Number.parseFloat(t);
41
81
  return Number.isNaN(n) ? void 0 : n;
42
- }, Z = () => {
82
+ }, Q = () => {
43
83
  let e = /* @__PURE__ */ new Date();
44
84
  return (/* @__PURE__ */ new Date(e.getTime() - e.getTimezoneOffset() * 6e4)).toISOString().slice(0, 16);
45
- }, Q = (e) => (Math.abs(e) >= 100 ? e.toFixed(0) : e.toFixed(2)).replace(/\.?0+$/, "");
46
- function $() {
47
- let [e, n] = y({
85
+ }, $ = (e) => (Math.abs(e) >= 100 ? e.toFixed(0) : e.toFixed(2)).replace(/\.?0+$/, "");
86
+ function pe() {
87
+ let [e, t] = x({
48
88
  athleteId: "",
49
89
  displayName: ""
50
90
  });
51
- return /* @__PURE__ */ I(t, {
91
+ return /* @__PURE__ */ z(n, {
52
92
  title: "Performance",
53
93
  description: "Log workouts, record metrics and track an athlete's progress over time.",
54
- children: [/* @__PURE__ */ F("div", {
94
+ children: [/* @__PURE__ */ R("div", {
55
95
  "data-tour": "performance-athlete-picker",
56
96
  className: "sticky top-0 z-20 -mx-6 mb-8 bg-bg-canvas/80 px-6 pb-4 pt-1 backdrop-blur supports-[backdrop-filter]:bg-bg-canvas/60",
57
- children: /* @__PURE__ */ F(L, {
97
+ children: /* @__PURE__ */ R(B, {
58
98
  treatment: "insight",
59
99
  className: "p-5 sm:p-6",
60
- children: /* @__PURE__ */ F(_, {
100
+ children: /* @__PURE__ */ R(y, {
61
101
  athleteId: e.athleteId,
62
- onSelect: n,
102
+ onSelect: t,
63
103
  idPrefix: "perf-athlete"
64
104
  })
65
105
  })
66
- }), e.athleteId ? /* @__PURE__ */ F(ee, {
106
+ }), e.athleteId ? /* @__PURE__ */ R(me, {
67
107
  athleteId: e.athleteId,
68
108
  displayName: e.displayName
69
- }) : /* @__PURE__ */ F(s, {
109
+ }) : /* @__PURE__ */ R(c, {
70
110
  illustration: "empty-data",
71
- icon: /* @__PURE__ */ F(M, { className: "h-10 w-10" }),
111
+ icon: /* @__PURE__ */ R(F, { className: "h-10 w-10" }),
72
112
  title: "Pick an athlete to begin",
73
113
  description: "Choose a team and an athlete above to log workouts, record metrics and review their history."
74
114
  })]
75
115
  });
76
116
  }
77
- function ee({ athleteId: t, displayName: n }) {
78
- let [i, u] = y(0), [f, h] = y(!1), [g, _] = y(!1), x = p({
79
- athleteId: t,
80
- pagination: {
81
- limit: W,
82
- offset: i * W
117
+ function me({ athleteId: n, displayName: r }) {
118
+ let a = e(), [d, p] = x(0), [_, v] = x(""), [y, C] = x(!1), [w, O] = x(!1), k = b(() => _ === "" ? null : ie(_), [_]), A = m({
119
+ athleteId: n,
120
+ pagination: k ? { limit: te } : {
121
+ limit: K,
122
+ offset: d * K
83
123
  }
84
- }), S = d(t), T = x.data?.items ?? [], E = x.data?.pageInfo.hasMore ?? !1, D = v(() => {
124
+ }), M = f(n, ne), N = b(() => A.data?.items ?? [], [A.data]), P = A.data?.pageInfo.hasMore ?? !1, F = b(() => k ? N.filter((e) => {
125
+ let t = X(e.performedAt);
126
+ return t >= k.start && t <= k.end;
127
+ }) : N, [N, k]), I = k ? Math.max(0, Math.ceil(F.length / K) - 1) : d, V = Math.min(d, I), H = k ? F.slice(V * K, (V + 1) * K) : F, U = k ? F.length > (V + 1) * K : P, W = b(() => {
128
+ if (!k || !P) return !0;
129
+ let e = N[N.length - 1];
130
+ return e != null && X(e.performedAt) <= k.start;
131
+ }, [
132
+ k,
133
+ P,
134
+ N
135
+ ]), G = b(() => re.map((e) => ({
136
+ value: e,
137
+ label: `${se(e, a)} · ${oe(ie(e))}`
138
+ })), [a]), q = b(() => _ === "" ? {
139
+ comparison: a("atheletebridge.pages.performance.window.vsPrevious", "vs previous"),
140
+ noComparison: a("atheletebridge.pages.performance.window.firstReading", "First reading")
141
+ } : {
142
+ comparison: ce(_, a),
143
+ noComparison: le(_, a)
144
+ }, [_, a]), J = b(() => {
85
145
  let e = /* @__PURE__ */ new Map();
86
- for (let t of S.data ?? []) {
146
+ for (let t of M.data ?? []) {
87
147
  let n = `${t.type}::${t.label}`, r = e.get(n) ?? [];
88
148
  r.push(t), e.set(n, r);
89
149
  }
90
150
  return Array.from(e.entries()).map(([e, t]) => {
91
- let n = [...t].sort((e, t) => new Date(e.recordedAt).getTime() - new Date(t.recordedAt).getTime()), r = n.map((e) => e.value), i = n[n.length - 1], a = n.length > 1 ? n[n.length - 2] : null;
151
+ let n = [...t].sort((e, t) => X(e.recordedAt) - X(t.recordedAt)), r = k ? n.filter((e) => {
152
+ let t = X(e.recordedAt);
153
+ return t >= k.start && t <= k.end;
154
+ }) : n;
155
+ if (r.length === 0) return null;
156
+ let i = r.map((e) => e.value), a = r[r.length - 1], o = null;
157
+ if (k) {
158
+ let e = k.start - (k.end - k.start + 1), t = n.filter((t) => {
159
+ let n = X(t.recordedAt);
160
+ return n >= e && n < k.start;
161
+ });
162
+ o = t.length > 0 ? t[t.length - 1].value : null;
163
+ } else o = n.length > 1 ? n[n.length - 2].value : null;
92
164
  return {
93
165
  key: e,
94
- type: i.type,
95
- label: i.label,
96
- unit: i.unit,
97
- latest: i.value,
98
- previous: a ? a.value : null,
99
- min: Math.min(...r),
100
- max: Math.max(...r),
101
- series: r,
102
- recordedAt: i.recordedAt,
103
- count: n.length
166
+ type: a.type,
167
+ label: a.label,
168
+ unit: a.unit,
169
+ latest: a.value,
170
+ previous: o,
171
+ min: Math.min(...i),
172
+ max: Math.max(...i),
173
+ series: i,
174
+ recordedAt: a.recordedAt
104
175
  };
105
- }).sort((e, t) => new Date(t.recordedAt).getTime() - new Date(e.recordedAt).getTime());
106
- }, [S.data]), k = v(() => [
176
+ }).filter((e) => e !== null).sort((e, t) => X(t.recordedAt) - X(e.recordedAt));
177
+ }, [M.data, k]), Y = b(() => [
107
178
  {
108
179
  key: "workout",
109
180
  header: "Workout",
110
181
  priority: "primary",
111
- cell: (e) => /* @__PURE__ */ I("div", {
182
+ cell: (e) => /* @__PURE__ */ z("div", {
112
183
  className: "flex items-center gap-3",
113
- children: [/* @__PURE__ */ F("span", {
184
+ children: [/* @__PURE__ */ R("span", {
114
185
  className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-lg bg-[var(--color-accent-soft)] text-[var(--color-accent-teal)]",
115
- children: /* @__PURE__ */ F(te(e.title), {
186
+ children: /* @__PURE__ */ R(he(e.title), {
116
187
  className: "h-4 w-4",
117
188
  "aria-hidden": "true"
118
189
  })
119
- }), /* @__PURE__ */ F("span", {
190
+ }), /* @__PURE__ */ R("span", {
120
191
  className: "min-w-0 truncate font-medium text-text-primary",
121
192
  children: e.title
122
193
  })]
@@ -127,12 +198,12 @@ function ee({ athleteId: t, displayName: n }) {
127
198
  header: "Duration",
128
199
  priority: "secondary",
129
200
  mobileLabel: "Duration",
130
- cell: (e) => e.durationMin == null ? /* @__PURE__ */ F("span", {
201
+ cell: (e) => e.durationMin == null ? /* @__PURE__ */ R("span", {
131
202
  className: "text-text-muted",
132
203
  children: "—"
133
- }) : /* @__PURE__ */ F("span", {
204
+ }) : /* @__PURE__ */ R("span", {
134
205
  className: "tabular-nums text-text-secondary",
135
- children: o(e.durationMin)
206
+ children: s(e.durationMin)
136
207
  })
137
208
  },
138
209
  {
@@ -140,19 +211,19 @@ function ee({ athleteId: t, displayName: n }) {
140
211
  header: "RPE",
141
212
  priority: "secondary",
142
213
  mobileLabel: "RPE",
143
- cell: (e) => e.rpe == null ? /* @__PURE__ */ F("span", {
214
+ cell: (e) => e.rpe == null ? /* @__PURE__ */ R("span", {
144
215
  className: "text-text-muted",
145
216
  children: "—"
146
- }) : /* @__PURE__ */ F(ne, { rpe: e.rpe })
217
+ }) : /* @__PURE__ */ R(ge, { rpe: e.rpe })
147
218
  },
148
219
  {
149
220
  key: "date",
150
221
  header: "Date",
151
222
  priority: "secondary",
152
223
  mobileLabel: "Date",
153
- cell: (e) => /* @__PURE__ */ F("span", {
224
+ cell: (e) => /* @__PURE__ */ R("span", {
154
225
  className: "tabular-nums text-text-secondary",
155
- children: a(e.performedAt)
226
+ children: o(e.performedAt)
156
227
  })
157
228
  },
158
229
  {
@@ -160,165 +231,202 @@ function ee({ athleteId: t, displayName: n }) {
160
231
  header: "Status",
161
232
  priority: "primary",
162
233
  mobileLabel: "Status",
163
- cell: (e) => /* @__PURE__ */ F(r, { status: e.status })
234
+ cell: (e) => /* @__PURE__ */ R(i, { status: e.status })
164
235
  },
165
236
  {
166
237
  key: "notes",
167
238
  header: "Notes",
168
239
  priority: "hidden-on-mobile",
169
- cell: (e) => e.notes ? /* @__PURE__ */ F("span", {
240
+ cell: (e) => e.notes ? /* @__PURE__ */ R("span", {
170
241
  className: "line-clamp-2 max-w-[22ch] text-text-secondary",
171
242
  children: e.notes
172
- }) : /* @__PURE__ */ F("span", {
243
+ }) : /* @__PURE__ */ R("span", {
173
244
  className: "text-text-muted",
174
245
  children: "—"
175
246
  })
176
247
  }
177
248
  ], []);
178
- return /* @__PURE__ */ I("div", {
249
+ return /* @__PURE__ */ z("div", {
179
250
  className: "space-y-8 pb-24 sm:pb-0",
180
251
  children: [
181
- /* @__PURE__ */ I("div", {
252
+ /* @__PURE__ */ z("div", {
182
253
  className: "flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between",
183
- children: [/* @__PURE__ */ I("p", {
254
+ children: [/* @__PURE__ */ z("p", {
184
255
  className: "text-sm text-text-secondary",
185
- children: ["Tracking ", /* @__PURE__ */ F("span", {
186
- className: "font-medium text-text-primary",
187
- children: n || "athlete"
188
- })]
189
- }), /* @__PURE__ */ I("div", {
190
- className: "flex flex-wrap gap-2",
191
- children: [/* @__PURE__ */ I("button", {
192
- type: "button",
193
- onClick: () => _(!0),
194
- className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
195
- children: [/* @__PURE__ */ F(w, { className: "h-4 w-4" }), " Record metric"]
196
- }), /* @__PURE__ */ I("button", {
197
- type: "button",
198
- onClick: () => h(!0),
199
- className: e(q, "hidden sm:inline-flex"),
200
- children: [/* @__PURE__ */ F(C, { className: "h-4 w-4" }), " Log workout"]
201
- })]
256
+ children: [
257
+ "Tracking ",
258
+ /* @__PURE__ */ R("span", {
259
+ className: "font-medium text-text-primary",
260
+ children: r || "athlete"
261
+ }),
262
+ k ? /* @__PURE__ */ z(L, { children: [" · ", /* @__PURE__ */ R("span", {
263
+ className: "tabular-nums text-text-muted",
264
+ children: oe(k)
265
+ })] }) : null
266
+ ]
267
+ }), /* @__PURE__ */ z("div", {
268
+ className: "flex flex-wrap items-center gap-2",
269
+ children: [
270
+ /* @__PURE__ */ z("span", {
271
+ className: "flex items-center gap-2",
272
+ "data-tour": "performance-date-range",
273
+ children: [/* @__PURE__ */ R(T, {
274
+ className: "h-4 w-4 shrink-0 text-text-muted",
275
+ "aria-hidden": "true"
276
+ }), /* @__PURE__ */ R(g, {
277
+ value: _,
278
+ onChange: (e) => {
279
+ v(e), p(0);
280
+ },
281
+ options: G,
282
+ allLabel: a("atheletebridge.pages.performance.window.allTime", "All time"),
283
+ ariaLabel: a("atheletebridge.pages.performance.window.ariaLabel", "Date range")
284
+ })]
285
+ }),
286
+ /* @__PURE__ */ z("button", {
287
+ type: "button",
288
+ onClick: () => O(!0),
289
+ className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
290
+ children: [/* @__PURE__ */ R(D, { className: "h-4 w-4" }), " Record metric"]
291
+ }),
292
+ /* @__PURE__ */ z("button", {
293
+ type: "button",
294
+ onClick: () => C(!0),
295
+ className: t(Z, "hidden sm:inline-flex"),
296
+ children: [/* @__PURE__ */ R(E, { className: "h-4 w-4" }), " Log workout"]
297
+ })
298
+ ]
202
299
  })]
203
300
  }),
204
- /* @__PURE__ */ I("section", { children: [/* @__PURE__ */ F("h2", {
301
+ /* @__PURE__ */ z("section", { children: [/* @__PURE__ */ R("h2", {
205
302
  className: "mb-4 text-lg font-semibold text-text-primary",
206
303
  children: "Performance metrics"
207
- }), S.isLoading ? /* @__PURE__ */ F(l, { label: "Loading metrics…" }) : S.isError ? /* @__PURE__ */ F(c, { onRetry: () => void S.refetch() }) : D.length === 0 ? /* @__PURE__ */ F(s, {
304
+ }), M.isLoading ? /* @__PURE__ */ R(u, { label: "Loading metrics…" }) : M.isError ? /* @__PURE__ */ R(l, { onRetry: () => void M.refetch() }) : J.length === 0 ? /* @__PURE__ */ R(c, {
208
305
  illustration: "empty-data",
209
- icon: /* @__PURE__ */ F(w, { className: "h-10 w-10" }),
210
- title: "No metrics recorded",
211
- description: "Record a metric — speed, strength, endurance and more — to start charting progress.",
212
- action: /* @__PURE__ */ I("button", {
306
+ icon: /* @__PURE__ */ R(D, { className: "h-10 w-10" }),
307
+ title: k ? a("atheletebridge.pages.performance.metrics.emptyWindowTitle", "No metrics in this window") : "No metrics recorded",
308
+ description: k ? a("atheletebridge.pages.performance.metrics.emptyWindowDescription", "Nothing was recorded for this athlete in the selected period. Widen the date range, or record a metric.") : "Record a metric — speed, strength, endurance and more — to start charting progress.",
309
+ action: /* @__PURE__ */ z("button", {
213
310
  type: "button",
214
- onClick: () => _(!0),
215
- className: q,
216
- children: [/* @__PURE__ */ F(O, { className: "h-4 w-4" }), " Record metric"]
311
+ onClick: () => O(!0),
312
+ className: Z,
313
+ children: [/* @__PURE__ */ R(j, { className: "h-4 w-4" }), " Record metric"]
217
314
  })
218
- }) : /* @__PURE__ */ F("div", {
315
+ }) : /* @__PURE__ */ R("div", {
219
316
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
220
- children: D.map((e) => /* @__PURE__ */ F(re, { metric: e }, e.key))
317
+ children: J.map((e) => /* @__PURE__ */ R(_e, {
318
+ metric: e,
319
+ labels: q,
320
+ tr: a
321
+ }, e.key))
221
322
  })] }),
222
- /* @__PURE__ */ I("section", { children: [/* @__PURE__ */ F("h2", {
223
- className: "mb-4 text-lg font-semibold text-text-primary",
224
- children: "Workout history"
225
- }), x.isLoading ? /* @__PURE__ */ F(l, { label: "Loading workouts…" }) : x.isError ? /* @__PURE__ */ F(c, { onRetry: () => void x.refetch() }) : T.length === 0 ? /* @__PURE__ */ F(s, {
226
- illustration: "empty-data",
227
- icon: /* @__PURE__ */ F(b, { className: "h-10 w-10" }),
228
- title: "No workouts logged",
229
- description: "Log a workout to build this athlete's training history.",
230
- action: /* @__PURE__ */ I("button", {
231
- type: "button",
232
- onClick: () => h(!0),
233
- className: q,
234
- children: [/* @__PURE__ */ F(C, { className: "h-4 w-4" }), " Log workout"]
235
- })
236
- }) : /* @__PURE__ */ I(P, { children: [/* @__PURE__ */ F(L, {
237
- treatment: "metric",
238
- className: "overflow-hidden p-1 sm:p-2",
239
- children: /* @__PURE__ */ F(U, {
240
- columns: k,
241
- data: T,
242
- rowKey: (e) => e.id,
243
- caption: `Workout history for ${n || "athlete"}`
323
+ /* @__PURE__ */ z("section", { children: [
324
+ /* @__PURE__ */ R("h2", {
325
+ className: "mb-4 text-lg font-semibold text-text-primary",
326
+ children: "Workout history"
327
+ }),
328
+ A.isLoading ? /* @__PURE__ */ R(u, { label: "Loading workouts…" }) : A.isError ? /* @__PURE__ */ R(l, { onRetry: () => void A.refetch() }) : H.length === 0 ? /* @__PURE__ */ R(c, {
329
+ illustration: "empty-data",
330
+ icon: /* @__PURE__ */ R(S, { className: "h-10 w-10" }),
331
+ title: k ? a("atheletebridge.pages.performance.workouts.emptyWindowTitle", "No workouts in this window") : "No workouts logged",
332
+ description: k ? a("atheletebridge.pages.performance.workouts.emptyWindowDescription", "Nothing was logged for this athlete in the selected period. Widen the date range, or log a workout.") : "Log a workout to build this athlete's training history.",
333
+ action: /* @__PURE__ */ z("button", {
334
+ type: "button",
335
+ onClick: () => C(!0),
336
+ className: Z,
337
+ children: [/* @__PURE__ */ R(E, { className: "h-4 w-4" }), " Log workout"]
338
+ })
339
+ }) : /* @__PURE__ */ z(L, { children: [/* @__PURE__ */ R(B, {
340
+ treatment: "metric",
341
+ className: "overflow-hidden p-1 sm:p-2",
342
+ children: /* @__PURE__ */ R(ee, {
343
+ columns: Y,
344
+ data: H,
345
+ rowKey: (e) => e.id,
346
+ caption: `Workout history for ${r || "athlete"}`
347
+ })
348
+ }), /* @__PURE__ */ R(h, {
349
+ className: "mt-6",
350
+ page: V,
351
+ hasMore: U,
352
+ onPrev: () => p(Math.max(0, V - 1)),
353
+ onNext: () => p(V + 1)
354
+ })] }),
355
+ W ? null : /* @__PURE__ */ R("p", {
356
+ className: "mt-3 text-xs text-text-muted",
357
+ children: a("atheletebridge.pages.performance.workouts.windowTruncated", "Only the most recent page of workouts was searched, and it does not reach back to the start of this window — older sessions in the range are not listed.")
244
358
  })
245
- }), /* @__PURE__ */ F(m, {
246
- className: "mt-6",
247
- page: i,
248
- hasMore: E,
249
- onPrev: () => u((e) => Math.max(0, e - 1)),
250
- onNext: () => u((e) => e + 1)
251
- })] })] }),
252
- /* @__PURE__ */ F("div", {
359
+ ] }),
360
+ /* @__PURE__ */ R("div", {
253
361
  className: "sticky bottom-0 z-30 -mx-6 border-t border-border-seam bg-bg-canvas/85 px-6 pb-[max(env(safe-area-inset-bottom),0.75rem)] pt-3 backdrop-blur sm:hidden",
254
- children: /* @__PURE__ */ I("button", {
362
+ children: /* @__PURE__ */ z("button", {
255
363
  type: "button",
256
- onClick: () => h(!0),
257
- className: e(q, "w-full py-3 text-base"),
258
- children: [/* @__PURE__ */ F(O, { className: "h-5 w-5" }), " Log workout"]
364
+ onClick: () => C(!0),
365
+ className: t(Z, "w-full py-3 text-base"),
366
+ children: [/* @__PURE__ */ R(j, { className: "h-5 w-5" }), " Log workout"]
259
367
  })
260
368
  }),
261
- /* @__PURE__ */ F(ie, {
262
- open: f,
263
- onOpenChange: h,
264
- athleteId: t,
265
- displayName: n
369
+ /* @__PURE__ */ R(ve, {
370
+ open: y,
371
+ onOpenChange: C,
372
+ athleteId: n,
373
+ displayName: r
266
374
  }),
267
- /* @__PURE__ */ F(ae, {
268
- open: g,
269
- onOpenChange: _,
270
- athleteId: t,
271
- displayName: n
375
+ /* @__PURE__ */ R(ye, {
376
+ open: w,
377
+ onOpenChange: O,
378
+ athleteId: n,
379
+ displayName: r
272
380
  })
273
381
  ]
274
382
  });
275
383
  }
276
- function te(e) {
384
+ function he(e) {
277
385
  let t = e.toLowerCase();
278
- return /strength|lift|squat|deadlift|bench|1rm|weight/.test(t) ? C : /speed|sprint|agility|accel|split/.test(t) ? N : /endurance|aerobic|cardio|run|beep|yo-?yo/.test(t) ? b : /recovery|mobility|stretch|rest/.test(t) ? T : /accuracy|shoot|target/.test(t) ? j : C;
386
+ return /strength|lift|squat|deadlift|bench|1rm|weight/.test(t) ? E : /speed|sprint|agility|accel|split/.test(t) ? I : /endurance|aerobic|cardio|run|beep|yo-?yo/.test(t) ? S : /recovery|mobility|stretch|rest/.test(t) ? O : /accuracy|shoot|target/.test(t) ? P : E;
279
387
  }
280
- function ne({ rpe: t }) {
281
- return /* @__PURE__ */ F("span", {
282
- className: e("inline-flex h-7 min-w-[1.75rem] items-center justify-center rounded-md border px-1.5 text-sm font-semibold tabular-nums", t >= 8 ? "border-status-error-border text-status-error-text" : t >= 5 ? "border-status-warning-border text-status-warning-text" : "border-border-seam text-text-secondary"),
283
- children: t
388
+ function ge({ rpe: e }) {
389
+ return /* @__PURE__ */ R("span", {
390
+ className: t("inline-flex h-7 min-w-[1.75rem] items-center justify-center rounded-md border px-1.5 text-sm font-semibold tabular-nums", e >= 8 ? "border-status-error-border text-status-error-text" : e >= 5 ? "border-status-warning-border text-status-warning-text" : "border-border-seam text-text-secondary"),
391
+ children: e
284
392
  });
285
393
  }
286
- function re({ metric: e }) {
287
- let t = J[e.type], r = e.previous == null ? null : e.latest - e.previous, o = e.max > e.min, s = o ? Math.round((e.latest - e.min) / (e.max - e.min) * 100) : 100, c = e.unit ? ` ${e.unit}` : "";
288
- return /* @__PURE__ */ I(L, {
394
+ function _e({ metric: e, labels: t, tr: n }) {
395
+ let i = ue[e.type], s = e.previous == null ? null : e.latest - e.previous, c = e.max > e.min, l = c ? Math.round((e.latest - e.min) / (e.max - e.min) * 100) : 100, u = e.unit ? ` ${e.unit}` : "";
396
+ return /* @__PURE__ */ z(B, {
289
397
  treatment: "metric",
290
398
  className: "flex flex-col gap-3 p-5",
291
399
  children: [
292
- /* @__PURE__ */ I("div", {
400
+ /* @__PURE__ */ z("div", {
293
401
  className: "flex items-center justify-between gap-2",
294
- children: [/* @__PURE__ */ I("span", {
402
+ children: [/* @__PURE__ */ z("span", {
295
403
  className: "flex items-center gap-2 text-xs font-semibold uppercase tracking-wide text-[var(--color-accent-teal)]",
296
- children: [/* @__PURE__ */ F(t, {
404
+ children: [/* @__PURE__ */ R(i, {
297
405
  className: "h-4 w-4",
298
406
  "aria-hidden": "true"
299
- }), i[e.type]]
300
- }), /* @__PURE__ */ F("span", {
407
+ }), a[e.type]]
408
+ }), /* @__PURE__ */ R("span", {
301
409
  className: "text-xs text-text-muted",
302
- children: a(e.recordedAt)
410
+ children: o(e.recordedAt)
303
411
  })]
304
412
  }),
305
- /* @__PURE__ */ I("div", {
413
+ /* @__PURE__ */ z("div", {
306
414
  className: "flex items-end justify-between gap-3",
307
- children: [/* @__PURE__ */ I("div", {
415
+ children: [/* @__PURE__ */ z("div", {
308
416
  className: "min-w-0",
309
- children: [/* @__PURE__ */ F("p", {
417
+ children: [/* @__PURE__ */ R("p", {
310
418
  className: "truncate text-sm text-text-secondary",
311
419
  children: e.label
312
- }), /* @__PURE__ */ I("p", {
420
+ }), /* @__PURE__ */ z("p", {
313
421
  className: "mt-0.5 text-3xl font-bold leading-none tracking-tight tabular-nums text-text-primary",
314
- children: [Q(e.latest), e.unit ? /* @__PURE__ */ F("span", {
422
+ children: [$(e.latest), e.unit ? /* @__PURE__ */ R("span", {
315
423
  className: "ml-1 text-base font-medium text-text-secondary",
316
424
  children: e.unit
317
425
  }) : null]
318
426
  })]
319
- }), e.series.length > 1 ? /* @__PURE__ */ F("div", {
427
+ }), e.series.length > 1 ? /* @__PURE__ */ R("div", {
320
428
  className: "w-24 shrink-0 sm:w-28",
321
- children: /* @__PURE__ */ F(n, {
429
+ children: /* @__PURE__ */ R(r, {
322
430
  data: e.series,
323
431
  variant: "area",
324
432
  height: 40,
@@ -326,58 +434,65 @@ function re({ metric: e }) {
326
434
  })
327
435
  }) : null]
328
436
  }),
329
- o ? /* @__PURE__ */ I("div", { children: [/* @__PURE__ */ F("span", {
437
+ c ? /* @__PURE__ */ z("div", { children: [/* @__PURE__ */ R("span", {
330
438
  className: "block h-1.5 overflow-hidden rounded-full bg-bg-sunken",
331
439
  "aria-hidden": "true",
332
- children: /* @__PURE__ */ F("span", {
440
+ children: /* @__PURE__ */ R("span", {
333
441
  className: "block h-1.5 rounded-full bg-[var(--color-accent-teal)]",
334
- style: { width: `${Math.max(4, Math.min(100, s))}%` }
442
+ style: { width: `${Math.max(4, Math.min(100, l))}%` }
335
443
  })
336
- }), /* @__PURE__ */ I("div", {
444
+ }), /* @__PURE__ */ z("div", {
337
445
  className: "mt-1 flex justify-between text-[0.7rem] tabular-nums text-text-muted",
338
446
  children: [
339
- /* @__PURE__ */ F("span", { children: Q(e.min) }),
340
- /* @__PURE__ */ F("span", { children: Q((e.min + e.max) / 2) }),
341
- /* @__PURE__ */ F("span", { children: Q(e.max) })
447
+ /* @__PURE__ */ R("span", { children: $(e.min) }),
448
+ /* @__PURE__ */ R("span", { children: $((e.min + e.max) / 2) }),
449
+ /* @__PURE__ */ R("span", { children: $(e.max) })
342
450
  ]
343
451
  })] }) : null,
344
- /* @__PURE__ */ F("div", {
452
+ /* @__PURE__ */ R("div", {
345
453
  className: "mt-auto flex items-center gap-1.5 text-sm",
346
- children: r == null || r === 0 ? /* @__PURE__ */ F("span", {
454
+ children: s == null ? /* @__PURE__ */ R("span", {
455
+ className: "text-text-muted",
456
+ children: t.noComparison
457
+ }) : s === 0 ? /* @__PURE__ */ z("span", {
347
458
  className: "text-text-muted",
348
- children: e.count > 1 ? "No change vs previous" : "First reading"
349
- }) : /* @__PURE__ */ I(P, { children: [/* @__PURE__ */ I("span", {
459
+ children: [
460
+ n("atheletebridge.pages.performance.window.noChange", "No change"),
461
+ " ",
462
+ t.comparison
463
+ ]
464
+ }) : /* @__PURE__ */ z(L, { children: [/* @__PURE__ */ z("span", {
350
465
  className: "inline-flex items-center gap-0.5 font-medium tabular-nums text-text-secondary",
351
466
  children: [
352
- F(r > 0 ? S : x, {
467
+ R(s > 0 ? w : C, {
353
468
  className: "h-4 w-4",
354
469
  "aria-hidden": "true"
355
470
  }),
356
- Q(Math.abs(r)),
357
- c
471
+ $(Math.abs(s)),
472
+ u
358
473
  ]
359
- }), /* @__PURE__ */ F("span", {
474
+ }), /* @__PURE__ */ R("span", {
360
475
  className: "text-text-muted",
361
- children: "vs previous"
476
+ children: t.comparison
362
477
  })] })
363
478
  })
364
479
  ]
365
480
  });
366
481
  }
367
- function ie({ open: t, onOpenChange: n, athleteId: r, displayName: i }) {
368
- let a = u(), [o, s] = y(""), [c, l] = y("COMPLETED"), [d, f] = y(Z), [p, m] = y(""), [_, v] = y(""), [b, x] = y(""), [S, C] = y(""), [w, T] = y(null), D = () => {
369
- s(""), l("COMPLETED"), f(Z()), m(""), v(""), x(""), C(""), T(null);
482
+ function ve({ open: e, onOpenChange: n, athleteId: r, displayName: i }) {
483
+ let a = d(), [o, s] = x(""), [c, l] = x("COMPLETED"), [u, f] = x(Q), [p, m] = x(""), [h, g] = x(""), [y, b] = x(""), [S, C] = x(""), [w, T] = x(null), E = () => {
484
+ s(""), l("COMPLETED"), f(Q()), m(""), g(""), b(""), C(""), T(null);
370
485
  };
371
- return /* @__PURE__ */ F(R, {
372
- open: t,
486
+ return /* @__PURE__ */ R(V, {
487
+ open: e,
373
488
  onOpenChange: n,
374
- children: /* @__PURE__ */ I(z, { children: [/* @__PURE__ */ F(V, { children: /* @__PURE__ */ I(H, { children: ["Log workout", i ? ` — ${i}` : ""] }) }), /* @__PURE__ */ I("form", {
489
+ children: /* @__PURE__ */ z(H, { children: [/* @__PURE__ */ R(W, { children: /* @__PURE__ */ z(G, { children: ["Log workout", i ? ` — ${i}` : ""] }) }), /* @__PURE__ */ z("form", {
375
490
  onSubmit: async (e) => {
376
491
  if (e.preventDefault(), T(null), !o.trim()) {
377
492
  T("A workout title is required.");
378
493
  return;
379
494
  }
380
- if (!d) {
495
+ if (!u) {
381
496
  T("A performed date and time is required.");
382
497
  return;
383
498
  }
@@ -386,146 +501,146 @@ function ie({ open: t, onOpenChange: n, athleteId: r, displayName: i }) {
386
501
  athleteId: r,
387
502
  title: o.trim(),
388
503
  status: c,
389
- performedAt: new Date(d).toISOString(),
390
- durationMin: Y(p),
391
- rpe: Y(_),
392
- totalLoad: X(b),
504
+ performedAt: new Date(u).toISOString(),
505
+ durationMin: de(p),
506
+ rpe: de(h),
507
+ totalLoad: fe(y),
393
508
  notes: S.trim() || void 0
394
- }), D(), n(!1);
509
+ }), E(), n(!1);
395
510
  } catch (e) {
396
511
  T(e instanceof Error ? e.message : "Failed to log workout.");
397
512
  }
398
513
  },
399
514
  className: "space-y-4 px-1",
400
515
  children: [
401
- /* @__PURE__ */ F(h, {
516
+ /* @__PURE__ */ R(_, {
402
517
  label: "Title",
403
518
  htmlFor: "workoutTitle",
404
519
  required: !0,
405
- children: /* @__PURE__ */ F("input", {
520
+ children: /* @__PURE__ */ R("input", {
406
521
  id: "workoutTitle",
407
- className: g,
522
+ className: v,
408
523
  value: o,
409
524
  onChange: (e) => s(e.target.value),
410
525
  placeholder: "e.g. Lower-body strength"
411
526
  })
412
527
  }),
413
- /* @__PURE__ */ I("div", {
528
+ /* @__PURE__ */ z("div", {
414
529
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
415
- children: [/* @__PURE__ */ F(h, {
530
+ children: [/* @__PURE__ */ R(_, {
416
531
  label: "Status",
417
532
  htmlFor: "workoutStatus",
418
- children: /* @__PURE__ */ F("select", {
533
+ children: /* @__PURE__ */ R("select", {
419
534
  id: "workoutStatus",
420
- className: g,
535
+ className: v,
421
536
  value: c,
422
537
  onChange: (e) => l(e.target.value),
423
- children: G.map((e) => /* @__PURE__ */ F("option", {
538
+ children: q.map((e) => /* @__PURE__ */ R("option", {
424
539
  value: e,
425
540
  children: e.charAt(0) + e.slice(1).toLowerCase()
426
541
  }, e))
427
542
  })
428
- }), /* @__PURE__ */ F(h, {
543
+ }), /* @__PURE__ */ R(_, {
429
544
  label: "Performed at",
430
545
  htmlFor: "workoutPerformedAt",
431
546
  required: !0,
432
- children: /* @__PURE__ */ F("input", {
547
+ children: /* @__PURE__ */ R("input", {
433
548
  id: "workoutPerformedAt",
434
549
  type: "datetime-local",
435
- className: g,
436
- value: d,
550
+ className: v,
551
+ value: u,
437
552
  onChange: (e) => f(e.target.value)
438
553
  })
439
554
  })]
440
555
  }),
441
- /* @__PURE__ */ I("div", {
556
+ /* @__PURE__ */ z("div", {
442
557
  className: "grid grid-cols-1 gap-4 sm:grid-cols-3",
443
558
  children: [
444
- /* @__PURE__ */ F(h, {
559
+ /* @__PURE__ */ R(_, {
445
560
  label: "Duration (min)",
446
561
  htmlFor: "workoutDuration",
447
- children: /* @__PURE__ */ F("input", {
562
+ children: /* @__PURE__ */ R("input", {
448
563
  id: "workoutDuration",
449
564
  inputMode: "numeric",
450
- className: g,
565
+ className: v,
451
566
  value: p,
452
567
  onChange: (e) => m(e.target.value)
453
568
  })
454
569
  }),
455
- /* @__PURE__ */ F(h, {
570
+ /* @__PURE__ */ R(_, {
456
571
  label: "RPE (1–10)",
457
572
  htmlFor: "workoutRpe",
458
- children: /* @__PURE__ */ F("input", {
573
+ children: /* @__PURE__ */ R("input", {
459
574
  id: "workoutRpe",
460
575
  inputMode: "numeric",
461
- className: g,
462
- value: _,
463
- onChange: (e) => v(e.target.value)
576
+ className: v,
577
+ value: h,
578
+ onChange: (e) => g(e.target.value)
464
579
  })
465
580
  }),
466
- /* @__PURE__ */ F(h, {
581
+ /* @__PURE__ */ R(_, {
467
582
  label: "Total load",
468
583
  htmlFor: "workoutLoad",
469
- children: /* @__PURE__ */ F("input", {
584
+ children: /* @__PURE__ */ R("input", {
470
585
  id: "workoutLoad",
471
586
  inputMode: "decimal",
472
- className: g,
473
- value: b,
474
- onChange: (e) => x(e.target.value)
587
+ className: v,
588
+ value: y,
589
+ onChange: (e) => b(e.target.value)
475
590
  })
476
591
  })
477
592
  ]
478
593
  }),
479
- /* @__PURE__ */ F(h, {
594
+ /* @__PURE__ */ R(_, {
480
595
  label: "Notes",
481
596
  htmlFor: "workoutNotes",
482
- children: /* @__PURE__ */ F("textarea", {
597
+ children: /* @__PURE__ */ R("textarea", {
483
598
  id: "workoutNotes",
484
599
  rows: 2,
485
- className: g,
600
+ className: v,
486
601
  value: S,
487
602
  onChange: (e) => C(e.target.value),
488
603
  placeholder: "How did the session go?"
489
604
  })
490
605
  }),
491
- w && /* @__PURE__ */ F("p", {
606
+ w && /* @__PURE__ */ R("p", {
492
607
  className: "text-sm text-status-error-text",
493
608
  children: w
494
609
  }),
495
- /* @__PURE__ */ I(B, { children: [/* @__PURE__ */ F("button", {
610
+ /* @__PURE__ */ z(U, { children: [/* @__PURE__ */ R("button", {
496
611
  type: "button",
497
612
  onClick: () => n(!1),
498
613
  className: "rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
499
614
  children: "Cancel"
500
- }), /* @__PURE__ */ I("button", {
615
+ }), /* @__PURE__ */ z("button", {
501
616
  type: "submit",
502
617
  disabled: a.isPending,
503
- className: e(q, "disabled:opacity-60"),
504
- children: [a.isPending ? /* @__PURE__ */ F(E, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ F(k, { className: "h-4 w-4" }), "Log workout"]
618
+ className: t(Z, "disabled:opacity-60"),
619
+ children: [a.isPending ? /* @__PURE__ */ R(k, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ R(M, { className: "h-4 w-4" }), "Log workout"]
505
620
  })] })
506
621
  ]
507
622
  })] })
508
623
  });
509
624
  }
510
- function ae({ open: t, onOpenChange: n, athleteId: r, displayName: a }) {
511
- let o = f(), [s, c] = y("CUSTOM"), [l, u] = y(""), [d, p] = y(""), [m, _] = y(""), [v, b] = y(""), [x, S] = y(Z), [C, w] = y(null), T = () => {
512
- c("CUSTOM"), u(""), p(""), _(""), b(""), S(Z()), w(null);
625
+ function ye({ open: e, onOpenChange: n, athleteId: r, displayName: i }) {
626
+ let o = p(), [s, c] = x("CUSTOM"), [l, u] = x(""), [d, f] = x(""), [m, h] = x(""), [g, y] = x(""), [b, S] = x(Q), [C, w] = x(null), T = () => {
627
+ c("CUSTOM"), u(""), f(""), h(""), y(""), S(Q()), w(null);
513
628
  };
514
- return /* @__PURE__ */ F(R, {
515
- open: t,
629
+ return /* @__PURE__ */ R(V, {
630
+ open: e,
516
631
  onOpenChange: n,
517
- children: /* @__PURE__ */ I(z, { children: [/* @__PURE__ */ F(V, { children: /* @__PURE__ */ I(H, { children: ["Record metric", a ? ` — ${a}` : ""] }) }), /* @__PURE__ */ I("form", {
632
+ children: /* @__PURE__ */ z(H, { children: [/* @__PURE__ */ R(W, { children: /* @__PURE__ */ z(G, { children: ["Record metric", i ? ` — ${i}` : ""] }) }), /* @__PURE__ */ z("form", {
518
633
  onSubmit: async (e) => {
519
634
  if (e.preventDefault(), w(null), !l.trim()) {
520
635
  w("A metric label is required.");
521
636
  return;
522
637
  }
523
- let t = X(d);
638
+ let t = fe(d);
524
639
  if (t === void 0) {
525
640
  w("A numeric value is required.");
526
641
  return;
527
642
  }
528
- if (!x) {
643
+ if (!b) {
529
644
  w("A recorded date and time is required.");
530
645
  return;
531
646
  }
@@ -536,8 +651,8 @@ function ae({ open: t, onOpenChange: n, athleteId: r, displayName: a }) {
536
651
  label: l.trim(),
537
652
  value: t,
538
653
  unit: m.trim() || void 0,
539
- source: v.trim() || void 0,
540
- recordedAt: new Date(x).toISOString()
654
+ source: g.trim() || void 0,
655
+ recordedAt: new Date(b).toISOString()
541
656
  }), T(), n(!1);
542
657
  } catch (e) {
543
658
  w(e instanceof Error ? e.message : "Failed to record metric.");
@@ -545,104 +660,104 @@ function ae({ open: t, onOpenChange: n, athleteId: r, displayName: a }) {
545
660
  },
546
661
  className: "space-y-4 px-1",
547
662
  children: [
548
- /* @__PURE__ */ I("div", {
663
+ /* @__PURE__ */ z("div", {
549
664
  className: "grid grid-cols-1 gap-4 sm:grid-cols-2",
550
- children: [/* @__PURE__ */ F(h, {
665
+ children: [/* @__PURE__ */ R(_, {
551
666
  label: "Type",
552
667
  htmlFor: "metricType",
553
- children: /* @__PURE__ */ F("select", {
668
+ children: /* @__PURE__ */ R("select", {
554
669
  id: "metricType",
555
- className: g,
670
+ className: v,
556
671
  value: s,
557
672
  onChange: (e) => c(e.target.value),
558
- children: K.map((e) => /* @__PURE__ */ F("option", {
673
+ children: J.map((e) => /* @__PURE__ */ R("option", {
559
674
  value: e,
560
- children: i[e]
675
+ children: a[e]
561
676
  }, e))
562
677
  })
563
- }), /* @__PURE__ */ F(h, {
678
+ }), /* @__PURE__ */ R(_, {
564
679
  label: "Recorded at",
565
680
  htmlFor: "metricRecordedAt",
566
681
  required: !0,
567
- children: /* @__PURE__ */ F("input", {
682
+ children: /* @__PURE__ */ R("input", {
568
683
  id: "metricRecordedAt",
569
684
  type: "datetime-local",
570
- className: g,
571
- value: x,
685
+ className: v,
686
+ value: b,
572
687
  onChange: (e) => S(e.target.value)
573
688
  })
574
689
  })]
575
690
  }),
576
- /* @__PURE__ */ F(h, {
691
+ /* @__PURE__ */ R(_, {
577
692
  label: "Label",
578
693
  htmlFor: "metricLabel",
579
694
  required: !0,
580
- children: /* @__PURE__ */ F("input", {
695
+ children: /* @__PURE__ */ R("input", {
581
696
  id: "metricLabel",
582
- className: g,
697
+ className: v,
583
698
  value: l,
584
699
  onChange: (e) => u(e.target.value),
585
700
  placeholder: "e.g. 40m sprint"
586
701
  })
587
702
  }),
588
- /* @__PURE__ */ I("div", {
703
+ /* @__PURE__ */ z("div", {
589
704
  className: "grid grid-cols-2 gap-4",
590
- children: [/* @__PURE__ */ F(h, {
705
+ children: [/* @__PURE__ */ R(_, {
591
706
  label: "Value",
592
707
  htmlFor: "metricValue",
593
708
  required: !0,
594
- children: /* @__PURE__ */ F("input", {
709
+ children: /* @__PURE__ */ R("input", {
595
710
  id: "metricValue",
596
711
  inputMode: "decimal",
597
- className: g,
712
+ className: v,
598
713
  value: d,
599
- onChange: (e) => p(e.target.value),
714
+ onChange: (e) => f(e.target.value),
600
715
  placeholder: "e.g. 4.8"
601
716
  })
602
- }), /* @__PURE__ */ F(h, {
717
+ }), /* @__PURE__ */ R(_, {
603
718
  label: "Unit",
604
719
  htmlFor: "metricUnit",
605
- children: /* @__PURE__ */ F("input", {
720
+ children: /* @__PURE__ */ R("input", {
606
721
  id: "metricUnit",
607
- className: g,
722
+ className: v,
608
723
  value: m,
609
- onChange: (e) => _(e.target.value),
724
+ onChange: (e) => h(e.target.value),
610
725
  placeholder: "e.g. s, kg, bpm"
611
726
  })
612
727
  })]
613
728
  }),
614
- /* @__PURE__ */ F(h, {
729
+ /* @__PURE__ */ R(_, {
615
730
  label: "Source",
616
731
  htmlFor: "metricSource",
617
732
  hint: "Optional — device, test or coach.",
618
- children: /* @__PURE__ */ F("input", {
733
+ children: /* @__PURE__ */ R("input", {
619
734
  id: "metricSource",
620
- className: g,
621
- value: v,
622
- onChange: (e) => b(e.target.value),
735
+ className: v,
736
+ value: g,
737
+ onChange: (e) => y(e.target.value),
623
738
  placeholder: "e.g. GPS vest"
624
739
  })
625
740
  }),
626
- C && /* @__PURE__ */ F("p", {
741
+ C && /* @__PURE__ */ R("p", {
627
742
  className: "text-sm text-status-error-text",
628
743
  children: C
629
744
  }),
630
- /* @__PURE__ */ I(B, { children: [/* @__PURE__ */ F("button", {
745
+ /* @__PURE__ */ z(U, { children: [/* @__PURE__ */ R("button", {
631
746
  type: "button",
632
747
  onClick: () => n(!1),
633
748
  className: "rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
634
749
  children: "Cancel"
635
- }), /* @__PURE__ */ I("button", {
750
+ }), /* @__PURE__ */ z("button", {
636
751
  type: "submit",
637
752
  disabled: o.isPending,
638
- className: e(q, "disabled:opacity-60"),
639
- children: [o.isPending ? /* @__PURE__ */ F(E, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ F(O, { className: "h-4 w-4" }), "Record metric"]
753
+ className: t(Z, "disabled:opacity-60"),
754
+ children: [o.isPending ? /* @__PURE__ */ R(k, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ R(j, { className: "h-4 w-4" }), "Record metric"]
640
755
  })] })
641
756
  ]
642
757
  })] })
643
758
  });
644
759
  }
645
760
  //#endregion
646
- export { $ as PerformancePage };
761
+ export { pe as PerformancePage };
647
762
 
648
763
  //# sourceMappingURL=PerformancePage.js.map