@burdenoff/microfe-atheletebridge 2026.805.1 → 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.
- package/dist/atheletebridge/hooks/index.d.ts +1 -1
- package/dist/atheletebridge/hooks/index.d.ts.map +1 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts +41 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts.map +1 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +58 -28
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
- package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.d.ts +6 -2
- package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.js +284 -130
- package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.js.map +1 -1
- package/dist/atheletebridge/pages/performance/PerformancePage.d.ts +7 -0
- package/dist/atheletebridge/pages/performance/PerformancePage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/performance/PerformancePage.js +392 -277
- package/dist/atheletebridge/pages/performance/PerformancePage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,31 +1,32 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
1
|
+
import { useAbTranslate as e } from "../../i18n.js";
|
|
2
|
+
import { useAthleteBridge as t } from "../../context/AthleteBridgeContext.js";
|
|
3
|
+
import { PageLayout as n } from "../../components/PageLayout.js";
|
|
4
|
+
import { STATUS as r } from "../../components/viz/lib/palette.js";
|
|
5
|
+
import { LineChart as i } from "../../components/viz/LineChart.js";
|
|
6
|
+
import { BarChart as a } from "../../components/viz/BarChart.js";
|
|
7
|
+
import { DonutChart as o } from "../../components/viz/DonutChart.js";
|
|
8
|
+
import { RatingStars as s } from "../../components/viz/RatingStars.js";
|
|
8
9
|
import "../../components/viz/index.js";
|
|
9
|
-
import { MetricsCard as
|
|
10
|
-
import { humanizeEnum as
|
|
11
|
-
import { Crest as
|
|
12
|
-
import { UserAvatar as
|
|
13
|
-
import { EmptyState as
|
|
14
|
-
import { ErrorState as
|
|
15
|
-
import { useCoachAnalytics as
|
|
16
|
-
import { useMemo as
|
|
17
|
-
import { Activity as
|
|
18
|
-
import { Fragment as
|
|
19
|
-
import { Badge as
|
|
10
|
+
import { MetricsCard as c } from "../../components/MetricsCard.js";
|
|
11
|
+
import { humanizeEnum as l } from "../../components/domain.js";
|
|
12
|
+
import { Crest as u } from "../../components/Crest.js";
|
|
13
|
+
import { UserAvatar as d } from "../../components/UserAvatar.js";
|
|
14
|
+
import { EmptyState as f } from "../../components/EmptyState.js";
|
|
15
|
+
import { ErrorState as p, LoadingState as m } from "../../components/LoadingState.js";
|
|
16
|
+
import { useCoachAnalytics as h, useUserDirectory as g } from "../../hooks/useAthleteBridgeApi.js";
|
|
17
|
+
import { useMemo as _ } from "react";
|
|
18
|
+
import { Activity as v, BarChart3 as y, CheckCircle2 as b, Info as x, ListChecks as S, Star as C, Users as w } from "lucide-react";
|
|
19
|
+
import { Fragment as T, jsx as E, jsxs as D } from "react/jsx-runtime";
|
|
20
|
+
import { Badge as O, GlassCard as k, GradientText as A, ResponsiveTable as j, Tooltip as M, TooltipContent as N, TooltipProvider as P, TooltipTrigger as F } from "@burdenoff/fe-libs/ui";
|
|
20
21
|
//#region src/atheletebridge/pages/analytics/CoachAnalyticsPage.tsx
|
|
21
|
-
var
|
|
22
|
-
COMPLETED:
|
|
23
|
-
CONFIRMED:
|
|
24
|
-
REQUESTED:
|
|
25
|
-
CANCELLED:
|
|
22
|
+
var I = {
|
|
23
|
+
COMPLETED: r.success,
|
|
24
|
+
CONFIRMED: r.info,
|
|
25
|
+
REQUESTED: r.warning,
|
|
26
|
+
CANCELLED: r.danger,
|
|
26
27
|
NO_SHOW: "var(--color-text-muted)"
|
|
27
28
|
};
|
|
28
|
-
function
|
|
29
|
+
function L(e) {
|
|
29
30
|
return e == null ? {
|
|
30
31
|
label: "No data",
|
|
31
32
|
variant: "secondary"
|
|
@@ -40,23 +41,35 @@ function F(e) {
|
|
|
40
41
|
variant: "default"
|
|
41
42
|
};
|
|
42
43
|
}
|
|
43
|
-
function
|
|
44
|
-
return e && e.trim() ? e :
|
|
44
|
+
function R(e, t, n) {
|
|
45
|
+
return e && e.trim() ? e : `${n} ${t.slice(0, 4)}`;
|
|
45
46
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
47
|
+
var z = (e) => Math.round(e).toLocaleString();
|
|
48
|
+
function B({ value: e, max: t }) {
|
|
49
|
+
let n = t > 0 ? Math.round(e / t * 100) : 0;
|
|
50
|
+
return /* @__PURE__ */ E("span", {
|
|
51
|
+
className: "block h-1.5 w-16 overflow-hidden rounded-full bg-bg-sunken",
|
|
52
|
+
"aria-hidden": "true",
|
|
53
|
+
children: /* @__PURE__ */ E("span", {
|
|
54
|
+
className: "block h-1.5 rounded-full bg-[var(--color-accent-teal)]",
|
|
55
|
+
style: { width: `${Math.max(e > 0 ? 4 : 0, Math.min(100, n))}%` }
|
|
56
|
+
})
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
function V() {
|
|
60
|
+
let r = e(), { navigateTo: w } = t(), z = h(), B = g(_(() => [...z.coachIds, ...z.athleteIds], [z.coachIds, z.athleteIds])), V = _(() => z.sessionsByStatus.map((e) => ({
|
|
61
|
+
label: l(e.status),
|
|
49
62
|
value: e.count,
|
|
50
|
-
color:
|
|
51
|
-
})), [
|
|
52
|
-
label:
|
|
63
|
+
color: I[e.status]
|
|
64
|
+
})), [z.sessionsByStatus]), U = _(() => z.ratingByCoach.map((e) => ({
|
|
65
|
+
label: R(B.nameOf(e.coachId), e.coachId, "Coach"),
|
|
53
66
|
value: Number(e.avgRating.toFixed(2))
|
|
54
|
-
})), [
|
|
67
|
+
})), [z.ratingByCoach, B]), W = [
|
|
55
68
|
{
|
|
56
69
|
key: "rank",
|
|
57
70
|
header: "#",
|
|
58
71
|
priority: "secondary",
|
|
59
|
-
cell: (e, t) => /* @__PURE__ */
|
|
72
|
+
cell: (e, t) => /* @__PURE__ */ E("span", {
|
|
60
73
|
className: "tabular-nums text-text-secondary",
|
|
61
74
|
children: e.rank ?? t + 1
|
|
62
75
|
})
|
|
@@ -65,14 +78,14 @@ function L() {
|
|
|
65
78
|
key: "team",
|
|
66
79
|
header: "Team",
|
|
67
80
|
priority: "primary",
|
|
68
|
-
cell: (e) => /* @__PURE__ */
|
|
81
|
+
cell: (e) => /* @__PURE__ */ D("span", {
|
|
69
82
|
className: "flex items-center gap-2",
|
|
70
|
-
children: [/* @__PURE__ */
|
|
83
|
+
children: [/* @__PURE__ */ E(u, {
|
|
71
84
|
name: e.team?.name ?? "Team",
|
|
72
85
|
sport: e.team?.sport,
|
|
73
86
|
size: 20,
|
|
74
87
|
showSportGlyph: !1
|
|
75
|
-
}), /* @__PURE__ */
|
|
88
|
+
}), /* @__PURE__ */ E("span", {
|
|
76
89
|
className: "truncate font-medium text-text-primary",
|
|
77
90
|
children: e.team?.name ?? "Team"
|
|
78
91
|
})]
|
|
@@ -82,7 +95,7 @@ function L() {
|
|
|
82
95
|
key: "played",
|
|
83
96
|
header: "P",
|
|
84
97
|
priority: "hidden-on-mobile",
|
|
85
|
-
cell: (e) => /* @__PURE__ */
|
|
98
|
+
cell: (e) => /* @__PURE__ */ E("span", {
|
|
86
99
|
className: "tabular-nums text-text-secondary",
|
|
87
100
|
children: e.played
|
|
88
101
|
})
|
|
@@ -93,7 +106,7 @@ function L() {
|
|
|
93
106
|
priority: "hidden-on-mobile",
|
|
94
107
|
cell: (e) => {
|
|
95
108
|
let t = e.goalsFor - e.goalsAgainst;
|
|
96
|
-
return /* @__PURE__ */
|
|
109
|
+
return /* @__PURE__ */ D("span", {
|
|
97
110
|
className: "tabular-nums text-text-secondary",
|
|
98
111
|
children: [t > 0 ? "+" : "", t]
|
|
99
112
|
});
|
|
@@ -103,133 +116,133 @@ function L() {
|
|
|
103
116
|
key: "points",
|
|
104
117
|
header: "Pts",
|
|
105
118
|
priority: "secondary",
|
|
106
|
-
cell: (e) => /* @__PURE__ */
|
|
119
|
+
cell: (e) => /* @__PURE__ */ E("span", {
|
|
107
120
|
className: "font-semibold tabular-nums text-text-primary",
|
|
108
121
|
children: e.points
|
|
109
122
|
})
|
|
110
123
|
}
|
|
111
124
|
];
|
|
112
|
-
if (
|
|
125
|
+
if (z.isLoading) return /* @__PURE__ */ E(n, {
|
|
113
126
|
title: "Coach analytics",
|
|
114
|
-
children: /* @__PURE__ */
|
|
127
|
+
children: /* @__PURE__ */ E(m, { label: "Crunching coaching data…" })
|
|
115
128
|
});
|
|
116
|
-
if (
|
|
129
|
+
if (z.isError) return /* @__PURE__ */ E(n, {
|
|
117
130
|
title: "Coach analytics",
|
|
118
|
-
children: /* @__PURE__ */
|
|
131
|
+
children: /* @__PURE__ */ E(p, {
|
|
119
132
|
title: "Analytics unavailable",
|
|
120
133
|
message: "We could not load coaching analytics. Please try again."
|
|
121
134
|
})
|
|
122
135
|
});
|
|
123
|
-
let
|
|
124
|
-
return /* @__PURE__ */
|
|
125
|
-
title: /* @__PURE__ */
|
|
136
|
+
let G = z.totalSessions > 0 || z.standings.length > 0 || z.loadByAthlete.length > 0, K = L(z.trainingLoad.ratio);
|
|
137
|
+
return /* @__PURE__ */ E(n, {
|
|
138
|
+
title: /* @__PURE__ */ D("span", {
|
|
126
139
|
className: "flex items-center gap-2",
|
|
127
|
-
children: [/* @__PURE__ */
|
|
140
|
+
children: [/* @__PURE__ */ E(A, { children: "Coach analytics" }), /* @__PURE__ */ E(O, {
|
|
128
141
|
variant: "outline",
|
|
129
142
|
children: "Beta"
|
|
130
143
|
})]
|
|
131
144
|
}),
|
|
132
145
|
description: "Honest aggregates over your real sessions, workouts and results.",
|
|
133
|
-
children:
|
|
146
|
+
children: G ? /* @__PURE__ */ D("div", {
|
|
134
147
|
className: "space-y-8",
|
|
135
148
|
children: [
|
|
136
|
-
/* @__PURE__ */
|
|
149
|
+
/* @__PURE__ */ D("div", {
|
|
137
150
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
138
151
|
children: [
|
|
139
|
-
/* @__PURE__ */
|
|
140
|
-
icon: /* @__PURE__ */
|
|
141
|
-
value:
|
|
152
|
+
/* @__PURE__ */ E(c, {
|
|
153
|
+
icon: /* @__PURE__ */ E(S, { className: "h-5 w-5" }),
|
|
154
|
+
value: z.totalSessions,
|
|
142
155
|
label: "Total sessions",
|
|
143
156
|
tone: "accent"
|
|
144
157
|
}),
|
|
145
|
-
/* @__PURE__ */
|
|
158
|
+
/* @__PURE__ */ D(k, {
|
|
146
159
|
treatment: "metric",
|
|
147
160
|
className: "flex flex-col justify-between gap-3 p-5",
|
|
148
161
|
children: [
|
|
149
|
-
/* @__PURE__ */
|
|
162
|
+
/* @__PURE__ */ D("div", {
|
|
150
163
|
className: "flex items-start justify-between gap-2",
|
|
151
|
-
children: [/* @__PURE__ */
|
|
164
|
+
children: [/* @__PURE__ */ E("span", {
|
|
152
165
|
className: "text-sm font-medium text-text-secondary",
|
|
153
166
|
children: "Avg session rating"
|
|
154
|
-
}), /* @__PURE__ */
|
|
167
|
+
}), /* @__PURE__ */ E(C, { className: "h-5 w-5 text-text-muted" })]
|
|
155
168
|
}),
|
|
156
|
-
|
|
169
|
+
z.avgRating == null ? /* @__PURE__ */ E("span", {
|
|
157
170
|
className: "text-sm text-text-muted",
|
|
158
171
|
children: "No rated sessions yet"
|
|
159
|
-
}) : /* @__PURE__ */
|
|
172
|
+
}) : /* @__PURE__ */ D("div", {
|
|
160
173
|
className: "flex items-end gap-3",
|
|
161
|
-
children: [/* @__PURE__ */
|
|
174
|
+
children: [/* @__PURE__ */ D("span", {
|
|
162
175
|
className: "text-3xl font-semibold leading-none tabular-nums text-text-primary",
|
|
163
|
-
children: [
|
|
176
|
+
children: [z.avgRating.toFixed(1), /* @__PURE__ */ E("span", {
|
|
164
177
|
className: "ml-1 text-base text-text-secondary",
|
|
165
178
|
children: "/5"
|
|
166
179
|
})]
|
|
167
|
-
}), /* @__PURE__ */
|
|
180
|
+
}), /* @__PURE__ */ E("div", {
|
|
168
181
|
className: "pb-1",
|
|
169
|
-
children: /* @__PURE__ */
|
|
170
|
-
value:
|
|
182
|
+
children: /* @__PURE__ */ E(s, {
|
|
183
|
+
value: z.avgRating,
|
|
171
184
|
max: 5,
|
|
172
185
|
size: 16
|
|
173
186
|
})
|
|
174
187
|
})]
|
|
175
188
|
}),
|
|
176
|
-
/* @__PURE__ */
|
|
189
|
+
/* @__PURE__ */ D("span", {
|
|
177
190
|
className: "text-xs text-text-muted tabular-nums",
|
|
178
191
|
children: [
|
|
179
|
-
|
|
192
|
+
z.ratedCount,
|
|
180
193
|
" rated of ",
|
|
181
|
-
|
|
194
|
+
z.totalSessions
|
|
182
195
|
]
|
|
183
196
|
})
|
|
184
197
|
]
|
|
185
198
|
}),
|
|
186
|
-
/* @__PURE__ */
|
|
187
|
-
icon: /* @__PURE__ */
|
|
188
|
-
value: `${Math.round(
|
|
199
|
+
/* @__PURE__ */ E(c, {
|
|
200
|
+
icon: /* @__PURE__ */ E(b, { className: "h-5 w-5" }),
|
|
201
|
+
value: `${Math.round(z.completedPct)}%`,
|
|
189
202
|
label: "Sessions completed",
|
|
190
203
|
tone: "success"
|
|
191
204
|
})
|
|
192
205
|
]
|
|
193
206
|
}),
|
|
194
|
-
/* @__PURE__ */
|
|
207
|
+
/* @__PURE__ */ D("div", {
|
|
195
208
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
|
|
196
|
-
children: [/* @__PURE__ */
|
|
209
|
+
children: [/* @__PURE__ */ D(k, {
|
|
197
210
|
treatment: "insight",
|
|
198
211
|
className: "p-6",
|
|
199
|
-
children: [/* @__PURE__ */
|
|
212
|
+
children: [/* @__PURE__ */ E("h2", {
|
|
200
213
|
className: "mb-4 text-lg font-semibold text-text-primary",
|
|
201
214
|
children: "Session status overview"
|
|
202
|
-
}),
|
|
203
|
-
segments:
|
|
204
|
-
centerLabel:
|
|
215
|
+
}), V.length > 0 ? /* @__PURE__ */ E(o, {
|
|
216
|
+
segments: V,
|
|
217
|
+
centerLabel: z.totalSessions,
|
|
205
218
|
centerCaption: "sessions",
|
|
206
219
|
valueFormatter: (e) => e.toLocaleString()
|
|
207
|
-
}) : /* @__PURE__ */
|
|
220
|
+
}) : /* @__PURE__ */ E("p", {
|
|
208
221
|
className: "text-sm text-text-muted",
|
|
209
222
|
children: "No sessions to break down yet."
|
|
210
223
|
})]
|
|
211
|
-
}), /* @__PURE__ */
|
|
224
|
+
}), /* @__PURE__ */ D(k, {
|
|
212
225
|
treatment: "insight",
|
|
213
226
|
className: "p-6",
|
|
214
|
-
children: [/* @__PURE__ */
|
|
227
|
+
children: [/* @__PURE__ */ E("h2", {
|
|
215
228
|
className: "mb-4 text-lg font-semibold text-text-primary",
|
|
216
229
|
children: "Average rating by coach"
|
|
217
|
-
}),
|
|
218
|
-
series:
|
|
230
|
+
}), U.length > 0 ? /* @__PURE__ */ D(T, { children: [/* @__PURE__ */ E(a, {
|
|
231
|
+
series: U,
|
|
219
232
|
height: 220,
|
|
220
233
|
colorful: !0,
|
|
221
234
|
valueFormatter: (e) => e.toFixed(1)
|
|
222
|
-
}), /* @__PURE__ */
|
|
235
|
+
}), /* @__PURE__ */ E("div", {
|
|
223
236
|
className: "mt-3 flex flex-wrap gap-x-4 gap-y-2",
|
|
224
|
-
children:
|
|
237
|
+
children: z.ratingByCoach.map((e) => /* @__PURE__ */ D("span", {
|
|
225
238
|
className: "flex items-center gap-2 text-xs text-text-secondary",
|
|
226
|
-
children: [/* @__PURE__ */
|
|
227
|
-
name:
|
|
239
|
+
children: [/* @__PURE__ */ E(d, {
|
|
240
|
+
name: B.nameOf(e.coachId),
|
|
228
241
|
id: e.coachId,
|
|
229
242
|
size: "xs"
|
|
230
|
-
}), /* @__PURE__ */
|
|
243
|
+
}), /* @__PURE__ */ D("span", {
|
|
231
244
|
className: "truncate",
|
|
232
|
-
children: [
|
|
245
|
+
children: [R(B.nameOf(e.coachId), e.coachId, "Coach"), /* @__PURE__ */ D("span", {
|
|
233
246
|
className: "ml-1 text-text-muted tabular-nums",
|
|
234
247
|
children: [
|
|
235
248
|
"(",
|
|
@@ -239,134 +252,275 @@ function L() {
|
|
|
239
252
|
})]
|
|
240
253
|
})]
|
|
241
254
|
}, e.coachId))
|
|
242
|
-
})] }) : /* @__PURE__ */
|
|
255
|
+
})] }) : /* @__PURE__ */ E("p", {
|
|
243
256
|
className: "text-sm text-text-muted",
|
|
244
257
|
children: "Rate completed sessions to compare coaches."
|
|
245
258
|
})]
|
|
246
259
|
})]
|
|
247
260
|
}),
|
|
248
|
-
/* @__PURE__ */
|
|
261
|
+
/* @__PURE__ */ D("div", {
|
|
249
262
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
|
|
250
|
-
children: [/* @__PURE__ */
|
|
263
|
+
children: [/* @__PURE__ */ D(k, {
|
|
251
264
|
treatment: "insight",
|
|
252
265
|
className: "p-6",
|
|
253
|
-
children: [/* @__PURE__ */
|
|
266
|
+
children: [/* @__PURE__ */ D("div", {
|
|
254
267
|
className: "mb-4 flex items-center justify-between gap-2",
|
|
255
|
-
children: [/* @__PURE__ */
|
|
268
|
+
children: [/* @__PURE__ */ E("h2", {
|
|
256
269
|
className: "text-lg font-semibold text-text-primary",
|
|
257
270
|
children: "Weekly training load"
|
|
258
|
-
}), /* @__PURE__ */
|
|
271
|
+
}), /* @__PURE__ */ E(P, { children: /* @__PURE__ */ D(M, { children: [/* @__PURE__ */ E(F, {
|
|
259
272
|
asChild: !0,
|
|
260
|
-
children: /* @__PURE__ */
|
|
273
|
+
children: /* @__PURE__ */ E("button", {
|
|
261
274
|
type: "button",
|
|
262
275
|
"aria-label": "About ACWR training load",
|
|
263
276
|
className: "rounded-full p-1 text-text-muted transition-colors hover:text-text-primary",
|
|
264
|
-
children: /* @__PURE__ */
|
|
277
|
+
children: /* @__PURE__ */ E(x, { className: "h-4 w-4" })
|
|
265
278
|
})
|
|
266
|
-
}), /* @__PURE__ */
|
|
279
|
+
}), /* @__PURE__ */ D(N, {
|
|
267
280
|
className: "max-w-xs",
|
|
268
281
|
children: [
|
|
269
282
|
"Total workout load per week (sum of real ",
|
|
270
|
-
/* @__PURE__ */
|
|
283
|
+
/* @__PURE__ */ E("code", { children: "totalLoad" }),
|
|
271
284
|
"). The badge is the acute:chronic workload ratio (last 7 days vs 28-day average) — a standard sports-science load indicator; 0.8–1.3 is the typical sweet spot."
|
|
272
285
|
]
|
|
273
286
|
})] }) })]
|
|
274
|
-
}),
|
|
275
|
-
series:
|
|
287
|
+
}), z.loadTrend.some((e) => e.value > 0) ? /* @__PURE__ */ D(T, { children: [/* @__PURE__ */ E(i, {
|
|
288
|
+
series: z.loadTrend,
|
|
276
289
|
seriesLabel: "Training load",
|
|
277
290
|
height: 200,
|
|
278
291
|
valueFormatter: (e) => e.toLocaleString()
|
|
279
|
-
}), /* @__PURE__ */
|
|
292
|
+
}), /* @__PURE__ */ D("div", {
|
|
280
293
|
className: "mt-4 flex flex-wrap items-center gap-x-6 gap-y-2 text-sm",
|
|
281
294
|
children: [
|
|
282
|
-
/* @__PURE__ */
|
|
295
|
+
/* @__PURE__ */ D("span", {
|
|
283
296
|
className: "text-text-secondary",
|
|
284
297
|
children: [
|
|
285
298
|
"Acute (7d)",
|
|
286
299
|
" ",
|
|
287
|
-
/* @__PURE__ */
|
|
300
|
+
/* @__PURE__ */ E("span", {
|
|
288
301
|
className: "font-semibold tabular-nums text-text-primary",
|
|
289
|
-
children: Math.round(
|
|
302
|
+
children: Math.round(z.trainingLoad.acute).toLocaleString()
|
|
290
303
|
})
|
|
291
304
|
]
|
|
292
305
|
}),
|
|
293
|
-
/* @__PURE__ */
|
|
306
|
+
/* @__PURE__ */ D("span", {
|
|
294
307
|
className: "text-text-secondary",
|
|
295
308
|
children: [
|
|
296
309
|
"Chronic (28d avg)",
|
|
297
310
|
" ",
|
|
298
|
-
/* @__PURE__ */
|
|
311
|
+
/* @__PURE__ */ E("span", {
|
|
299
312
|
className: "font-semibold tabular-nums text-text-primary",
|
|
300
|
-
children: Math.round(
|
|
313
|
+
children: Math.round(z.trainingLoad.chronic).toLocaleString()
|
|
301
314
|
})
|
|
302
315
|
]
|
|
303
316
|
}),
|
|
304
|
-
/* @__PURE__ */
|
|
317
|
+
/* @__PURE__ */ D("span", {
|
|
305
318
|
className: "flex items-center gap-2 text-text-secondary",
|
|
306
|
-
children: ["ACWR", /* @__PURE__ */
|
|
307
|
-
variant:
|
|
319
|
+
children: ["ACWR", /* @__PURE__ */ E(O, {
|
|
320
|
+
variant: K.variant,
|
|
308
321
|
className: "tabular-nums",
|
|
309
|
-
children:
|
|
322
|
+
children: z.trainingLoad.ratio == null ? K.label : `${z.trainingLoad.ratio.toFixed(2)} · ${K.label}`
|
|
310
323
|
})]
|
|
311
324
|
})
|
|
312
325
|
]
|
|
313
|
-
})] }) : /* @__PURE__ */
|
|
326
|
+
})] }) : /* @__PURE__ */ E("p", {
|
|
314
327
|
className: "text-sm text-text-muted",
|
|
315
328
|
children: "Log workouts with a load to see training trend."
|
|
316
329
|
})]
|
|
317
|
-
}), /* @__PURE__ */
|
|
330
|
+
}), /* @__PURE__ */ D(k, {
|
|
318
331
|
treatment: "insight",
|
|
319
332
|
className: "p-6",
|
|
320
|
-
children: [/* @__PURE__ */
|
|
333
|
+
children: [/* @__PURE__ */ E("h2", {
|
|
321
334
|
className: "mb-4 text-lg font-semibold text-text-primary",
|
|
322
335
|
children: "Sessions per week"
|
|
323
|
-
}),
|
|
324
|
-
series:
|
|
336
|
+
}), z.sessionTrend.some((e) => e.value > 0) ? /* @__PURE__ */ E(a, {
|
|
337
|
+
series: z.sessionTrend,
|
|
325
338
|
height: 200,
|
|
326
339
|
valueFormatter: (e) => e.toLocaleString()
|
|
327
|
-
}) : /* @__PURE__ */
|
|
340
|
+
}) : /* @__PURE__ */ E("p", {
|
|
328
341
|
className: "text-sm text-text-muted",
|
|
329
342
|
children: "Schedule sessions to see weekly volume."
|
|
330
343
|
})]
|
|
331
344
|
})]
|
|
332
345
|
}),
|
|
333
|
-
|
|
346
|
+
/* @__PURE__ */ E(H, {
|
|
347
|
+
rows: z.loadByAthlete,
|
|
348
|
+
directory: B,
|
|
349
|
+
truncated: z.loadSampleTruncated,
|
|
350
|
+
tr: r
|
|
351
|
+
}),
|
|
352
|
+
z.standings.length > 0 ? /* @__PURE__ */ D("section", { children: [/* @__PURE__ */ D("div", {
|
|
334
353
|
className: "mb-4 flex flex-wrap items-center justify-between gap-3",
|
|
335
|
-
children: [/* @__PURE__ */
|
|
354
|
+
children: [/* @__PURE__ */ D("h2", {
|
|
336
355
|
className: "flex items-center gap-2 text-lg font-semibold text-text-primary",
|
|
337
356
|
children: [
|
|
338
|
-
/* @__PURE__ */
|
|
357
|
+
/* @__PURE__ */ E(v, { className: "h-5 w-5 text-text-muted" }),
|
|
339
358
|
"League standings",
|
|
340
|
-
|
|
359
|
+
z.competition ? /* @__PURE__ */ E(O, {
|
|
341
360
|
variant: "secondary",
|
|
342
|
-
children:
|
|
361
|
+
children: z.competition
|
|
343
362
|
}) : null
|
|
344
363
|
]
|
|
345
|
-
}), /* @__PURE__ */
|
|
364
|
+
}), /* @__PURE__ */ E("button", {
|
|
346
365
|
type: "button",
|
|
347
|
-
onClick: () =>
|
|
366
|
+
onClick: () => w("/standings"),
|
|
348
367
|
className: "text-sm font-medium text-[var(--color-accent-teal)] transition-colors hover:underline",
|
|
349
368
|
children: "View full standings"
|
|
350
369
|
})]
|
|
351
|
-
}), /* @__PURE__ */
|
|
370
|
+
}), /* @__PURE__ */ E(k, {
|
|
352
371
|
treatment: "insight",
|
|
353
372
|
className: "p-2 sm:p-4",
|
|
354
|
-
children: /* @__PURE__ */
|
|
355
|
-
columns:
|
|
356
|
-
data:
|
|
373
|
+
children: /* @__PURE__ */ E(j, {
|
|
374
|
+
columns: W,
|
|
375
|
+
data: z.standings,
|
|
357
376
|
rowKey: (e) => e.id
|
|
358
377
|
})
|
|
359
378
|
})] }) : null
|
|
360
379
|
]
|
|
361
|
-
}) : /* @__PURE__ */
|
|
380
|
+
}) : /* @__PURE__ */ E(f, {
|
|
362
381
|
illustration: "empty-data",
|
|
363
|
-
icon: /* @__PURE__ */
|
|
382
|
+
icon: /* @__PURE__ */ E(y, { className: "h-10 w-10" }),
|
|
364
383
|
title: "No coaching data yet",
|
|
365
384
|
description: "Book and complete sessions, log workouts and record fixtures to unlock analytics."
|
|
366
385
|
})
|
|
367
386
|
});
|
|
368
387
|
}
|
|
388
|
+
function H({ rows: e, directory: t, truncated: n, tr: r }) {
|
|
389
|
+
let i = _(() => e.reduce((e, t) => Math.max(e, t.acute, t.chronic), 0), [e]), a = _(() => [
|
|
390
|
+
{
|
|
391
|
+
key: "athlete",
|
|
392
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.athlete", "Athlete"),
|
|
393
|
+
priority: "primary",
|
|
394
|
+
cell: (e) => /* @__PURE__ */ D("span", {
|
|
395
|
+
className: "flex items-center gap-2",
|
|
396
|
+
children: [/* @__PURE__ */ E(d, {
|
|
397
|
+
name: t.nameOf(e.athleteId),
|
|
398
|
+
id: e.athleteId,
|
|
399
|
+
size: "xs"
|
|
400
|
+
}), /* @__PURE__ */ D("span", {
|
|
401
|
+
className: "min-w-0",
|
|
402
|
+
children: [/* @__PURE__ */ E("span", {
|
|
403
|
+
className: "block truncate font-medium text-text-primary",
|
|
404
|
+
children: R(t.nameOf(e.athleteId), e.athleteId, "Athlete")
|
|
405
|
+
}), /* @__PURE__ */ D("span", {
|
|
406
|
+
className: "block text-xs tabular-nums text-text-muted",
|
|
407
|
+
children: [
|
|
408
|
+
e.workoutCount,
|
|
409
|
+
" ",
|
|
410
|
+
r("atheletebridge.pages.analytics.loadByAthlete.workouts28d", "workouts · 28d")
|
|
411
|
+
]
|
|
412
|
+
})]
|
|
413
|
+
})]
|
|
414
|
+
})
|
|
415
|
+
},
|
|
416
|
+
{
|
|
417
|
+
key: "acute",
|
|
418
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.acute", "Acute load (7d)"),
|
|
419
|
+
priority: "secondary",
|
|
420
|
+
mobileLabel: r("atheletebridge.pages.analytics.loadByAthlete.acute", "Acute load (7d)"),
|
|
421
|
+
cell: (e) => e.loadedCount === 0 ? /* @__PURE__ */ E("span", {
|
|
422
|
+
className: "text-text-muted",
|
|
423
|
+
children: "—"
|
|
424
|
+
}) : /* @__PURE__ */ D("span", {
|
|
425
|
+
className: "flex items-center gap-2",
|
|
426
|
+
children: [/* @__PURE__ */ E("span", {
|
|
427
|
+
className: "w-14 text-right font-medium tabular-nums text-text-primary",
|
|
428
|
+
children: z(e.acute)
|
|
429
|
+
}), /* @__PURE__ */ E(B, {
|
|
430
|
+
value: e.acute,
|
|
431
|
+
max: i
|
|
432
|
+
})]
|
|
433
|
+
})
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
key: "chronic",
|
|
437
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.chronic", "Chronic load (28d avg)"),
|
|
438
|
+
priority: "secondary",
|
|
439
|
+
mobileLabel: r("atheletebridge.pages.analytics.loadByAthlete.chronic", "Chronic load (28d avg)"),
|
|
440
|
+
cell: (e) => e.loadedCount === 0 ? /* @__PURE__ */ E("span", {
|
|
441
|
+
className: "text-text-muted",
|
|
442
|
+
children: "—"
|
|
443
|
+
}) : /* @__PURE__ */ D("span", {
|
|
444
|
+
className: "flex items-center gap-2",
|
|
445
|
+
children: [/* @__PURE__ */ E("span", {
|
|
446
|
+
className: "w-14 text-right font-medium tabular-nums text-text-primary",
|
|
447
|
+
children: z(e.chronic)
|
|
448
|
+
}), /* @__PURE__ */ E(B, {
|
|
449
|
+
value: e.chronic,
|
|
450
|
+
max: i
|
|
451
|
+
})]
|
|
452
|
+
})
|
|
453
|
+
},
|
|
454
|
+
{
|
|
455
|
+
key: "ratio",
|
|
456
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.ratio", "Load ratio"),
|
|
457
|
+
priority: "secondary",
|
|
458
|
+
mobileLabel: r("atheletebridge.pages.analytics.loadByAthlete.ratio", "Load ratio"),
|
|
459
|
+
cell: (e) => e.ratio == null ? /* @__PURE__ */ E("span", {
|
|
460
|
+
className: "text-text-muted",
|
|
461
|
+
children: "—"
|
|
462
|
+
}) : /* @__PURE__ */ E("span", {
|
|
463
|
+
className: "font-semibold tabular-nums text-text-primary",
|
|
464
|
+
children: e.ratio.toFixed(2)
|
|
465
|
+
})
|
|
466
|
+
},
|
|
467
|
+
{
|
|
468
|
+
key: "band",
|
|
469
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.status", "Status"),
|
|
470
|
+
priority: "primary",
|
|
471
|
+
mobileLabel: r("atheletebridge.pages.analytics.loadByAthlete.status", "Status"),
|
|
472
|
+
cell: (e) => {
|
|
473
|
+
let t = L(e.ratio);
|
|
474
|
+
return /* @__PURE__ */ E(O, {
|
|
475
|
+
variant: t.variant,
|
|
476
|
+
children: t.label
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
], [
|
|
481
|
+
t,
|
|
482
|
+
i,
|
|
483
|
+
r
|
|
484
|
+
]);
|
|
485
|
+
return /* @__PURE__ */ D("section", { children: [/* @__PURE__ */ D("div", {
|
|
486
|
+
className: "mb-4 flex flex-wrap items-center gap-2",
|
|
487
|
+
children: [/* @__PURE__ */ D("h2", {
|
|
488
|
+
className: "flex items-center gap-2 text-lg font-semibold text-text-primary",
|
|
489
|
+
children: [/* @__PURE__ */ E(w, { className: "h-5 w-5 text-text-muted" }), r("atheletebridge.pages.analytics.loadByAthlete.title", "Training load by athlete")]
|
|
490
|
+
}), /* @__PURE__ */ E(P, { children: /* @__PURE__ */ D(M, { children: [/* @__PURE__ */ E(F, {
|
|
491
|
+
asChild: !0,
|
|
492
|
+
children: /* @__PURE__ */ E("button", {
|
|
493
|
+
type: "button",
|
|
494
|
+
"aria-label": r("atheletebridge.pages.analytics.loadByAthlete.aboutLabel", "About per-athlete training load"),
|
|
495
|
+
className: "rounded-full p-1 text-text-muted transition-colors hover:text-text-primary",
|
|
496
|
+
children: /* @__PURE__ */ E(x, { className: "h-4 w-4" })
|
|
497
|
+
})
|
|
498
|
+
}), /* @__PURE__ */ E(N, {
|
|
499
|
+
className: "max-w-xs",
|
|
500
|
+
children: r("atheletebridge.pages.analytics.loadByAthlete.about", "Each athlete’s acute:chronic workload ratio — their last 7 days of logged workout load against their 28-day weekly average. 0.8–1.3 is the typical sweet spot; above 1.5 is a spike worth reviewing.")
|
|
501
|
+
})] }) })]
|
|
502
|
+
}), e.length === 0 ? /* @__PURE__ */ E(k, {
|
|
503
|
+
treatment: "insight",
|
|
504
|
+
className: "p-6",
|
|
505
|
+
children: /* @__PURE__ */ E("p", {
|
|
506
|
+
className: "text-sm text-text-muted",
|
|
507
|
+
children: r("atheletebridge.pages.analytics.loadByAthlete.empty", "No workouts logged in the last 28 days. Log workouts with a total load to compare athletes.")
|
|
508
|
+
})
|
|
509
|
+
}) : /* @__PURE__ */ D(T, { children: [/* @__PURE__ */ E(k, {
|
|
510
|
+
treatment: "insight",
|
|
511
|
+
className: "p-2 sm:p-4",
|
|
512
|
+
children: /* @__PURE__ */ E(j, {
|
|
513
|
+
columns: a,
|
|
514
|
+
data: e,
|
|
515
|
+
rowKey: (e) => e.athleteId,
|
|
516
|
+
caption: r("atheletebridge.pages.analytics.loadByAthlete.caption", "Acute and chronic training load per athlete over the last 28 days")
|
|
517
|
+
})
|
|
518
|
+
}), n ? /* @__PURE__ */ E("p", {
|
|
519
|
+
className: "mt-3 text-xs text-text-muted",
|
|
520
|
+
children: r("atheletebridge.pages.analytics.loadByAthlete.truncated", "Computed from the most recent page of workout logs, which does not reach back a full 28 days — these loads are a floor, not a total.")
|
|
521
|
+
}) : null] })] });
|
|
522
|
+
}
|
|
369
523
|
//#endregion
|
|
370
|
-
export {
|
|
524
|
+
export { V as CoachAnalyticsPage };
|
|
371
525
|
|
|
372
526
|
//# sourceMappingURL=CoachAnalyticsPage.js.map
|