@burdenoff/microfe-atheletebridge 2026.805.1 → 2026.829.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/components/LoadingState.d.ts.map +1 -1
- package/dist/atheletebridge/components/LoadingState.js +39 -32
- package/dist/atheletebridge/components/LoadingState.js.map +1 -1
- package/dist/atheletebridge/components/TeamCard.d.ts.map +1 -1
- package/dist/atheletebridge/components/TeamCard.js +45 -49
- package/dist/atheletebridge/components/TeamCard.js.map +1 -1
- 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/DashboardPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/DashboardPage.js +56 -24
- package/dist/atheletebridge/pages/DashboardPage.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 +330 -174
- package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.js.map +1 -1
- package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js +110 -106
- package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/fixtures/FixturesListPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/fixtures/FixturesListPage.js +80 -71
- package/dist/atheletebridge/pages/fixtures/FixturesListPage.js.map +1 -1
- package/dist/atheletebridge/pages/onboarding/OnboardingPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/onboarding/OnboardingPage.js +244 -210
- package/dist/atheletebridge/pages/onboarding/OnboardingPage.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 +526 -362
- package/dist/atheletebridge/pages/performance/PerformancePage.js.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramDetailPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramDetailPage.js +169 -143
- package/dist/atheletebridge/pages/programs/ProgramDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramsListPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramsListPage.js +77 -72
- package/dist/atheletebridge/pages/programs/ProgramsListPage.js.map +1 -1
- package/dist/atheletebridge/pages/sessions/SessionDetailPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/sessions/SessionDetailPage.js +104 -86
- package/dist/atheletebridge/pages/sessions/SessionDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/sessions/SessionsListPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/sessions/SessionsListPage.js +54 -49
- package/dist/atheletebridge/pages/sessions/SessionsListPage.js.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamDetailPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamDetailPage.js +286 -267
- package/dist/atheletebridge/pages/teams/TeamDetailPage.js.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamFormPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamFormPage.js +185 -180
- package/dist/atheletebridge/pages/teams/TeamFormPage.js.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamsListPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamsListPage.js +70 -74
- package/dist/atheletebridge/pages/teams/TeamsListPage.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,99 +1,116 @@
|
|
|
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, t) {
|
|
29
30
|
return e == null ? {
|
|
30
|
-
label: "No data",
|
|
31
|
+
label: t("atheletebridge.pages.analytics.acwr.noData", "No data"),
|
|
31
32
|
variant: "secondary"
|
|
32
33
|
} : e > 1.5 ? {
|
|
33
|
-
label: "At risk",
|
|
34
|
+
label: t("atheletebridge.pages.analytics.acwr.atRisk", "At risk"),
|
|
34
35
|
variant: "destructive"
|
|
35
36
|
} : e < .8 || e > 1.3 ? {
|
|
36
|
-
label: "Watch",
|
|
37
|
+
label: t("atheletebridge.pages.analytics.acwr.watch", "Watch"),
|
|
37
38
|
variant: "secondary"
|
|
38
39
|
} : {
|
|
39
|
-
label: "Optimal",
|
|
40
|
+
label: t("atheletebridge.pages.analytics.acwr.optimal", "Optimal"),
|
|
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, r("atheletebridge.rolePrefix.coach", "Coach")),
|
|
53
66
|
value: Number(e.avgRating.toFixed(2))
|
|
54
|
-
})), [
|
|
67
|
+
})), [
|
|
68
|
+
z.ratingByCoach,
|
|
69
|
+
B,
|
|
70
|
+
r
|
|
71
|
+
]), W = [
|
|
55
72
|
{
|
|
56
73
|
key: "rank",
|
|
57
|
-
header: "#",
|
|
74
|
+
header: r("atheletebridge.pages.analytics.standings.rank", "#"),
|
|
58
75
|
priority: "secondary",
|
|
59
|
-
cell: (e, t) => /* @__PURE__ */
|
|
76
|
+
cell: (e, t) => /* @__PURE__ */ E("span", {
|
|
60
77
|
className: "tabular-nums text-text-secondary",
|
|
61
78
|
children: e.rank ?? t + 1
|
|
62
79
|
})
|
|
63
80
|
},
|
|
64
81
|
{
|
|
65
82
|
key: "team",
|
|
66
|
-
header: "Team",
|
|
83
|
+
header: r("atheletebridge.pages.analytics.standings.team", "Team"),
|
|
67
84
|
priority: "primary",
|
|
68
|
-
cell: (e) => /* @__PURE__ */
|
|
85
|
+
cell: (e) => /* @__PURE__ */ D("span", {
|
|
69
86
|
className: "flex items-center gap-2",
|
|
70
|
-
children: [/* @__PURE__ */
|
|
71
|
-
name: e.team?.name ?? "Team",
|
|
87
|
+
children: [/* @__PURE__ */ E(u, {
|
|
88
|
+
name: e.team?.name ?? r("atheletebridge.pages.analytics.standings.teamFallback", "Team"),
|
|
72
89
|
sport: e.team?.sport,
|
|
73
90
|
size: 20,
|
|
74
91
|
showSportGlyph: !1
|
|
75
|
-
}), /* @__PURE__ */
|
|
92
|
+
}), /* @__PURE__ */ E("span", {
|
|
76
93
|
className: "truncate font-medium text-text-primary",
|
|
77
|
-
children: e.team?.name ?? "Team"
|
|
94
|
+
children: e.team?.name ?? r("atheletebridge.pages.analytics.standings.teamFallback", "Team")
|
|
78
95
|
})]
|
|
79
96
|
})
|
|
80
97
|
},
|
|
81
98
|
{
|
|
82
99
|
key: "played",
|
|
83
|
-
header: "P",
|
|
100
|
+
header: r("atheletebridge.pages.analytics.standings.played", "P"),
|
|
84
101
|
priority: "hidden-on-mobile",
|
|
85
|
-
cell: (e) => /* @__PURE__ */
|
|
102
|
+
cell: (e) => /* @__PURE__ */ E("span", {
|
|
86
103
|
className: "tabular-nums text-text-secondary",
|
|
87
104
|
children: e.played
|
|
88
105
|
})
|
|
89
106
|
},
|
|
90
107
|
{
|
|
91
108
|
key: "gd",
|
|
92
|
-
header: "GD",
|
|
109
|
+
header: r("atheletebridge.pages.analytics.standings.gd", "GD"),
|
|
93
110
|
priority: "hidden-on-mobile",
|
|
94
111
|
cell: (e) => {
|
|
95
112
|
let t = e.goalsFor - e.goalsAgainst;
|
|
96
|
-
return /* @__PURE__ */
|
|
113
|
+
return /* @__PURE__ */ D("span", {
|
|
97
114
|
className: "tabular-nums text-text-secondary",
|
|
98
115
|
children: [t > 0 ? "+" : "", t]
|
|
99
116
|
});
|
|
@@ -101,135 +118,137 @@ function L() {
|
|
|
101
118
|
},
|
|
102
119
|
{
|
|
103
120
|
key: "points",
|
|
104
|
-
header: "Pts",
|
|
121
|
+
header: r("atheletebridge.pages.analytics.standings.points", "Pts"),
|
|
105
122
|
priority: "secondary",
|
|
106
|
-
cell: (e) => /* @__PURE__ */
|
|
123
|
+
cell: (e) => /* @__PURE__ */ E("span", {
|
|
107
124
|
className: "font-semibold tabular-nums text-text-primary",
|
|
108
125
|
children: e.points
|
|
109
126
|
})
|
|
110
127
|
}
|
|
111
128
|
];
|
|
112
|
-
if (
|
|
113
|
-
title: "Coach analytics",
|
|
114
|
-
children: /* @__PURE__ */
|
|
129
|
+
if (z.isLoading) return /* @__PURE__ */ E(n, {
|
|
130
|
+
title: r("atheletebridge.pages.analytics.title", "Coach analytics"),
|
|
131
|
+
children: /* @__PURE__ */ E(m, { label: r("atheletebridge.pages.analytics.loading", "Crunching coaching data…") })
|
|
115
132
|
});
|
|
116
|
-
if (
|
|
117
|
-
title: "Coach analytics",
|
|
118
|
-
children: /* @__PURE__ */
|
|
119
|
-
title: "Analytics unavailable",
|
|
120
|
-
message: "We could not load coaching analytics. Please try again."
|
|
133
|
+
if (z.isError) return /* @__PURE__ */ E(n, {
|
|
134
|
+
title: r("atheletebridge.pages.analytics.title", "Coach analytics"),
|
|
135
|
+
children: /* @__PURE__ */ E(p, {
|
|
136
|
+
title: r("atheletebridge.pages.analytics.errorTitle", "Analytics unavailable"),
|
|
137
|
+
message: r("atheletebridge.pages.analytics.errorMessage", "We could not load coaching analytics. Please try again.")
|
|
121
138
|
})
|
|
122
139
|
});
|
|
123
|
-
let
|
|
124
|
-
return /* @__PURE__ */
|
|
125
|
-
title: /* @__PURE__ */
|
|
140
|
+
let G = z.totalSessions > 0 || z.standings.length > 0 || z.loadByAthlete.length > 0, K = L(z.trainingLoad.ratio, r);
|
|
141
|
+
return /* @__PURE__ */ E(n, {
|
|
142
|
+
title: /* @__PURE__ */ D("span", {
|
|
126
143
|
className: "flex items-center gap-2",
|
|
127
|
-
children: [/* @__PURE__ */
|
|
144
|
+
children: [/* @__PURE__ */ E(A, { children: r("atheletebridge.pages.analytics.title", "Coach analytics") }), /* @__PURE__ */ E(O, {
|
|
128
145
|
variant: "outline",
|
|
129
|
-
children: "Beta"
|
|
146
|
+
children: r("common.beta", "Beta")
|
|
130
147
|
})]
|
|
131
148
|
}),
|
|
132
|
-
description: "Honest aggregates over your real sessions, workouts and results.",
|
|
133
|
-
children:
|
|
149
|
+
description: r("atheletebridge.pages.analytics.description", "Honest aggregates over your real sessions, workouts and results."),
|
|
150
|
+
children: G ? /* @__PURE__ */ D("div", {
|
|
134
151
|
className: "space-y-8",
|
|
135
152
|
children: [
|
|
136
|
-
/* @__PURE__ */
|
|
153
|
+
/* @__PURE__ */ D("div", {
|
|
137
154
|
className: "grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3",
|
|
138
155
|
children: [
|
|
139
|
-
/* @__PURE__ */
|
|
140
|
-
icon: /* @__PURE__ */
|
|
141
|
-
value:
|
|
142
|
-
label: "Total sessions",
|
|
156
|
+
/* @__PURE__ */ E(c, {
|
|
157
|
+
icon: /* @__PURE__ */ E(S, { className: "h-5 w-5" }),
|
|
158
|
+
value: z.totalSessions,
|
|
159
|
+
label: r("atheletebridge.pages.analytics.totalSessions", "Total sessions"),
|
|
143
160
|
tone: "accent"
|
|
144
161
|
}),
|
|
145
|
-
/* @__PURE__ */
|
|
162
|
+
/* @__PURE__ */ D(k, {
|
|
146
163
|
treatment: "metric",
|
|
147
164
|
className: "flex flex-col justify-between gap-3 p-5",
|
|
148
165
|
children: [
|
|
149
|
-
/* @__PURE__ */
|
|
166
|
+
/* @__PURE__ */ D("div", {
|
|
150
167
|
className: "flex items-start justify-between gap-2",
|
|
151
|
-
children: [/* @__PURE__ */
|
|
168
|
+
children: [/* @__PURE__ */ E("span", {
|
|
152
169
|
className: "text-sm font-medium text-text-secondary",
|
|
153
|
-
children: "Avg session rating"
|
|
154
|
-
}), /* @__PURE__ */
|
|
170
|
+
children: r("atheletebridge.pages.analytics.avgRating", "Avg session rating")
|
|
171
|
+
}), /* @__PURE__ */ E(C, { className: "h-5 w-5 text-text-muted" })]
|
|
155
172
|
}),
|
|
156
|
-
|
|
173
|
+
z.avgRating == null ? /* @__PURE__ */ E("span", {
|
|
157
174
|
className: "text-sm text-text-muted",
|
|
158
|
-
children: "No rated sessions yet"
|
|
159
|
-
}) : /* @__PURE__ */
|
|
175
|
+
children: r("atheletebridge.pages.analytics.noRatedSessions", "No rated sessions yet")
|
|
176
|
+
}) : /* @__PURE__ */ D("div", {
|
|
160
177
|
className: "flex items-end gap-3",
|
|
161
|
-
children: [/* @__PURE__ */
|
|
178
|
+
children: [/* @__PURE__ */ D("span", {
|
|
162
179
|
className: "text-3xl font-semibold leading-none tabular-nums text-text-primary",
|
|
163
|
-
children: [
|
|
180
|
+
children: [z.avgRating.toFixed(1), /* @__PURE__ */ E("span", {
|
|
164
181
|
className: "ml-1 text-base text-text-secondary",
|
|
165
|
-
children: "/5"
|
|
182
|
+
children: r("atheletebridge.pages.analytics.ratingOutOf", "/5")
|
|
166
183
|
})]
|
|
167
|
-
}), /* @__PURE__ */
|
|
184
|
+
}), /* @__PURE__ */ E("div", {
|
|
168
185
|
className: "pb-1",
|
|
169
|
-
children: /* @__PURE__ */
|
|
170
|
-
value:
|
|
186
|
+
children: /* @__PURE__ */ E(s, {
|
|
187
|
+
value: z.avgRating,
|
|
171
188
|
max: 5,
|
|
172
189
|
size: 16
|
|
173
190
|
})
|
|
174
191
|
})]
|
|
175
192
|
}),
|
|
176
|
-
/* @__PURE__ */
|
|
193
|
+
/* @__PURE__ */ D("span", {
|
|
177
194
|
className: "text-xs text-text-muted tabular-nums",
|
|
178
195
|
children: [
|
|
179
|
-
|
|
180
|
-
"
|
|
181
|
-
|
|
196
|
+
z.ratedCount,
|
|
197
|
+
" ",
|
|
198
|
+
r("atheletebridge.pages.analytics.ratedOf", "rated of"),
|
|
199
|
+
" ",
|
|
200
|
+
z.totalSessions
|
|
182
201
|
]
|
|
183
202
|
})
|
|
184
203
|
]
|
|
185
204
|
}),
|
|
186
|
-
/* @__PURE__ */
|
|
187
|
-
icon: /* @__PURE__ */
|
|
188
|
-
value: `${Math.round(
|
|
189
|
-
label: "Sessions completed",
|
|
205
|
+
/* @__PURE__ */ E(c, {
|
|
206
|
+
icon: /* @__PURE__ */ E(b, { className: "h-5 w-5" }),
|
|
207
|
+
value: `${Math.round(z.completedPct)}%`,
|
|
208
|
+
label: r("atheletebridge.pages.analytics.sessionsCompleted", "Sessions completed"),
|
|
190
209
|
tone: "success"
|
|
191
210
|
})
|
|
192
211
|
]
|
|
193
212
|
}),
|
|
194
|
-
/* @__PURE__ */
|
|
213
|
+
/* @__PURE__ */ D("div", {
|
|
195
214
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
|
|
196
|
-
children: [/* @__PURE__ */
|
|
215
|
+
children: [/* @__PURE__ */ D(k, {
|
|
197
216
|
treatment: "insight",
|
|
198
217
|
className: "p-6",
|
|
199
|
-
children: [/* @__PURE__ */
|
|
218
|
+
children: [/* @__PURE__ */ E("h2", {
|
|
200
219
|
className: "mb-4 text-lg font-semibold text-text-primary",
|
|
201
|
-
children: "Session status overview"
|
|
202
|
-
}),
|
|
203
|
-
segments:
|
|
204
|
-
centerLabel:
|
|
205
|
-
centerCaption: "sessions",
|
|
220
|
+
children: r("atheletebridge.pages.analytics.statusOverviewTitle", "Session status overview")
|
|
221
|
+
}), V.length > 0 ? /* @__PURE__ */ E(o, {
|
|
222
|
+
segments: V,
|
|
223
|
+
centerLabel: z.totalSessions,
|
|
224
|
+
centerCaption: r("atheletebridge.pages.analytics.sessionsCaption", "sessions"),
|
|
206
225
|
valueFormatter: (e) => e.toLocaleString()
|
|
207
|
-
}) : /* @__PURE__ */
|
|
226
|
+
}) : /* @__PURE__ */ E("p", {
|
|
208
227
|
className: "text-sm text-text-muted",
|
|
209
|
-
children: "No sessions to break down yet."
|
|
228
|
+
children: r("atheletebridge.pages.analytics.statusOverviewEmpty", "No sessions to break down yet.")
|
|
210
229
|
})]
|
|
211
|
-
}), /* @__PURE__ */
|
|
230
|
+
}), /* @__PURE__ */ D(k, {
|
|
212
231
|
treatment: "insight",
|
|
213
232
|
className: "p-6",
|
|
214
|
-
children: [/* @__PURE__ */
|
|
233
|
+
children: [/* @__PURE__ */ E("h2", {
|
|
215
234
|
className: "mb-4 text-lg font-semibold text-text-primary",
|
|
216
|
-
children: "Average rating by coach"
|
|
217
|
-
}),
|
|
218
|
-
series:
|
|
235
|
+
children: r("atheletebridge.pages.analytics.ratingByCoachTitle", "Average rating by coach")
|
|
236
|
+
}), U.length > 0 ? /* @__PURE__ */ D(T, { children: [/* @__PURE__ */ E(a, {
|
|
237
|
+
series: U,
|
|
219
238
|
height: 220,
|
|
220
239
|
colorful: !0,
|
|
221
240
|
valueFormatter: (e) => e.toFixed(1)
|
|
222
|
-
}), /* @__PURE__ */
|
|
241
|
+
}), /* @__PURE__ */ E("div", {
|
|
223
242
|
className: "mt-3 flex flex-wrap gap-x-4 gap-y-2",
|
|
224
|
-
children:
|
|
243
|
+
children: z.ratingByCoach.map((e) => /* @__PURE__ */ D("span", {
|
|
225
244
|
className: "flex items-center gap-2 text-xs text-text-secondary",
|
|
226
|
-
children: [/* @__PURE__ */
|
|
227
|
-
name:
|
|
245
|
+
children: [/* @__PURE__ */ E(d, {
|
|
246
|
+
name: B.nameOf(e.coachId),
|
|
228
247
|
id: e.coachId,
|
|
229
248
|
size: "xs"
|
|
230
|
-
}), /* @__PURE__ */
|
|
249
|
+
}), /* @__PURE__ */ D("span", {
|
|
231
250
|
className: "truncate",
|
|
232
|
-
children: [
|
|
251
|
+
children: [R(B.nameOf(e.coachId), e.coachId, r("atheletebridge.rolePrefix.coach", "Coach")), /* @__PURE__ */ D("span", {
|
|
233
252
|
className: "ml-1 text-text-muted tabular-nums",
|
|
234
253
|
children: [
|
|
235
254
|
"(",
|
|
@@ -239,134 +258,271 @@ function L() {
|
|
|
239
258
|
})]
|
|
240
259
|
})]
|
|
241
260
|
}, e.coachId))
|
|
242
|
-
})] }) : /* @__PURE__ */
|
|
261
|
+
})] }) : /* @__PURE__ */ E("p", {
|
|
243
262
|
className: "text-sm text-text-muted",
|
|
244
|
-
children: "Rate completed sessions to compare coaches."
|
|
263
|
+
children: r("atheletebridge.pages.analytics.ratingByCoachEmpty", "Rate completed sessions to compare coaches.")
|
|
245
264
|
})]
|
|
246
265
|
})]
|
|
247
266
|
}),
|
|
248
|
-
/* @__PURE__ */
|
|
267
|
+
/* @__PURE__ */ D("div", {
|
|
249
268
|
className: "grid grid-cols-1 gap-6 lg:grid-cols-2",
|
|
250
|
-
children: [/* @__PURE__ */
|
|
269
|
+
children: [/* @__PURE__ */ D(k, {
|
|
251
270
|
treatment: "insight",
|
|
252
271
|
className: "p-6",
|
|
253
|
-
children: [/* @__PURE__ */
|
|
272
|
+
children: [/* @__PURE__ */ D("div", {
|
|
254
273
|
className: "mb-4 flex items-center justify-between gap-2",
|
|
255
|
-
children: [/* @__PURE__ */
|
|
274
|
+
children: [/* @__PURE__ */ E("h2", {
|
|
256
275
|
className: "text-lg font-semibold text-text-primary",
|
|
257
|
-
children: "Weekly training load"
|
|
258
|
-
}), /* @__PURE__ */
|
|
276
|
+
children: r("atheletebridge.pages.analytics.weeklyLoadTitle", "Weekly training load")
|
|
277
|
+
}), /* @__PURE__ */ E(P, { children: /* @__PURE__ */ D(M, { children: [/* @__PURE__ */ E(F, {
|
|
259
278
|
asChild: !0,
|
|
260
|
-
children: /* @__PURE__ */
|
|
279
|
+
children: /* @__PURE__ */ E("button", {
|
|
261
280
|
type: "button",
|
|
262
|
-
"aria-label": "About ACWR training load",
|
|
281
|
+
"aria-label": r("atheletebridge.pages.analytics.acwrAboutLabel", "About ACWR training load"),
|
|
263
282
|
className: "rounded-full p-1 text-text-muted transition-colors hover:text-text-primary",
|
|
264
|
-
children: /* @__PURE__ */
|
|
283
|
+
children: /* @__PURE__ */ E(x, { className: "h-4 w-4" })
|
|
265
284
|
})
|
|
266
|
-
}), /* @__PURE__ */
|
|
285
|
+
}), /* @__PURE__ */ E(N, {
|
|
267
286
|
className: "max-w-xs",
|
|
268
|
-
children:
|
|
269
|
-
"Total workout load per week (sum of real ",
|
|
270
|
-
/* @__PURE__ */ w("code", { children: "totalLoad" }),
|
|
271
|
-
"). 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
|
-
]
|
|
287
|
+
children: r("atheletebridge.pages.analytics.acwrAbout", "Total workout load per week (sum of real totalLoad). 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.")
|
|
273
288
|
})] }) })]
|
|
274
|
-
}),
|
|
275
|
-
series:
|
|
276
|
-
seriesLabel: "Training load",
|
|
289
|
+
}), z.loadTrend.some((e) => e.value > 0) ? /* @__PURE__ */ D(T, { children: [/* @__PURE__ */ E(i, {
|
|
290
|
+
series: z.loadTrend,
|
|
291
|
+
seriesLabel: r("atheletebridge.pages.analytics.trainingLoadLabel", "Training load"),
|
|
277
292
|
height: 200,
|
|
278
293
|
valueFormatter: (e) => e.toLocaleString()
|
|
279
|
-
}), /* @__PURE__ */
|
|
294
|
+
}), /* @__PURE__ */ D("div", {
|
|
280
295
|
className: "mt-4 flex flex-wrap items-center gap-x-6 gap-y-2 text-sm",
|
|
281
296
|
children: [
|
|
282
|
-
/* @__PURE__ */
|
|
297
|
+
/* @__PURE__ */ D("span", {
|
|
283
298
|
className: "text-text-secondary",
|
|
284
299
|
children: [
|
|
285
|
-
"Acute (7d)",
|
|
300
|
+
r("atheletebridge.pages.analytics.acuteLoad", "Acute (7d)"),
|
|
286
301
|
" ",
|
|
287
|
-
/* @__PURE__ */
|
|
302
|
+
/* @__PURE__ */ E("span", {
|
|
288
303
|
className: "font-semibold tabular-nums text-text-primary",
|
|
289
|
-
children: Math.round(
|
|
304
|
+
children: Math.round(z.trainingLoad.acute).toLocaleString()
|
|
290
305
|
})
|
|
291
306
|
]
|
|
292
307
|
}),
|
|
293
|
-
/* @__PURE__ */
|
|
308
|
+
/* @__PURE__ */ D("span", {
|
|
294
309
|
className: "text-text-secondary",
|
|
295
310
|
children: [
|
|
296
|
-
"Chronic (28d avg)",
|
|
311
|
+
r("atheletebridge.pages.analytics.chronicLoad", "Chronic (28d avg)"),
|
|
297
312
|
" ",
|
|
298
|
-
/* @__PURE__ */
|
|
313
|
+
/* @__PURE__ */ E("span", {
|
|
299
314
|
className: "font-semibold tabular-nums text-text-primary",
|
|
300
|
-
children: Math.round(
|
|
315
|
+
children: Math.round(z.trainingLoad.chronic).toLocaleString()
|
|
301
316
|
})
|
|
302
317
|
]
|
|
303
318
|
}),
|
|
304
|
-
/* @__PURE__ */
|
|
319
|
+
/* @__PURE__ */ D("span", {
|
|
305
320
|
className: "flex items-center gap-2 text-text-secondary",
|
|
306
|
-
children: ["ACWR", /* @__PURE__ */
|
|
307
|
-
variant:
|
|
321
|
+
children: [r("atheletebridge.pages.analytics.acwrAbbreviation", "ACWR"), /* @__PURE__ */ E(O, {
|
|
322
|
+
variant: K.variant,
|
|
308
323
|
className: "tabular-nums",
|
|
309
|
-
children:
|
|
324
|
+
children: z.trainingLoad.ratio == null ? K.label : `${z.trainingLoad.ratio.toFixed(2)} · ${K.label}`
|
|
310
325
|
})]
|
|
311
326
|
})
|
|
312
327
|
]
|
|
313
|
-
})] }) : /* @__PURE__ */
|
|
328
|
+
})] }) : /* @__PURE__ */ E("p", {
|
|
314
329
|
className: "text-sm text-text-muted",
|
|
315
|
-
children: "Log workouts with a load to see training trend."
|
|
330
|
+
children: r("atheletebridge.pages.analytics.weeklyLoadEmpty", "Log workouts with a load to see training trend.")
|
|
316
331
|
})]
|
|
317
|
-
}), /* @__PURE__ */
|
|
332
|
+
}), /* @__PURE__ */ D(k, {
|
|
318
333
|
treatment: "insight",
|
|
319
334
|
className: "p-6",
|
|
320
|
-
children: [/* @__PURE__ */
|
|
335
|
+
children: [/* @__PURE__ */ E("h2", {
|
|
321
336
|
className: "mb-4 text-lg font-semibold text-text-primary",
|
|
322
|
-
children: "Sessions per week"
|
|
323
|
-
}),
|
|
324
|
-
series:
|
|
337
|
+
children: r("atheletebridge.pages.analytics.sessionsPerWeekTitle", "Sessions per week")
|
|
338
|
+
}), z.sessionTrend.some((e) => e.value > 0) ? /* @__PURE__ */ E(a, {
|
|
339
|
+
series: z.sessionTrend,
|
|
325
340
|
height: 200,
|
|
326
341
|
valueFormatter: (e) => e.toLocaleString()
|
|
327
|
-
}) : /* @__PURE__ */
|
|
342
|
+
}) : /* @__PURE__ */ E("p", {
|
|
328
343
|
className: "text-sm text-text-muted",
|
|
329
|
-
children: "Schedule sessions to see weekly volume."
|
|
344
|
+
children: r("atheletebridge.pages.analytics.sessionsPerWeekEmpty", "Schedule sessions to see weekly volume.")
|
|
330
345
|
})]
|
|
331
346
|
})]
|
|
332
347
|
}),
|
|
333
|
-
|
|
348
|
+
/* @__PURE__ */ E(H, {
|
|
349
|
+
rows: z.loadByAthlete,
|
|
350
|
+
directory: B,
|
|
351
|
+
truncated: z.loadSampleTruncated,
|
|
352
|
+
tr: r
|
|
353
|
+
}),
|
|
354
|
+
z.standings.length > 0 ? /* @__PURE__ */ D("section", { children: [/* @__PURE__ */ D("div", {
|
|
334
355
|
className: "mb-4 flex flex-wrap items-center justify-between gap-3",
|
|
335
|
-
children: [/* @__PURE__ */
|
|
356
|
+
children: [/* @__PURE__ */ D("h2", {
|
|
336
357
|
className: "flex items-center gap-2 text-lg font-semibold text-text-primary",
|
|
337
358
|
children: [
|
|
338
|
-
/* @__PURE__ */
|
|
339
|
-
"League standings",
|
|
340
|
-
|
|
359
|
+
/* @__PURE__ */ E(v, { className: "h-5 w-5 text-text-muted" }),
|
|
360
|
+
r("atheletebridge.pages.analytics.standingsTitle", "League standings"),
|
|
361
|
+
z.competition ? /* @__PURE__ */ E(O, {
|
|
341
362
|
variant: "secondary",
|
|
342
|
-
children:
|
|
363
|
+
children: z.competition
|
|
343
364
|
}) : null
|
|
344
365
|
]
|
|
345
|
-
}), /* @__PURE__ */
|
|
366
|
+
}), /* @__PURE__ */ E("button", {
|
|
346
367
|
type: "button",
|
|
347
|
-
onClick: () =>
|
|
368
|
+
onClick: () => w("/standings"),
|
|
348
369
|
className: "text-sm font-medium text-[var(--color-accent-teal)] transition-colors hover:underline",
|
|
349
|
-
children: "View full standings"
|
|
370
|
+
children: r("atheletebridge.pages.analytics.viewFullStandings", "View full standings")
|
|
350
371
|
})]
|
|
351
|
-
}), /* @__PURE__ */
|
|
372
|
+
}), /* @__PURE__ */ E(k, {
|
|
352
373
|
treatment: "insight",
|
|
353
374
|
className: "p-2 sm:p-4",
|
|
354
|
-
children: /* @__PURE__ */
|
|
355
|
-
columns:
|
|
356
|
-
data:
|
|
375
|
+
children: /* @__PURE__ */ E(j, {
|
|
376
|
+
columns: W,
|
|
377
|
+
data: z.standings,
|
|
357
378
|
rowKey: (e) => e.id
|
|
358
379
|
})
|
|
359
380
|
})] }) : null
|
|
360
381
|
]
|
|
361
|
-
}) : /* @__PURE__ */
|
|
382
|
+
}) : /* @__PURE__ */ E(f, {
|
|
362
383
|
illustration: "empty-data",
|
|
363
|
-
icon: /* @__PURE__ */
|
|
364
|
-
title: "No coaching data yet",
|
|
365
|
-
description: "Book and complete sessions, log workouts and record fixtures to unlock analytics."
|
|
384
|
+
icon: /* @__PURE__ */ E(y, { className: "h-10 w-10" }),
|
|
385
|
+
title: r("atheletebridge.pages.analytics.emptyTitle", "No coaching data yet"),
|
|
386
|
+
description: r("atheletebridge.pages.analytics.emptyDescription", "Book and complete sessions, log workouts and record fixtures to unlock analytics.")
|
|
366
387
|
})
|
|
367
388
|
});
|
|
368
389
|
}
|
|
390
|
+
function H({ rows: e, directory: t, truncated: n, tr: r }) {
|
|
391
|
+
let i = _(() => e.reduce((e, t) => Math.max(e, t.acute, t.chronic), 0), [e]), a = _(() => [
|
|
392
|
+
{
|
|
393
|
+
key: "athlete",
|
|
394
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.athlete", "Athlete"),
|
|
395
|
+
priority: "primary",
|
|
396
|
+
cell: (e) => /* @__PURE__ */ D("span", {
|
|
397
|
+
className: "flex items-center gap-2",
|
|
398
|
+
children: [/* @__PURE__ */ E(d, {
|
|
399
|
+
name: t.nameOf(e.athleteId),
|
|
400
|
+
id: e.athleteId,
|
|
401
|
+
size: "xs"
|
|
402
|
+
}), /* @__PURE__ */ D("span", {
|
|
403
|
+
className: "min-w-0",
|
|
404
|
+
children: [/* @__PURE__ */ E("span", {
|
|
405
|
+
className: "block truncate font-medium text-text-primary",
|
|
406
|
+
children: R(t.nameOf(e.athleteId), e.athleteId, r("atheletebridge.rolePrefix.athlete", "Athlete"))
|
|
407
|
+
}), /* @__PURE__ */ D("span", {
|
|
408
|
+
className: "block text-xs tabular-nums text-text-muted",
|
|
409
|
+
children: [
|
|
410
|
+
e.workoutCount,
|
|
411
|
+
" ",
|
|
412
|
+
r("atheletebridge.pages.analytics.loadByAthlete.workouts28d", "workouts · 28d")
|
|
413
|
+
]
|
|
414
|
+
})]
|
|
415
|
+
})]
|
|
416
|
+
})
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
key: "acute",
|
|
420
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.acute", "Acute load (7d)"),
|
|
421
|
+
priority: "secondary",
|
|
422
|
+
mobileLabel: r("atheletebridge.pages.analytics.loadByAthlete.acute", "Acute load (7d)"),
|
|
423
|
+
cell: (e) => e.loadedCount === 0 ? /* @__PURE__ */ E("span", {
|
|
424
|
+
className: "text-text-muted",
|
|
425
|
+
children: "—"
|
|
426
|
+
}) : /* @__PURE__ */ D("span", {
|
|
427
|
+
className: "flex items-center gap-2",
|
|
428
|
+
children: [/* @__PURE__ */ E("span", {
|
|
429
|
+
className: "w-14 text-right font-medium tabular-nums text-text-primary",
|
|
430
|
+
children: z(e.acute)
|
|
431
|
+
}), /* @__PURE__ */ E(B, {
|
|
432
|
+
value: e.acute,
|
|
433
|
+
max: i
|
|
434
|
+
})]
|
|
435
|
+
})
|
|
436
|
+
},
|
|
437
|
+
{
|
|
438
|
+
key: "chronic",
|
|
439
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.chronic", "Chronic load (28d avg)"),
|
|
440
|
+
priority: "secondary",
|
|
441
|
+
mobileLabel: r("atheletebridge.pages.analytics.loadByAthlete.chronic", "Chronic load (28d avg)"),
|
|
442
|
+
cell: (e) => e.loadedCount === 0 ? /* @__PURE__ */ E("span", {
|
|
443
|
+
className: "text-text-muted",
|
|
444
|
+
children: "—"
|
|
445
|
+
}) : /* @__PURE__ */ D("span", {
|
|
446
|
+
className: "flex items-center gap-2",
|
|
447
|
+
children: [/* @__PURE__ */ E("span", {
|
|
448
|
+
className: "w-14 text-right font-medium tabular-nums text-text-primary",
|
|
449
|
+
children: z(e.chronic)
|
|
450
|
+
}), /* @__PURE__ */ E(B, {
|
|
451
|
+
value: e.chronic,
|
|
452
|
+
max: i
|
|
453
|
+
})]
|
|
454
|
+
})
|
|
455
|
+
},
|
|
456
|
+
{
|
|
457
|
+
key: "ratio",
|
|
458
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.ratio", "Load ratio"),
|
|
459
|
+
priority: "secondary",
|
|
460
|
+
mobileLabel: r("atheletebridge.pages.analytics.loadByAthlete.ratio", "Load ratio"),
|
|
461
|
+
cell: (e) => e.ratio == null ? /* @__PURE__ */ E("span", {
|
|
462
|
+
className: "text-text-muted",
|
|
463
|
+
children: "—"
|
|
464
|
+
}) : /* @__PURE__ */ E("span", {
|
|
465
|
+
className: "font-semibold tabular-nums text-text-primary",
|
|
466
|
+
children: e.ratio.toFixed(2)
|
|
467
|
+
})
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
key: "band",
|
|
471
|
+
header: r("atheletebridge.pages.analytics.loadByAthlete.status", "Status"),
|
|
472
|
+
priority: "primary",
|
|
473
|
+
mobileLabel: r("atheletebridge.pages.analytics.loadByAthlete.status", "Status"),
|
|
474
|
+
cell: (e) => {
|
|
475
|
+
let t = L(e.ratio, r);
|
|
476
|
+
return /* @__PURE__ */ E(O, {
|
|
477
|
+
variant: t.variant,
|
|
478
|
+
children: t.label
|
|
479
|
+
});
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
], [
|
|
483
|
+
t,
|
|
484
|
+
i,
|
|
485
|
+
r
|
|
486
|
+
]);
|
|
487
|
+
return /* @__PURE__ */ D("section", { children: [/* @__PURE__ */ D("div", {
|
|
488
|
+
className: "mb-4 flex flex-wrap items-center gap-2",
|
|
489
|
+
children: [/* @__PURE__ */ D("h2", {
|
|
490
|
+
className: "flex items-center gap-2 text-lg font-semibold text-text-primary",
|
|
491
|
+
children: [/* @__PURE__ */ E(w, { className: "h-5 w-5 text-text-muted" }), r("atheletebridge.pages.analytics.loadByAthlete.title", "Training load by athlete")]
|
|
492
|
+
}), /* @__PURE__ */ E(P, { children: /* @__PURE__ */ D(M, { children: [/* @__PURE__ */ E(F, {
|
|
493
|
+
asChild: !0,
|
|
494
|
+
children: /* @__PURE__ */ E("button", {
|
|
495
|
+
type: "button",
|
|
496
|
+
"aria-label": r("atheletebridge.pages.analytics.loadByAthlete.aboutLabel", "About per-athlete training load"),
|
|
497
|
+
className: "rounded-full p-1 text-text-muted transition-colors hover:text-text-primary",
|
|
498
|
+
children: /* @__PURE__ */ E(x, { className: "h-4 w-4" })
|
|
499
|
+
})
|
|
500
|
+
}), /* @__PURE__ */ E(N, {
|
|
501
|
+
className: "max-w-xs",
|
|
502
|
+
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.")
|
|
503
|
+
})] }) })]
|
|
504
|
+
}), e.length === 0 ? /* @__PURE__ */ E(k, {
|
|
505
|
+
treatment: "insight",
|
|
506
|
+
className: "p-6",
|
|
507
|
+
children: /* @__PURE__ */ E("p", {
|
|
508
|
+
className: "text-sm text-text-muted",
|
|
509
|
+
children: r("atheletebridge.pages.analytics.loadByAthlete.empty", "No workouts logged in the last 28 days. Log workouts with a total load to compare athletes.")
|
|
510
|
+
})
|
|
511
|
+
}) : /* @__PURE__ */ D(T, { children: [/* @__PURE__ */ E(k, {
|
|
512
|
+
treatment: "insight",
|
|
513
|
+
className: "p-2 sm:p-4",
|
|
514
|
+
children: /* @__PURE__ */ E(j, {
|
|
515
|
+
columns: a,
|
|
516
|
+
data: e,
|
|
517
|
+
rowKey: (e) => e.athleteId,
|
|
518
|
+
caption: r("atheletebridge.pages.analytics.loadByAthlete.caption", "Acute and chronic training load per athlete over the last 28 days")
|
|
519
|
+
})
|
|
520
|
+
}), n ? /* @__PURE__ */ E("p", {
|
|
521
|
+
className: "mt-3 text-xs text-text-muted",
|
|
522
|
+
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.")
|
|
523
|
+
}) : null] })] });
|
|
524
|
+
}
|
|
369
525
|
//#endregion
|
|
370
|
-
export {
|
|
526
|
+
export { V as CoachAnalyticsPage };
|
|
371
527
|
|
|
372
528
|
//# sourceMappingURL=CoachAnalyticsPage.js.map
|