@burdenoff/microfe-atheletebridge 2026.710.1 → 2026.716.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/AthleteBridgeRoot.js +50 -53
- package/dist/atheletebridge/AthleteBridgeRoot.js.map +1 -1
- package/dist/atheletebridge/AthleteBridgeRoutes.d.ts.map +1 -1
- package/dist/atheletebridge/AthleteBridgeRoutes.js +29 -25
- package/dist/atheletebridge/AthleteBridgeRoutes.js.map +1 -1
- package/dist/atheletebridge/admin/AdminDashboardPage.d.ts +4 -0
- package/dist/atheletebridge/admin/AdminDashboardPage.d.ts.map +1 -0
- package/dist/atheletebridge/admin/AdminDashboardPage.js +553 -0
- package/dist/atheletebridge/admin/AdminDashboardPage.js.map +1 -0
- package/dist/atheletebridge/admin/AdminRoot.d.ts +9 -0
- package/dist/atheletebridge/admin/AdminRoot.d.ts.map +1 -0
- package/dist/atheletebridge/admin/AdminRoot.js +23 -0
- package/dist/atheletebridge/admin/AdminRoot.js.map +1 -0
- package/dist/atheletebridge/admin/index.d.ts +11 -0
- package/dist/atheletebridge/admin/index.d.ts.map +1 -0
- package/dist/atheletebridge/admin/index.js +2 -0
- package/dist/atheletebridge/components/DrillVideoLink.js +1 -1
- package/dist/atheletebridge/components/DrillVideoLink.js.map +1 -1
- package/dist/atheletebridge/components/UserSearchSelect.js +2 -2
- package/dist/atheletebridge/components/UserSearchSelect.js.map +1 -1
- package/dist/atheletebridge/components/domain.js +3 -3
- package/dist/atheletebridge/components/domain.js.map +1 -1
- package/dist/atheletebridge/hooks/index.js +1 -0
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.d.ts.map +1 -1
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +27 -27
- package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
- package/dist/atheletebridge/i18n.d.ts +26 -0
- package/dist/atheletebridge/i18n.d.ts.map +1 -0
- package/dist/atheletebridge/i18n.js +14 -0
- package/dist/atheletebridge/i18n.js.map +1 -0
- package/dist/atheletebridge/index.d.ts +1 -0
- package/dist/atheletebridge/index.d.ts.map +1 -1
- package/dist/atheletebridge/index.js +3 -0
- package/dist/atheletebridge/pages/DashboardPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/DashboardPage.js +166 -144
- package/dist/atheletebridge/pages/DashboardPage.js.map +1 -1
- package/dist/atheletebridge/pages/StandingsPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/StandingsPage.js +98 -92
- package/dist/atheletebridge/pages/StandingsPage.js.map +1 -1
- package/dist/atheletebridge/pages/fixtures/FixturesListPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/fixtures/FixturesListPage.js +6 -4
- package/dist/atheletebridge/pages/fixtures/FixturesListPage.js.map +1 -1
- package/dist/atheletebridge/pages/onboarding/OnboardingPage.d.ts +4 -0
- package/dist/atheletebridge/pages/onboarding/OnboardingPage.d.ts.map +1 -0
- package/dist/atheletebridge/pages/onboarding/OnboardingPage.js +371 -0
- package/dist/atheletebridge/pages/onboarding/OnboardingPage.js.map +1 -0
- package/dist/atheletebridge/pages/performance/PerformancePage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/performance/PerformancePage.js +42 -41
- package/dist/atheletebridge/pages/performance/PerformancePage.js.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramsListPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/programs/ProgramsListPage.js +8 -6
- package/dist/atheletebridge/pages/programs/ProgramsListPage.js.map +1 -1
- package/dist/atheletebridge/pages/sessions/SessionDetailPage.js +1 -1
- 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 +6 -4
- package/dist/atheletebridge/pages/sessions/SessionsListPage.js.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamsListPage.d.ts.map +1 -1
- package/dist/atheletebridge/pages/teams/TeamsListPage.js +7 -5
- package/dist/atheletebridge/pages/teams/TeamsListPage.js.map +1 -1
- package/dist/atheletebridge/types/index.d.ts.map +1 -1
- package/dist/index.js +5 -3
- package/dist/services/createSandboxAssistantTransport.d.ts +8 -7
- package/dist/services/createSandboxAssistantTransport.d.ts.map +1 -1
- package/dist/services/createSandboxAssistantTransport.js +8 -114
- package/dist/services/createSandboxAssistantTransport.js.map +1 -1
- package/package.json +15 -4
- package/dist/generated/wspace-operations.js +0 -59
- package/dist/generated/wspace-operations.js.map +0 -1
- package/dist/services/assistantApi.d.ts +0 -70
- package/dist/services/assistantApi.d.ts.map +0 -1
- package/dist/services/assistantApi.js +0 -202
- package/dist/services/assistantApi.js.map +0 -1
|
@@ -1,242 +1,264 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
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 { Timeline as r } from "../components/viz/Timeline.js";
|
|
4
5
|
import "../components/viz/index.js";
|
|
5
|
-
import { MetricsCard as
|
|
6
|
-
import { TeamCard as
|
|
7
|
-
import { MatchupRow as
|
|
8
|
-
import { SessionCard as
|
|
9
|
-
import { EmptyState as
|
|
10
|
-
import { LoadingState as
|
|
11
|
-
import { useFixtures as
|
|
12
|
-
import { timeAgo as
|
|
13
|
-
import { useMemo as
|
|
14
|
-
import { ArrowRight as
|
|
15
|
-
import { jsx as
|
|
16
|
-
import { GlassCard as
|
|
6
|
+
import { MetricsCard as i } from "../components/MetricsCard.js";
|
|
7
|
+
import { TeamCard as a } from "../components/TeamCard.js";
|
|
8
|
+
import { MatchupRow as o } from "../components/MatchupRow.js";
|
|
9
|
+
import { SessionCard as s } from "../components/SessionCard.js";
|
|
10
|
+
import { EmptyState as c } from "../components/EmptyState.js";
|
|
11
|
+
import { LoadingState as l } from "../components/LoadingState.js";
|
|
12
|
+
import { useFixtures as u, usePrograms as d, useRecentActivity as f, useSessions as p, useTeams as m } from "../hooks/useAthleteBridgeApi.js";
|
|
13
|
+
import { timeAgo as h } from "../utils/timeAgo.js";
|
|
14
|
+
import { useMemo as g } from "react";
|
|
15
|
+
import { ArrowRight as _, CalendarDays as v, CheckCircle2 as y, ClipboardCheck as b, Dumbbell as x, Plus as S, Rocket as C, TrendingUp as w, Trophy as T, UserPlus as E, Users as D } from "lucide-react";
|
|
16
|
+
import { jsx as O, jsxs as k } from "react/jsx-runtime";
|
|
17
|
+
import { GlassCard as A, PagePurpose as j } from "@burdenoff/fe-libs/ui";
|
|
17
18
|
//#region src/atheletebridge/pages/DashboardPage.tsx
|
|
18
|
-
var
|
|
19
|
+
var M = "inline-flex items-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))]", N = {
|
|
19
20
|
"program-published": {
|
|
20
21
|
tone: "success",
|
|
21
|
-
Icon:
|
|
22
|
+
Icon: b
|
|
22
23
|
},
|
|
23
24
|
"member-added": {
|
|
24
25
|
tone: "accent",
|
|
25
|
-
Icon:
|
|
26
|
+
Icon: E
|
|
26
27
|
},
|
|
27
28
|
"fixture-updated": {
|
|
28
29
|
tone: "warning",
|
|
29
|
-
Icon:
|
|
30
|
+
Icon: v
|
|
30
31
|
},
|
|
31
32
|
"session-completed": {
|
|
32
33
|
tone: "info",
|
|
33
|
-
Icon:
|
|
34
|
+
Icon: y
|
|
34
35
|
},
|
|
35
36
|
"team-created": {
|
|
36
37
|
tone: "accent",
|
|
37
|
-
Icon:
|
|
38
|
+
Icon: D
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
|
-
function
|
|
41
|
-
let { navigateTo:
|
|
42
|
-
teams:
|
|
43
|
-
fixtures:
|
|
44
|
-
sessions:
|
|
45
|
-
programs:
|
|
41
|
+
function P() {
|
|
42
|
+
let y = e(), { navigateTo: E, currentUser: P } = t(), F = m({ pagination: { limit: 50 } }), I = u({ pagination: { limit: 50 } }), L = d({ pagination: { limit: 50 } }), R = p({ pagination: { limit: 50 } }), z = P?.firstName ?? P?.name ?? "coach", B = g(() => F.data?.items ?? [], [F.data]), V = g(() => I.data?.items ?? [], [I.data]), H = g(() => L.data?.items ?? [], [L.data]), U = g(() => R.data?.items ?? [], [R.data]), W = g(() => [...V].filter((e) => e.status === "SCHEDULED" || e.status === "LIVE").sort((e, t) => new Date(e.scheduledAt).getTime() - new Date(t.scheduledAt).getTime()).slice(0, 5), [V]), G = g(() => [...U].filter((e) => e.status === "REQUESTED" || e.status === "CONFIRMED").sort((e, t) => new Date(e.scheduledAt).getTime() - new Date(t.scheduledAt).getTime()).slice(0, 3), [U]), K = g(() => B.slice(0, 6), [B]), q = H.filter((e) => e.status === "PUBLISHED").length, J = f({
|
|
43
|
+
teams: B,
|
|
44
|
+
fixtures: V,
|
|
45
|
+
sessions: U,
|
|
46
|
+
programs: H,
|
|
46
47
|
limit: 6
|
|
47
|
-
}),
|
|
48
|
-
let t =
|
|
48
|
+
}), Y = g(() => J.map((e) => {
|
|
49
|
+
let t = N[e.type], n = t.Icon;
|
|
49
50
|
return {
|
|
50
51
|
id: e.id,
|
|
51
52
|
tone: t.tone,
|
|
52
|
-
icon: /* @__PURE__ */
|
|
53
|
+
icon: /* @__PURE__ */ O(n, {
|
|
53
54
|
className: "h-3 w-3",
|
|
54
55
|
"aria-hidden": "true"
|
|
55
56
|
}),
|
|
56
57
|
title: e.title,
|
|
57
58
|
meta: e.subtitle,
|
|
58
|
-
time:
|
|
59
|
+
time: h(e.at)
|
|
59
60
|
};
|
|
60
|
-
}), [
|
|
61
|
-
return
|
|
61
|
+
}), [J]);
|
|
62
|
+
return F.isLoading || I.isLoading || L.isLoading || R.isLoading ? /* @__PURE__ */ O(n, {
|
|
62
63
|
title: "AthleteBridge",
|
|
63
64
|
hero: !0,
|
|
64
65
|
gradientTitle: !0,
|
|
65
|
-
children: /* @__PURE__ */
|
|
66
|
-
}) : /* @__PURE__ */
|
|
67
|
-
title: `Welcome back, ${
|
|
66
|
+
children: /* @__PURE__ */ O(l, { label: y("atheletebridge.pages.dashboard.loading", "Loading your sporting operation…") })
|
|
67
|
+
}) : /* @__PURE__ */ k(n, {
|
|
68
|
+
title: `Welcome back, ${z}`,
|
|
68
69
|
description: "Your teams, fixtures, training and coaching — one connected record.",
|
|
69
70
|
hero: !0,
|
|
70
71
|
gradientTitle: !0,
|
|
71
|
-
actions: /* @__PURE__ */
|
|
72
|
+
actions: /* @__PURE__ */ k("div", {
|
|
72
73
|
className: "flex flex-wrap items-center gap-2",
|
|
73
|
-
children: [/* @__PURE__ */
|
|
74
|
+
children: [/* @__PURE__ */ k("button", {
|
|
74
75
|
type: "button",
|
|
75
|
-
onClick: () =>
|
|
76
|
-
className:
|
|
77
|
-
children: [/* @__PURE__ */
|
|
78
|
-
}), /* @__PURE__ */
|
|
76
|
+
onClick: () => E("/teams/new"),
|
|
77
|
+
className: M,
|
|
78
|
+
children: [/* @__PURE__ */ O(S, { className: "h-4 w-4" }), " New team"]
|
|
79
|
+
}), /* @__PURE__ */ k("button", {
|
|
79
80
|
type: "button",
|
|
80
|
-
onClick: () =>
|
|
81
|
-
className:
|
|
82
|
-
children: [/* @__PURE__ */
|
|
81
|
+
onClick: () => E("/performance"),
|
|
82
|
+
className: M,
|
|
83
|
+
children: [/* @__PURE__ */ O(w, { className: "h-4 w-4" }), " Track performance"]
|
|
83
84
|
})]
|
|
84
85
|
}),
|
|
85
86
|
children: [
|
|
86
|
-
/* @__PURE__ */
|
|
87
|
+
/* @__PURE__ */ O(j, {
|
|
87
88
|
className: "mb-6",
|
|
88
89
|
children: "AthleteBridge is the operating system for sports, coaching and training. From here you can assemble your roster, schedule fixtures, build training programs, run coaching sessions and track athlete performance — all reading and writing the same workspace-scoped source of truth."
|
|
89
90
|
}),
|
|
90
|
-
/* @__PURE__ */
|
|
91
|
+
/* @__PURE__ */ k("div", {
|
|
92
|
+
"data-tour": "dashboard-kpis",
|
|
91
93
|
className: "mb-8 grid grid-cols-2 gap-4 lg:grid-cols-4",
|
|
92
94
|
children: [
|
|
93
|
-
/* @__PURE__ */
|
|
94
|
-
icon: /* @__PURE__ */
|
|
95
|
-
value:
|
|
95
|
+
/* @__PURE__ */ O(i, {
|
|
96
|
+
icon: /* @__PURE__ */ O(D, { className: "h-5 w-5" }),
|
|
97
|
+
value: B.length,
|
|
96
98
|
label: "Teams",
|
|
97
99
|
tone: "accent",
|
|
98
100
|
featured: !0
|
|
99
101
|
}),
|
|
100
|
-
/* @__PURE__ */
|
|
101
|
-
icon: /* @__PURE__ */
|
|
102
|
-
value:
|
|
102
|
+
/* @__PURE__ */ O(i, {
|
|
103
|
+
icon: /* @__PURE__ */ O(v, { className: "h-5 w-5" }),
|
|
104
|
+
value: V.length,
|
|
103
105
|
label: "Fixtures",
|
|
104
106
|
tone: "accent"
|
|
105
107
|
}),
|
|
106
|
-
/* @__PURE__ */
|
|
107
|
-
icon: /* @__PURE__ */
|
|
108
|
-
value: `${
|
|
108
|
+
/* @__PURE__ */ O(i, {
|
|
109
|
+
icon: /* @__PURE__ */ O(x, { className: "h-5 w-5" }),
|
|
110
|
+
value: `${q}/${H.length}`,
|
|
109
111
|
label: "Programs published",
|
|
110
112
|
tone: "accent"
|
|
111
113
|
}),
|
|
112
|
-
/* @__PURE__ */
|
|
113
|
-
icon: /* @__PURE__ */
|
|
114
|
-
value:
|
|
114
|
+
/* @__PURE__ */ O(i, {
|
|
115
|
+
icon: /* @__PURE__ */ O(b, { className: "h-5 w-5" }),
|
|
116
|
+
value: U.length,
|
|
115
117
|
label: "Sessions",
|
|
116
118
|
tone: "accent"
|
|
117
119
|
})
|
|
118
120
|
]
|
|
119
121
|
}),
|
|
120
|
-
/* @__PURE__ */
|
|
122
|
+
/* @__PURE__ */ k("div", {
|
|
121
123
|
className: "mb-8 grid grid-cols-1 gap-6 lg:grid-cols-3",
|
|
122
|
-
children: [/* @__PURE__ */
|
|
124
|
+
children: [/* @__PURE__ */ k("section", {
|
|
125
|
+
"data-tour": "dashboard-fixtures",
|
|
123
126
|
className: "lg:col-span-2",
|
|
124
|
-
children: [/* @__PURE__ */
|
|
127
|
+
children: [/* @__PURE__ */ k("div", {
|
|
125
128
|
className: "mb-4 flex items-center justify-between",
|
|
126
|
-
children: [/* @__PURE__ */
|
|
129
|
+
children: [/* @__PURE__ */ O("h2", {
|
|
127
130
|
className: "text-lg font-semibold text-text-primary",
|
|
128
|
-
children: "Upcoming fixtures"
|
|
129
|
-
}), /* @__PURE__ */
|
|
131
|
+
children: y("atheletebridge.pages.dashboard.upcomingFixtures", "Upcoming fixtures")
|
|
132
|
+
}), /* @__PURE__ */ k("button", {
|
|
130
133
|
type: "button",
|
|
131
|
-
onClick: () =>
|
|
132
|
-
className: "flex items-center gap-1 text-sm font-medium text-
|
|
133
|
-
children: [
|
|
134
|
+
onClick: () => E("/fixtures"),
|
|
135
|
+
className: "flex items-center gap-1 text-sm font-medium text-text-link hover:underline",
|
|
136
|
+
children: [
|
|
137
|
+
y("atheletebridge.pages.dashboard.viewAllFixtures", "View all fixtures"),
|
|
138
|
+
" ",
|
|
139
|
+
/* @__PURE__ */ O(_, { className: "h-3.5 w-3.5" })
|
|
140
|
+
]
|
|
134
141
|
})]
|
|
135
|
-
}),
|
|
142
|
+
}), W.length === 0 ? /* @__PURE__ */ O(c, {
|
|
136
143
|
illustration: "empty-calendar",
|
|
137
|
-
icon: /* @__PURE__ */
|
|
138
|
-
title: "No upcoming fixtures",
|
|
139
|
-
description: "Schedule a match to start tracking results and standings.",
|
|
140
|
-
action: /* @__PURE__ */
|
|
144
|
+
icon: /* @__PURE__ */ O(v, { className: "h-10 w-10" }),
|
|
145
|
+
title: y("atheletebridge.pages.dashboard.noFixtures", "No upcoming fixtures"),
|
|
146
|
+
description: y("atheletebridge.pages.dashboard.noFixturesHint", "Schedule a match to start tracking results and standings."),
|
|
147
|
+
action: /* @__PURE__ */ k("button", {
|
|
141
148
|
type: "button",
|
|
142
|
-
onClick: () =>
|
|
143
|
-
className:
|
|
144
|
-
children: [/* @__PURE__ */
|
|
149
|
+
onClick: () => E("/fixtures/new"),
|
|
150
|
+
className: M,
|
|
151
|
+
children: [/* @__PURE__ */ O(S, { className: "h-4 w-4" }), " Schedule fixture"]
|
|
145
152
|
})
|
|
146
|
-
}) : /* @__PURE__ */
|
|
153
|
+
}) : /* @__PURE__ */ O(A, {
|
|
147
154
|
treatment: "glass",
|
|
148
155
|
className: "divide-y divide-border-seam px-4 py-1 sm:px-5",
|
|
149
|
-
children:
|
|
156
|
+
children: W.map((e) => /* @__PURE__ */ O(o, {
|
|
150
157
|
fixture: e,
|
|
151
|
-
onClick: () =>
|
|
158
|
+
onClick: () => E(`/fixtures/${e.id}`)
|
|
152
159
|
}, e.id))
|
|
153
160
|
})]
|
|
154
|
-
}), /* @__PURE__ */
|
|
155
|
-
|
|
156
|
-
children: /* @__PURE__ */
|
|
157
|
-
className: "
|
|
158
|
-
children: "
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
161
|
+
}), /* @__PURE__ */ k("section", {
|
|
162
|
+
"data-tour": "dashboard-activity",
|
|
163
|
+
children: [/* @__PURE__ */ O("div", {
|
|
164
|
+
className: "mb-4 flex items-center min-h-[1.75rem]",
|
|
165
|
+
children: /* @__PURE__ */ O("h2", {
|
|
166
|
+
className: "text-lg font-semibold text-text-primary",
|
|
167
|
+
children: "Recent activity"
|
|
168
|
+
})
|
|
169
|
+
}), Y.length === 0 ? /* @__PURE__ */ O(A, {
|
|
170
|
+
treatment: "metric",
|
|
171
|
+
className: "p-6",
|
|
172
|
+
children: /* @__PURE__ */ O(c, {
|
|
173
|
+
illustration: "empty-data",
|
|
174
|
+
icon: /* @__PURE__ */ O(w, { className: "h-10 w-10" }),
|
|
175
|
+
title: "No recent activity",
|
|
176
|
+
description: "Create teams, publish programs or record results — the latest moves land here."
|
|
177
|
+
})
|
|
178
|
+
}) : /* @__PURE__ */ O(A, {
|
|
179
|
+
treatment: "metric",
|
|
180
|
+
className: "p-5",
|
|
181
|
+
children: /* @__PURE__ */ O(r, { items: Y })
|
|
182
|
+
})]
|
|
183
|
+
})]
|
|
174
184
|
}),
|
|
175
|
-
/* @__PURE__ */
|
|
185
|
+
/* @__PURE__ */ k("section", {
|
|
186
|
+
"data-tour": "dashboard-sessions",
|
|
176
187
|
className: "mb-8",
|
|
177
|
-
children: [/* @__PURE__ */
|
|
188
|
+
children: [/* @__PURE__ */ k("div", {
|
|
178
189
|
className: "mb-4 flex items-center justify-between",
|
|
179
|
-
children: [/* @__PURE__ */
|
|
190
|
+
children: [/* @__PURE__ */ O("h2", {
|
|
180
191
|
className: "text-lg font-semibold text-text-primary",
|
|
181
192
|
children: "Upcoming sessions"
|
|
182
|
-
}), /* @__PURE__ */
|
|
193
|
+
}), /* @__PURE__ */ k("button", {
|
|
183
194
|
type: "button",
|
|
184
|
-
onClick: () =>
|
|
185
|
-
className: "flex items-center gap-1 text-sm font-medium text-
|
|
186
|
-
children: ["View all ", /* @__PURE__ */
|
|
195
|
+
onClick: () => E("/sessions"),
|
|
196
|
+
className: "flex items-center gap-1 text-sm font-medium text-text-link hover:underline",
|
|
197
|
+
children: ["View all ", /* @__PURE__ */ O(_, { className: "h-3.5 w-3.5" })]
|
|
187
198
|
})]
|
|
188
|
-
}),
|
|
199
|
+
}), G.length === 0 ? /* @__PURE__ */ O(c, {
|
|
189
200
|
illustration: "empty-calendar",
|
|
190
|
-
icon: /* @__PURE__ */
|
|
201
|
+
icon: /* @__PURE__ */ O(b, { className: "h-10 w-10" }),
|
|
191
202
|
title: "No upcoming sessions",
|
|
192
203
|
description: "Book a coaching session with an athlete to get started.",
|
|
193
|
-
action: /* @__PURE__ */
|
|
204
|
+
action: /* @__PURE__ */ k("button", {
|
|
194
205
|
type: "button",
|
|
195
|
-
onClick: () =>
|
|
196
|
-
className:
|
|
197
|
-
children: [/* @__PURE__ */
|
|
206
|
+
onClick: () => E("/sessions/new"),
|
|
207
|
+
className: M,
|
|
208
|
+
children: [/* @__PURE__ */ O(S, { className: "h-4 w-4" }), " Book session"]
|
|
198
209
|
})
|
|
199
|
-
}) : /* @__PURE__ */
|
|
210
|
+
}) : /* @__PURE__ */ O("div", {
|
|
200
211
|
className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
201
|
-
children:
|
|
212
|
+
children: G.map((e) => /* @__PURE__ */ O(s, {
|
|
202
213
|
session: e,
|
|
203
|
-
onClick: () =>
|
|
214
|
+
onClick: () => E(`/sessions/${e.id}`)
|
|
204
215
|
}, e.id))
|
|
205
216
|
})]
|
|
206
217
|
}),
|
|
207
|
-
/* @__PURE__ */
|
|
208
|
-
|
|
209
|
-
children: [/* @__PURE__ */
|
|
210
|
-
className: "
|
|
211
|
-
children: "
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
218
|
+
/* @__PURE__ */ k("section", {
|
|
219
|
+
"data-tour": "dashboard-teams",
|
|
220
|
+
children: [/* @__PURE__ */ k("div", {
|
|
221
|
+
className: "mb-4 flex items-center justify-between",
|
|
222
|
+
children: [/* @__PURE__ */ O("h2", {
|
|
223
|
+
className: "text-lg font-semibold text-text-primary",
|
|
224
|
+
children: "Your teams"
|
|
225
|
+
}), /* @__PURE__ */ k("button", {
|
|
226
|
+
type: "button",
|
|
227
|
+
onClick: () => E("/teams"),
|
|
228
|
+
className: "flex items-center gap-1 text-sm font-medium text-text-link hover:underline",
|
|
229
|
+
children: ["View all ", /* @__PURE__ */ O(_, { className: "h-3.5 w-3.5" })]
|
|
230
|
+
})]
|
|
231
|
+
}), K.length === 0 ? /* @__PURE__ */ O(c, {
|
|
232
|
+
illustration: "empty-data",
|
|
233
|
+
icon: /* @__PURE__ */ O(T, { className: "h-10 w-10" }),
|
|
234
|
+
title: "No teams yet",
|
|
235
|
+
description: "Set up AthleteBridge in about a minute — pick your sport, create your first team and add yourself to the roster.",
|
|
236
|
+
action: /* @__PURE__ */ k("div", {
|
|
237
|
+
className: "flex flex-wrap items-center justify-center gap-2",
|
|
238
|
+
children: [/* @__PURE__ */ k("button", {
|
|
239
|
+
type: "button",
|
|
240
|
+
onClick: () => E("/onboarding"),
|
|
241
|
+
className: M,
|
|
242
|
+
children: [/* @__PURE__ */ O(C, { className: "h-4 w-4" }), " Get started"]
|
|
243
|
+
}), /* @__PURE__ */ k("button", {
|
|
244
|
+
type: "button",
|
|
245
|
+
onClick: () => E("/teams/new"),
|
|
246
|
+
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",
|
|
247
|
+
children: [/* @__PURE__ */ O(S, { className: "h-4 w-4" }), " Create team"]
|
|
248
|
+
})]
|
|
249
|
+
})
|
|
250
|
+
}) : /* @__PURE__ */ O("div", {
|
|
251
|
+
className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
252
|
+
children: K.map((e) => /* @__PURE__ */ O(a, {
|
|
253
|
+
team: e,
|
|
254
|
+
onClick: () => E(`/teams/${e.id}`)
|
|
255
|
+
}, e.id))
|
|
217
256
|
})]
|
|
218
|
-
})
|
|
219
|
-
illustration: "empty-data",
|
|
220
|
-
icon: /* @__PURE__ */ E(C, { className: "h-10 w-10" }),
|
|
221
|
-
title: "No teams yet",
|
|
222
|
-
description: "Create your first team to build a roster and schedule fixtures.",
|
|
223
|
-
action: /* @__PURE__ */ D("button", {
|
|
224
|
-
type: "button",
|
|
225
|
-
onClick: () => v("/teams/new"),
|
|
226
|
-
className: A,
|
|
227
|
-
children: [/* @__PURE__ */ E(x, { className: "h-4 w-4" }), " Create team"]
|
|
228
|
-
})
|
|
229
|
-
}) : /* @__PURE__ */ E("div", {
|
|
230
|
-
className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3",
|
|
231
|
-
children: U.map((e) => /* @__PURE__ */ E(i, {
|
|
232
|
-
team: e,
|
|
233
|
-
onClick: () => v(`/teams/${e.id}`)
|
|
234
|
-
}, e.id))
|
|
235
|
-
})] })
|
|
257
|
+
})
|
|
236
258
|
]
|
|
237
259
|
});
|
|
238
260
|
}
|
|
239
261
|
//#endregion
|
|
240
|
-
export {
|
|
262
|
+
export { P as DashboardPage };
|
|
241
263
|
|
|
242
264
|
//# sourceMappingURL=DashboardPage.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/atheletebridge/pages/DashboardPage.tsx"],"sourcesContent":["/**\n * Dashboard / Overview\n * @module atheletebridge/pages\n *\n * The AthleteBridge landing page: a coach command-center that reads live counts\n * and recent items across teams, fixtures, programs and sessions from the real\n * `ath*` API. Elevated to the concept bar: glass teal-stat KPI tiles, a\n * crest-vs-crest upcoming-fixtures rail, and a real (derived) recent-activity\n * timeline — every item mapped to a real record, nothing fabricated.\n */\n\nimport { useMemo } from 'react';\nimport {\n Users,\n CalendarDays,\n Dumbbell,\n ClipboardCheck,\n ArrowRight,\n Plus,\n Trophy,\n TrendingUp,\n UserPlus,\n CheckCircle2,\n type LucideIcon,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { TeamCard } from '../components/TeamCard';\nimport { MatchupRow } from '../components/MatchupRow';\nimport { SessionCard } from '../components/SessionCard';\nimport { EmptyState } from '../components/EmptyState';\nimport { LoadingState } from '../components/LoadingState';\nimport { Timeline, type TimelineItem, type TimelineTone } from '../components/viz';\nimport { useAthleteBridge } from '../context/AthleteBridgeContext';\nimport {\n useTeams,\n useFixtures,\n usePrograms,\n useSessions,\n useRecentActivity,\n type ActivityType,\n} from '../hooks/useAthleteBridgeApi';\nimport { timeAgo } from '../utils/timeAgo';\n\n/**\n * Brand gradient CTA — orange action-primary blended toward accent-purple, the\n * same brand gradient the hero title uses. Token-only (no raw colors).\n */\nconst GRADIENT_CTA =\n 'inline-flex items-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))]';\n\n/** Per-activity-type node styling for the recent-activity timeline. */\nconst ACTIVITY_VISUAL: Record<ActivityType, { tone: TimelineTone; Icon: LucideIcon }> = {\n 'program-published': { tone: 'success', Icon: ClipboardCheck },\n 'member-added': { tone: 'accent', Icon: UserPlus },\n 'fixture-updated': { tone: 'warning', Icon: CalendarDays },\n 'session-completed': { tone: 'info', Icon: CheckCircle2 },\n 'team-created': { tone: 'accent', Icon: Users },\n};\n\nexport function DashboardPage() {\n const { navigateTo, currentUser } = useAthleteBridge();\n\n const teams = useTeams({ pagination: { limit: 50 } });\n const fixtures = useFixtures({ pagination: { limit: 50 } });\n const programs = usePrograms({ pagination: { limit: 50 } });\n const sessions = useSessions({ pagination: { limit: 50 } });\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'coach';\n\n const teamItems = useMemo(() => teams.data?.items ?? [], [teams.data]);\n const fixtureItems = useMemo(() => fixtures.data?.items ?? [], [fixtures.data]);\n const programItems = useMemo(() => programs.data?.items ?? [], [programs.data]);\n const sessionItems = useMemo(() => sessions.data?.items ?? [], [sessions.data]);\n\n const upcomingFixtures = useMemo(\n () =>\n [...fixtureItems]\n .filter((f) => f.status === 'SCHEDULED' || f.status === 'LIVE')\n .sort((a, b) => new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime())\n .slice(0, 5),\n [fixtureItems]\n );\n\n const upcomingSessions = useMemo(\n () =>\n [...sessionItems]\n .filter((s) => s.status === 'REQUESTED' || s.status === 'CONFIRMED')\n .sort((a, b) => new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime())\n .slice(0, 3),\n [sessionItems]\n );\n\n const recentTeams = useMemo(() => teamItems.slice(0, 6), [teamItems]);\n\n const publishedPrograms = programItems.filter((p) => p.status === 'PUBLISHED').length;\n\n const activity = useRecentActivity({\n teams: teamItems,\n fixtures: fixtureItems,\n sessions: sessionItems,\n programs: programItems,\n limit: 6,\n });\n\n const activityTimeline = useMemo<TimelineItem[]>(\n () =>\n activity.map((item) => {\n const visual = ACTIVITY_VISUAL[item.type];\n const Icon = visual.Icon;\n return {\n id: item.id,\n tone: visual.tone,\n icon: <Icon className=\"h-3 w-3\" aria-hidden=\"true\" />,\n title: item.title,\n meta: item.subtitle,\n time: timeAgo(item.at),\n };\n }),\n [activity]\n );\n\n const isLoading =\n teams.isLoading || fixtures.isLoading || programs.isLoading || sessions.isLoading;\n\n if (isLoading) {\n return (\n <PageLayout title=\"AthleteBridge\" hero gradientTitle>\n <LoadingState label=\"Loading your sporting operation…\" />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`Welcome back, ${firstName}`}\n description=\"Your teams, fixtures, training and coaching — one connected record.\"\n hero\n gradientTitle\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button type=\"button\" onClick={() => navigateTo('/teams/new')} className={GRADIENT_CTA}>\n <Plus className=\"h-4 w-4\" /> New team\n </button>\n <button type=\"button\" onClick={() => navigateTo('/performance')} className={GRADIENT_CTA}>\n <TrendingUp className=\"h-4 w-4\" /> Track performance\n </button>\n </div>\n }\n >\n <PagePurpose className=\"mb-6\">\n AthleteBridge is the operating system for sports, coaching and training. From here you can\n assemble your roster, schedule fixtures, build training programs, run coaching sessions and\n track athlete performance — all reading and writing the same workspace-scoped source of\n truth.\n </PagePurpose>\n\n {/* KPIs — glass tiles with teal stat values (2-col mobile → 4-col lg) */}\n <div className=\"mb-8 grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <MetricsCard\n icon={<Users className=\"h-5 w-5\" />}\n value={teamItems.length}\n label=\"Teams\"\n tone=\"accent\"\n featured\n />\n <MetricsCard\n icon={<CalendarDays className=\"h-5 w-5\" />}\n value={fixtureItems.length}\n label=\"Fixtures\"\n tone=\"accent\"\n />\n <MetricsCard\n icon={<Dumbbell className=\"h-5 w-5\" />}\n value={`${publishedPrograms}/${programItems.length}`}\n label=\"Programs published\"\n tone=\"accent\"\n />\n <MetricsCard\n icon={<ClipboardCheck className=\"h-5 w-5\" />}\n value={sessionItems.length}\n label=\"Sessions\"\n tone=\"accent\"\n />\n </div>\n\n {/* Upcoming fixtures (matchup rail) + Recent activity (timeline) */}\n <div className=\"mb-8 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Fixtures — spans two columns on large screens */}\n <section className=\"lg:col-span-2\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Upcoming fixtures</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures')}\n className=\"flex items-center gap-1 text-sm font-medium text-primary hover:underline\"\n >\n View all fixtures <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {upcomingFixtures.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<CalendarDays className=\"h-10 w-10\" />}\n title=\"No upcoming fixtures\"\n description=\"Schedule a match to start tracking results and standings.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures/new')}\n className={GRADIENT_CTA}\n >\n <Plus className=\"h-4 w-4\" /> Schedule fixture\n </button>\n }\n />\n ) : (\n <GlassCard treatment=\"glass\" className=\"divide-y divide-border-seam px-4 py-1 sm:px-5\">\n {upcomingFixtures.map((fixture) => (\n <MatchupRow\n key={fixture.id}\n fixture={fixture}\n onClick={() => navigateTo(`/fixtures/${fixture.id}`)}\n />\n ))}\n </GlassCard>\n )}\n </section>\n\n {/* Recent activity */}\n <section>\n <div className=\"mb-4 flex items-center min-h-[1.75rem]\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent activity</h2>\n </div>\n {activityTimeline.length === 0 ? (\n <GlassCard treatment=\"metric\" className=\"p-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<TrendingUp className=\"h-10 w-10\" />}\n title=\"No recent activity\"\n description=\"Create teams, publish programs or record results — the latest moves land here.\"\n />\n </GlassCard>\n ) : (\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <Timeline items={activityTimeline} />\n </GlassCard>\n )}\n </section>\n </div>\n\n {/* Upcoming sessions */}\n <section className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Upcoming sessions</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions')}\n className=\"flex items-center gap-1 text-sm font-medium text-primary hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {upcomingSessions.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<ClipboardCheck className=\"h-10 w-10\" />}\n title=\"No upcoming sessions\"\n description=\"Book a coaching session with an athlete to get started.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions/new')}\n className={GRADIENT_CTA}\n >\n <Plus className=\"h-4 w-4\" /> Book session\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {upcomingSessions.map((session) => (\n <SessionCard\n key={session.id}\n session={session}\n onClick={() => navigateTo(`/sessions/${session.id}`)}\n />\n ))}\n </div>\n )}\n </section>\n\n {/* Teams */}\n <section>\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Your teams</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/teams')}\n className=\"flex items-center gap-1 text-sm font-medium text-primary hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {recentTeams.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Trophy className=\"h-10 w-10\" />}\n title=\"No teams yet\"\n description=\"Create your first team to build a roster and schedule fixtures.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/teams/new')}\n className={GRADIENT_CTA}\n >\n <Plus className=\"h-4 w-4\" /> Create team\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {recentTeams.map((team) => (\n <TeamCard key={team.id} team={team} onClick={() => navigateTo(`/teams/${team.id}`)} />\n ))}\n </div>\n )}\n </section>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"DashboardPage.js","names":[],"sources":["../../../src/atheletebridge/pages/DashboardPage.tsx"],"sourcesContent":["/**\n * Dashboard / Overview\n * @module atheletebridge/pages\n *\n * The AthleteBridge landing page: a coach command-center that reads live counts\n * and recent items across teams, fixtures, programs and sessions from the real\n * `ath*` API. Elevated to the concept bar: glass teal-stat KPI tiles, a\n * crest-vs-crest upcoming-fixtures rail, and a real (derived) recent-activity\n * timeline — every item mapped to a real record, nothing fabricated.\n */\n\nimport { useMemo } from 'react';\nimport {\n Users,\n CalendarDays,\n Dumbbell,\n ClipboardCheck,\n ArrowRight,\n Plus,\n Rocket,\n Trophy,\n TrendingUp,\n UserPlus,\n CheckCircle2,\n type LucideIcon,\n} from 'lucide-react';\nimport { GlassCard, PagePurpose } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../components/PageLayout';\nimport { MetricsCard } from '../components/MetricsCard';\nimport { TeamCard } from '../components/TeamCard';\nimport { MatchupRow } from '../components/MatchupRow';\nimport { SessionCard } from '../components/SessionCard';\nimport { EmptyState } from '../components/EmptyState';\nimport { LoadingState } from '../components/LoadingState';\nimport { Timeline, type TimelineItem, type TimelineTone } from '../components/viz';\nimport { useAthleteBridge } from '../context/AthleteBridgeContext';\nimport {\n useTeams,\n useFixtures,\n usePrograms,\n useSessions,\n useRecentActivity,\n type ActivityType,\n} from '../hooks/useAthleteBridgeApi';\nimport { timeAgo } from '../utils/timeAgo';\nimport { useAbTranslate } from '../i18n';\n\n/**\n * Brand gradient CTA — orange action-primary blended toward accent-purple, the\n * same brand gradient the hero title uses. Token-only (no raw colors).\n */\nconst GRADIENT_CTA =\n 'inline-flex items-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))]';\n\n/** Per-activity-type node styling for the recent-activity timeline. */\nconst ACTIVITY_VISUAL: Record<ActivityType, { tone: TimelineTone; Icon: LucideIcon }> = {\n 'program-published': { tone: 'success', Icon: ClipboardCheck },\n 'member-added': { tone: 'accent', Icon: UserPlus },\n 'fixture-updated': { tone: 'warning', Icon: CalendarDays },\n 'session-completed': { tone: 'info', Icon: CheckCircle2 },\n 'team-created': { tone: 'accent', Icon: Users },\n};\n\nexport function DashboardPage() {\n const tr = useAbTranslate();\n const { navigateTo, currentUser } = useAthleteBridge();\n\n const teams = useTeams({ pagination: { limit: 50 } });\n const fixtures = useFixtures({ pagination: { limit: 50 } });\n const programs = usePrograms({ pagination: { limit: 50 } });\n const sessions = useSessions({ pagination: { limit: 50 } });\n\n const firstName = currentUser?.firstName ?? currentUser?.name ?? 'coach';\n\n const teamItems = useMemo(() => teams.data?.items ?? [], [teams.data]);\n const fixtureItems = useMemo(() => fixtures.data?.items ?? [], [fixtures.data]);\n const programItems = useMemo(() => programs.data?.items ?? [], [programs.data]);\n const sessionItems = useMemo(() => sessions.data?.items ?? [], [sessions.data]);\n\n const upcomingFixtures = useMemo(\n () =>\n [...fixtureItems]\n .filter((f) => f.status === 'SCHEDULED' || f.status === 'LIVE')\n .sort((a, b) => new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime())\n .slice(0, 5),\n [fixtureItems]\n );\n\n const upcomingSessions = useMemo(\n () =>\n [...sessionItems]\n .filter((s) => s.status === 'REQUESTED' || s.status === 'CONFIRMED')\n .sort((a, b) => new Date(a.scheduledAt).getTime() - new Date(b.scheduledAt).getTime())\n .slice(0, 3),\n [sessionItems]\n );\n\n const recentTeams = useMemo(() => teamItems.slice(0, 6), [teamItems]);\n\n const publishedPrograms = programItems.filter((p) => p.status === 'PUBLISHED').length;\n\n const activity = useRecentActivity({\n teams: teamItems,\n fixtures: fixtureItems,\n sessions: sessionItems,\n programs: programItems,\n limit: 6,\n });\n\n const activityTimeline = useMemo<TimelineItem[]>(\n () =>\n activity.map((item) => {\n const visual = ACTIVITY_VISUAL[item.type];\n const Icon = visual.Icon;\n return {\n id: item.id,\n tone: visual.tone,\n icon: <Icon className=\"h-3 w-3\" aria-hidden=\"true\" />,\n title: item.title,\n meta: item.subtitle,\n time: timeAgo(item.at),\n };\n }),\n [activity]\n );\n\n const isLoading =\n teams.isLoading || fixtures.isLoading || programs.isLoading || sessions.isLoading;\n\n if (isLoading) {\n return (\n <PageLayout title=\"AthleteBridge\" hero gradientTitle>\n <LoadingState\n label={tr('atheletebridge.pages.dashboard.loading', 'Loading your sporting operation…')}\n />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title={`Welcome back, ${firstName}`}\n description=\"Your teams, fixtures, training and coaching — one connected record.\"\n hero\n gradientTitle\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button type=\"button\" onClick={() => navigateTo('/teams/new')} className={GRADIENT_CTA}>\n <Plus className=\"h-4 w-4\" /> New team\n </button>\n <button type=\"button\" onClick={() => navigateTo('/performance')} className={GRADIENT_CTA}>\n <TrendingUp className=\"h-4 w-4\" /> Track performance\n </button>\n </div>\n }\n >\n <PagePurpose className=\"mb-6\">\n AthleteBridge is the operating system for sports, coaching and training. From here you can\n assemble your roster, schedule fixtures, build training programs, run coaching sessions and\n track athlete performance — all reading and writing the same workspace-scoped source of\n truth.\n </PagePurpose>\n\n {/* KPIs — glass tiles with teal stat values (2-col mobile → 4-col lg) */}\n <div data-tour=\"dashboard-kpis\" className=\"mb-8 grid grid-cols-2 gap-4 lg:grid-cols-4\">\n <MetricsCard\n icon={<Users className=\"h-5 w-5\" />}\n value={teamItems.length}\n label=\"Teams\"\n tone=\"accent\"\n featured\n />\n <MetricsCard\n icon={<CalendarDays className=\"h-5 w-5\" />}\n value={fixtureItems.length}\n label=\"Fixtures\"\n tone=\"accent\"\n />\n <MetricsCard\n icon={<Dumbbell className=\"h-5 w-5\" />}\n value={`${publishedPrograms}/${programItems.length}`}\n label=\"Programs published\"\n tone=\"accent\"\n />\n <MetricsCard\n icon={<ClipboardCheck className=\"h-5 w-5\" />}\n value={sessionItems.length}\n label=\"Sessions\"\n tone=\"accent\"\n />\n </div>\n\n {/* Upcoming fixtures (matchup rail) + Recent activity (timeline) */}\n <div className=\"mb-8 grid grid-cols-1 gap-6 lg:grid-cols-3\">\n {/* Fixtures — spans two columns on large screens */}\n <section data-tour=\"dashboard-fixtures\" className=\"lg:col-span-2\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">\n {tr('atheletebridge.pages.dashboard.upcomingFixtures', 'Upcoming fixtures')}\n </h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n {tr('atheletebridge.pages.dashboard.viewAllFixtures', 'View all fixtures')}{' '}\n <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {upcomingFixtures.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<CalendarDays className=\"h-10 w-10\" />}\n title={tr('atheletebridge.pages.dashboard.noFixtures', 'No upcoming fixtures')}\n description={tr(\n 'atheletebridge.pages.dashboard.noFixturesHint',\n 'Schedule a match to start tracking results and standings.'\n )}\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures/new')}\n className={GRADIENT_CTA}\n >\n <Plus className=\"h-4 w-4\" /> Schedule fixture\n </button>\n }\n />\n ) : (\n <GlassCard treatment=\"glass\" className=\"divide-y divide-border-seam px-4 py-1 sm:px-5\">\n {upcomingFixtures.map((fixture) => (\n <MatchupRow\n key={fixture.id}\n fixture={fixture}\n onClick={() => navigateTo(`/fixtures/${fixture.id}`)}\n />\n ))}\n </GlassCard>\n )}\n </section>\n\n {/* Recent activity */}\n <section data-tour=\"dashboard-activity\">\n <div className=\"mb-4 flex items-center min-h-[1.75rem]\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Recent activity</h2>\n </div>\n {activityTimeline.length === 0 ? (\n <GlassCard treatment=\"metric\" className=\"p-6\">\n <EmptyState\n illustration=\"empty-data\"\n icon={<TrendingUp className=\"h-10 w-10\" />}\n title=\"No recent activity\"\n description=\"Create teams, publish programs or record results — the latest moves land here.\"\n />\n </GlassCard>\n ) : (\n <GlassCard treatment=\"metric\" className=\"p-5\">\n <Timeline items={activityTimeline} />\n </GlassCard>\n )}\n </section>\n </div>\n\n {/* Upcoming sessions */}\n <section data-tour=\"dashboard-sessions\" className=\"mb-8\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Upcoming sessions</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {upcomingSessions.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<ClipboardCheck className=\"h-10 w-10\" />}\n title=\"No upcoming sessions\"\n description=\"Book a coaching session with an athlete to get started.\"\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions/new')}\n className={GRADIENT_CTA}\n >\n <Plus className=\"h-4 w-4\" /> Book session\n </button>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {upcomingSessions.map((session) => (\n <SessionCard\n key={session.id}\n session={session}\n onClick={() => navigateTo(`/sessions/${session.id}`)}\n />\n ))}\n </div>\n )}\n </section>\n\n {/* Teams */}\n <section data-tour=\"dashboard-teams\">\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Your teams</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo('/teams')}\n className=\"flex items-center gap-1 text-sm font-medium text-text-link hover:underline\"\n >\n View all <ArrowRight className=\"h-3.5 w-3.5\" />\n </button>\n </div>\n {recentTeams.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Trophy className=\"h-10 w-10\" />}\n title=\"No teams yet\"\n description=\"Set up AthleteBridge in about a minute — pick your sport, create your first team and add yourself to the roster.\"\n action={\n <div className=\"flex flex-wrap items-center justify-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/onboarding')}\n className={GRADIENT_CTA}\n >\n <Rocket className=\"h-4 w-4\" /> Get started\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo('/teams/new')}\n 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\"\n >\n <Plus className=\"h-4 w-4\" /> Create team\n </button>\n </div>\n }\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {recentTeams.map((team) => (\n <TeamCard key={team.id} team={team} onClick={() => navigateTo(`/teams/${team.id}`)} />\n ))}\n </div>\n )}\n </section>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StandingsPage.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/pages/StandingsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;
|
|
1
|
+
{"version":3,"file":"StandingsPage.d.ts","sourceRoot":"","sources":["../../../src/atheletebridge/pages/StandingsPage.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH,wBAAgB,aAAa,gCAkN5B"}
|