@burdenoff/microfe-atheletebridge 2026.705.1 → 2026.706.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.
Files changed (103) hide show
  1. package/dist/atheletebridge/AthleteBridgeRoot.js +55 -39
  2. package/dist/atheletebridge/AthleteBridgeRoot.js.map +1 -1
  3. package/dist/atheletebridge/AthleteBridgeRoutes.js +18 -6
  4. package/dist/atheletebridge/AthleteBridgeRoutes.js.map +1 -1
  5. package/dist/atheletebridge/components/Crest.js +70 -0
  6. package/dist/atheletebridge/components/Crest.js.map +1 -0
  7. package/dist/atheletebridge/components/FixtureCard.js +8 -72
  8. package/dist/atheletebridge/components/FixtureCard.js.map +1 -1
  9. package/dist/atheletebridge/components/MatchupRow.js +74 -0
  10. package/dist/atheletebridge/components/MatchupRow.js.map +1 -0
  11. package/dist/atheletebridge/components/MetricsCard.js +61 -21
  12. package/dist/atheletebridge/components/MetricsCard.js.map +1 -1
  13. package/dist/atheletebridge/components/ProgramCard.js +75 -43
  14. package/dist/atheletebridge/components/ProgramCard.js.map +1 -1
  15. package/dist/atheletebridge/components/Scoreboard.js +163 -0
  16. package/dist/atheletebridge/components/Scoreboard.js.map +1 -0
  17. package/dist/atheletebridge/components/SessionCard.js +64 -41
  18. package/dist/atheletebridge/components/SessionCard.js.map +1 -1
  19. package/dist/atheletebridge/components/SessionStatusTimeline.js +80 -0
  20. package/dist/atheletebridge/components/SessionStatusTimeline.js.map +1 -0
  21. package/dist/atheletebridge/components/StatusBadge.js +5 -5
  22. package/dist/atheletebridge/components/StatusBadge.js.map +1 -1
  23. package/dist/atheletebridge/components/TeamCard.js +65 -35
  24. package/dist/atheletebridge/components/TeamCard.js.map +1 -1
  25. package/dist/atheletebridge/components/UserAvatar.js +33 -0
  26. package/dist/atheletebridge/components/UserAvatar.js.map +1 -0
  27. package/dist/atheletebridge/components/domain.js +5 -2
  28. package/dist/atheletebridge/components/domain.js.map +1 -1
  29. package/dist/atheletebridge/components/viz/AvatarStack.js +2 -0
  30. package/dist/atheletebridge/components/viz/BarChart.js +83 -0
  31. package/dist/atheletebridge/components/viz/BarChart.js.map +1 -0
  32. package/dist/atheletebridge/components/viz/DonutChart.js +109 -0
  33. package/dist/atheletebridge/components/viz/DonutChart.js.map +1 -0
  34. package/dist/atheletebridge/components/viz/LineChart.js +123 -0
  35. package/dist/atheletebridge/components/viz/LineChart.js.map +1 -0
  36. package/dist/atheletebridge/components/viz/ProgressRing.js +6 -0
  37. package/dist/atheletebridge/components/viz/ProgressRing.js.map +1 -0
  38. package/dist/atheletebridge/components/viz/RatingStars.js +92 -0
  39. package/dist/atheletebridge/components/viz/RatingStars.js.map +1 -0
  40. package/dist/atheletebridge/components/viz/Sparkline.js +74 -0
  41. package/dist/atheletebridge/components/viz/Sparkline.js.map +1 -0
  42. package/dist/atheletebridge/components/viz/StatCard.js +60 -0
  43. package/dist/atheletebridge/components/viz/StatCard.js.map +1 -0
  44. package/dist/atheletebridge/components/viz/StepProgress.js +3 -0
  45. package/dist/atheletebridge/components/viz/Timeline.js +66 -0
  46. package/dist/atheletebridge/components/viz/Timeline.js.map +1 -0
  47. package/dist/atheletebridge/components/viz/index.js +13 -0
  48. package/dist/atheletebridge/components/viz/lib/Avatar.js +1 -0
  49. package/dist/atheletebridge/components/viz/lib/CartesianFrame.js +119 -0
  50. package/dist/atheletebridge/components/viz/lib/CartesianFrame.js.map +1 -0
  51. package/dist/atheletebridge/components/viz/lib/ResponsiveSvg.js +35 -0
  52. package/dist/atheletebridge/components/viz/lib/ResponsiveSvg.js.map +1 -0
  53. package/dist/atheletebridge/components/viz/lib/format.js +17 -0
  54. package/dist/atheletebridge/components/viz/lib/format.js.map +1 -0
  55. package/dist/atheletebridge/components/viz/lib/geometry.js +61 -0
  56. package/dist/atheletebridge/components/viz/lib/geometry.js.map +1 -0
  57. package/dist/atheletebridge/components/viz/lib/hooks.js +39 -0
  58. package/dist/atheletebridge/components/viz/lib/hooks.js.map +1 -0
  59. package/dist/atheletebridge/components/viz/lib/palette.js +27 -0
  60. package/dist/atheletebridge/components/viz/lib/palette.js.map +1 -0
  61. package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +369 -163
  62. package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
  63. package/dist/atheletebridge/pages/DashboardPage.js +182 -117
  64. package/dist/atheletebridge/pages/DashboardPage.js.map +1 -1
  65. package/dist/atheletebridge/pages/StandingsPage.js +119 -95
  66. package/dist/atheletebridge/pages/StandingsPage.js.map +1 -1
  67. package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.js +372 -0
  68. package/dist/atheletebridge/pages/analytics/CoachAnalyticsPage.js.map +1 -0
  69. package/dist/atheletebridge/pages/athletes/AthleteProfilePage.js +511 -0
  70. package/dist/atheletebridge/pages/athletes/AthleteProfilePage.js.map +1 -0
  71. package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js +120 -131
  72. package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js.map +1 -1
  73. package/dist/atheletebridge/pages/fixtures/FixtureFormPage.js +264 -176
  74. package/dist/atheletebridge/pages/fixtures/FixtureFormPage.js.map +1 -1
  75. package/dist/atheletebridge/pages/fixtures/FixturesListPage.js +84 -47
  76. package/dist/atheletebridge/pages/fixtures/FixturesListPage.js.map +1 -1
  77. package/dist/atheletebridge/pages/performance/PerformancePage.js +435 -284
  78. package/dist/atheletebridge/pages/performance/PerformancePage.js.map +1 -1
  79. package/dist/atheletebridge/pages/programs/ProgramDetailPage.js +188 -124
  80. package/dist/atheletebridge/pages/programs/ProgramDetailPage.js.map +1 -1
  81. package/dist/atheletebridge/pages/programs/ProgramsListPage.js +56 -39
  82. package/dist/atheletebridge/pages/programs/ProgramsListPage.js.map +1 -1
  83. package/dist/atheletebridge/pages/sessions/SessionDetailPage.js +268 -139
  84. package/dist/atheletebridge/pages/sessions/SessionDetailPage.js.map +1 -1
  85. package/dist/atheletebridge/pages/sessions/SessionFormPage.js +254 -162
  86. package/dist/atheletebridge/pages/sessions/SessionFormPage.js.map +1 -1
  87. package/dist/atheletebridge/pages/sessions/SessionsListPage.js +38 -36
  88. package/dist/atheletebridge/pages/sessions/SessionsListPage.js.map +1 -1
  89. package/dist/atheletebridge/pages/teams/TeamDetailPage.js +437 -189
  90. package/dist/atheletebridge/pages/teams/TeamDetailPage.js.map +1 -1
  91. package/dist/atheletebridge/pages/teams/TeamFormPage.js +368 -177
  92. package/dist/atheletebridge/pages/teams/TeamFormPage.js.map +1 -1
  93. package/dist/atheletebridge/pages/teams/TeamsListPage.js +3 -0
  94. package/dist/atheletebridge/pages/teams/TeamsListPage.js.map +1 -1
  95. package/dist/atheletebridge/pages/tournaments/TournamentBracketPage.js +298 -0
  96. package/dist/atheletebridge/pages/tournaments/TournamentBracketPage.js.map +1 -0
  97. package/dist/atheletebridge/utils/identity.js +31 -0
  98. package/dist/atheletebridge/utils/identity.js.map +1 -0
  99. package/dist/atheletebridge/utils/timeAgo.js +20 -0
  100. package/dist/atheletebridge/utils/timeAgo.js.map +1 -0
  101. package/dist/atheletebridge/utils/url.js +17 -0
  102. package/dist/atheletebridge/utils/url.js.map +1 -0
  103. package/package.json +1 -1
@@ -2,74 +2,168 @@ import { useAthleteBridge as e } from "../../context/AthleteBridgeContext.js";
2
2
  import { PageLayout as t } from "../../components/PageLayout.js";
3
3
  import { StatusBadge as n } from "../../components/StatusBadge.js";
4
4
  import { MEMBER_ROLE_LABELS as r, SPORT_LABELS as i } from "../../components/domain.js";
5
- import { FixtureCard as a } from "../../components/FixtureCard.js";
6
- import { EmptyState as o } from "../../components/EmptyState.js";
7
- import { ErrorState as s, LoadingState as c } from "../../components/LoadingState.js";
8
- import { useAddMember as l, useArchiveTeam as u, useRemoveMember as d, useTeam as f } from "../../hooks/useAthleteBridgeApi.js";
9
- import { FormField as p, fieldInputClass as m } from "../../components/form.js";
10
- import { UserSearchSelect as h } from "../../components/UserSearchSelect.js";
11
- import { useState as g } from "react";
12
- import { Archive as _, ArrowLeft as v, CalendarDays as y, Edit as b, Loader2 as x, MapPin as S, Plus as C, Trash2 as w, UserPlus as T } from "lucide-react";
13
- import { useParams as E } from "react-router-dom";
14
- import { jsx as D, jsxs as O } from "react/jsx-runtime";
15
- import { EmphasisPanel as k, GlassCard as A, ResponsiveDialog as j, ResponsiveDialogContent as M, ResponsiveDialogFooter as N, ResponsiveDialogHeader as P, ResponsiveDialogTitle as F } from "@burdenoff/fe-libs/ui";
5
+ import { Crest as ee } from "../../components/Crest.js";
6
+ import { MatchupRow as te } from "../../components/MatchupRow.js";
7
+ import { UserAvatar as ne } from "../../components/UserAvatar.js";
8
+ import { EmptyState as a } from "../../components/EmptyState.js";
9
+ import { ErrorState as re, LoadingState as ie } from "../../components/LoadingState.js";
10
+ import { useAddMember as ae, useArchiveTeam as o, useRemoveMember as oe, useTeam as se } from "../../hooks/useAthleteBridgeApi.js";
11
+ import { FormField as s, fieldInputClass as c } from "../../components/form.js";
12
+ import { UserSearchSelect as l } from "../../components/UserSearchSelect.js";
13
+ import { useState as u } from "react";
14
+ import { useMutation as d, useQueryClient as f } from "@tanstack/react-query";
15
+ import { Archive as ce, ArrowLeft as p, CalendarDays as m, Check as h, Edit as le, Loader2 as g, MapPin as _, Pencil as v, Plus as y, Trash2 as b, UserPlus as x, X as S } from "lucide-react";
16
+ import { useParams as C } from "react-router-dom";
17
+ import { Fragment as w, jsx as T, jsxs as E } from "react/jsx-runtime";
18
+ import { GlassCard as D, ResponsiveDialog as ue, ResponsiveDialogContent as de, ResponsiveDialogFooter as fe, ResponsiveDialogHeader as pe, ResponsiveDialogTitle as me } from "@burdenoff/fe-libs/ui";
19
+ import { clearGraphqlFetchResponseCache as O, graphqlFetch as k } from "@burdenoff/fe-libs/shared/graphql";
16
20
  //#region src/atheletebridge/pages/teams/TeamDetailPage.tsx
17
- var I = Object.keys(r), L = [
21
+ var A = Object.keys(r), j = [
18
22
  "TRIAL",
19
23
  "ACTIVE",
20
24
  "INJURED",
21
25
  "SUSPENDED",
22
26
  "RELEASED"
23
- ], R = {
27
+ ], M = (e) => e.charAt(0) + e.slice(1).toLowerCase(), N = {
24
28
  userId: "",
25
29
  displayName: "",
26
30
  role: "PLAYER",
27
31
  status: "ACTIVE",
28
32
  position: "",
29
33
  jerseyNumber: ""
34
+ }, P = (t) => {
35
+ let n = f(), { apiGatewayUrl: r } = e();
36
+ return d({
37
+ mutationFn: async ({ id: e, input: t }) => {
38
+ let n = await k({
39
+ gateway: "workspace",
40
+ baseUrl: r,
41
+ query: "mutation AthUpdateMember($id: ID!, $input: AthUpdateMemberInput!) {\n athUpdateMember(id: $id, input: $input) {\n id teamId displayName role status position jerseyNumber\n }\n }",
42
+ variables: {
43
+ id: e,
44
+ input: t
45
+ },
46
+ workspaceToken: !0
47
+ });
48
+ if (n.errors?.length) throw Error(n.errors[0]?.message ?? "Failed to update member.");
49
+ if (O(), !n.data) throw Error("Update did not return data.");
50
+ return n.data.athUpdateMember;
51
+ },
52
+ onSuccess: () => {
53
+ n.invalidateQueries({ queryKey: [
54
+ "atheletebridge",
55
+ "team",
56
+ t
57
+ ] }), n.invalidateQueries({ queryKey: [
58
+ "atheletebridge",
59
+ "members",
60
+ t
61
+ ] });
62
+ }
63
+ });
30
64
  };
31
- function z() {
32
- let { id: z } = E(), { navigateTo: B } = e(), V = f(z), H = u(), U = l(), W = d(z), [G, K] = g(!1), [q, J] = g(R), [Y, X] = g(null);
33
- if (V.isLoading) return /* @__PURE__ */ D(t, {
65
+ function F() {
66
+ let { id: d } = C(), { navigateTo: f } = e(), O = se(d), k = o(), F = ae(), I = oe(d), L = P(d), [R, z] = u(!1), [B, V] = u(N), [H, U] = u(null), [he, W] = u(null), [G, K] = u(null), [q, J] = u(null);
67
+ if (O.isLoading) return /* @__PURE__ */ T(t, {
34
68
  title: "Team",
35
- children: /* @__PURE__ */ D(c, { label: "Loading team…" })
69
+ children: /* @__PURE__ */ T(ie, { label: "Loading team…" })
36
70
  });
37
- if (V.isError || !V.data) return /* @__PURE__ */ D(t, {
71
+ if (O.isError || !O.data) return /* @__PURE__ */ T(t, {
38
72
  title: "Team",
39
- children: /* @__PURE__ */ D(s, {
73
+ children: /* @__PURE__ */ T(re, {
40
74
  title: "Team not found",
41
75
  message: "This team does not exist or you do not have access to it.",
42
- onRetry: () => B("/teams")
76
+ onRetry: () => f("/teams")
43
77
  })
44
78
  });
45
- let Z = V.data, Q = Z.members ?? [], $ = Z.fixtures ?? [];
46
- return /* @__PURE__ */ O(t, {
47
- title: Z.name,
48
- description: `${i[Z.sport]}${Z.season ? ` · ${Z.season}` : ""}`,
49
- actions: /* @__PURE__ */ O("div", {
79
+ let Y = O.data, X = Y.members ?? [], Z = Y.fixtures ?? [], Q = [
80
+ i[Y.sport],
81
+ Y.ageGroup ?? void 0,
82
+ Y.season ?? void 0,
83
+ Y.homeVenue ?? void 0
84
+ ].filter(Boolean), ge = async () => {
85
+ d && (await k.mutateAsync(d), f("/teams"));
86
+ }, _e = (e) => {
87
+ J(null), W(e.id), K({
88
+ role: e.role,
89
+ status: e.status,
90
+ position: e.position ?? "",
91
+ jerseyNumber: e.jerseyNumber == null ? "" : String(e.jerseyNumber)
92
+ });
93
+ }, $ = () => {
94
+ W(null), K(null), J(null);
95
+ }, ve = async (e) => {
96
+ if (!G) return;
97
+ J(null);
98
+ let t = G.jerseyNumber.trim(), n;
99
+ if (t && (n = Number.parseInt(t, 10), Number.isNaN(n))) {
100
+ J("Jersey number must be a number.");
101
+ return;
102
+ }
103
+ try {
104
+ await L.mutateAsync({
105
+ id: e,
106
+ input: {
107
+ role: G.role,
108
+ status: G.status,
109
+ position: G.position.trim() || void 0,
110
+ jerseyNumber: n
111
+ }
112
+ }), $();
113
+ } catch (e) {
114
+ J(e instanceof Error ? e.message : "Failed to update member.");
115
+ }
116
+ }, ye = async (e) => {
117
+ if (e.preventDefault(), U(null), !d) return;
118
+ if (!B.userId.trim() || !B.displayName.trim()) {
119
+ U("User ID and display name are required.");
120
+ return;
121
+ }
122
+ let t = B.jerseyNumber.trim() ? Number.parseInt(B.jerseyNumber, 10) : void 0;
123
+ if (t !== void 0 && Number.isNaN(t)) {
124
+ U("Jersey number must be a number.");
125
+ return;
126
+ }
127
+ try {
128
+ await F.mutateAsync({
129
+ teamId: d,
130
+ userId: B.userId.trim(),
131
+ displayName: B.displayName.trim(),
132
+ role: B.role,
133
+ status: B.status,
134
+ position: B.position.trim() || void 0,
135
+ jerseyNumber: t
136
+ }), V(N), z(!1);
137
+ } catch (e) {
138
+ U(e instanceof Error ? e.message : "Failed to add member.");
139
+ }
140
+ }, be = (e) => f(`/teams/${Y.id}/athletes/${e}`);
141
+ return /* @__PURE__ */ E(t, {
142
+ title: Y.name,
143
+ gradientTitle: !0,
144
+ description: Q.join(" · "),
145
+ actions: /* @__PURE__ */ E("div", {
50
146
  className: "flex flex-wrap items-center gap-2",
51
147
  children: [
52
- /* @__PURE__ */ O("button", {
148
+ /* @__PURE__ */ E("button", {
53
149
  type: "button",
54
- onClick: () => B("/teams"),
150
+ onClick: () => f("/teams"),
55
151
  className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
56
- children: [/* @__PURE__ */ D(v, { className: "h-4 w-4" }), " Back"]
152
+ children: [/* @__PURE__ */ T(p, { className: "h-4 w-4" }), " Back"]
57
153
  }),
58
- /* @__PURE__ */ O("button", {
154
+ /* @__PURE__ */ E("button", {
59
155
  type: "button",
60
- onClick: () => B(`/teams/${Z.id}/edit`),
61
- className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
62
- children: [/* @__PURE__ */ D(b, { className: "h-4 w-4" }), " Edit"]
156
+ onClick: () => f(`/teams/${Y.id}/edit`),
157
+ className: "inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90",
158
+ children: [/* @__PURE__ */ T(le, { className: "h-4 w-4" }), " Edit"]
63
159
  }),
64
- Z.status !== "ARCHIVED" && /* @__PURE__ */ O("button", {
160
+ Y.status !== "ARCHIVED" && /* @__PURE__ */ E("button", {
65
161
  type: "button",
66
- onClick: async () => {
67
- z && (await H.mutateAsync(z), B("/teams"));
68
- },
69
- disabled: H.isPending,
162
+ onClick: ge,
163
+ disabled: k.isPending,
70
164
  className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-2 text-sm font-medium text-status-error-text transition-colors hover:bg-status-error-bg-subtle disabled:opacity-60",
71
165
  children: [
72
- H.isPending ? /* @__PURE__ */ D(x, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ D(_, { className: "h-4 w-4" }),
166
+ k.isPending ? /* @__PURE__ */ T(g, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ T(ce, { className: "h-4 w-4" }),
73
167
  " ",
74
168
  "Archive"
75
169
  ]
@@ -77,240 +171,394 @@ function z() {
77
171
  ]
78
172
  }),
79
173
  children: [
80
- /* @__PURE__ */ O(A, {
174
+ /* @__PURE__ */ E(D, {
81
175
  treatment: "insight",
82
176
  className: "mb-8 p-6",
83
177
  children: [
84
- /* @__PURE__ */ O("div", {
85
- className: "flex flex-wrap items-center gap-3",
86
- children: [
87
- /* @__PURE__ */ D(n, { status: Z.status }),
88
- Z.ageGroup && /* @__PURE__ */ O("span", {
89
- className: "text-sm text-text-secondary",
90
- children: ["Age group: ", Z.ageGroup]
91
- }),
92
- Z.homeVenue && /* @__PURE__ */ O("span", {
93
- className: "flex items-center gap-1 text-sm text-text-secondary",
94
- children: [
95
- /* @__PURE__ */ D(S, { className: "h-3.5 w-3.5" }),
96
- " ",
97
- Z.homeVenue
98
- ]
99
- })
100
- ]
178
+ /* @__PURE__ */ E("div", {
179
+ className: "flex flex-col gap-4 sm:flex-row sm:items-center",
180
+ children: [/* @__PURE__ */ T(ee, {
181
+ name: Y.name,
182
+ sport: Y.sport,
183
+ size: 64
184
+ }), /* @__PURE__ */ E("div", {
185
+ className: "min-w-0 flex-1",
186
+ children: [/* @__PURE__ */ E("div", {
187
+ className: "flex flex-wrap items-center gap-3",
188
+ children: [/* @__PURE__ */ T("h2", {
189
+ className: "text-xl font-semibold text-text-primary",
190
+ children: Y.name
191
+ }), /* @__PURE__ */ T(n, { status: Y.status })]
192
+ }), /* @__PURE__ */ T("div", {
193
+ className: "mt-1.5 flex flex-wrap items-center gap-x-2 gap-y-1 text-sm text-text-secondary",
194
+ children: Q.map((e, t) => /* @__PURE__ */ E("span", {
195
+ className: "flex items-center gap-2",
196
+ children: [t > 0 && /* @__PURE__ */ T("span", {
197
+ "aria-hidden": "true",
198
+ className: "text-text-muted",
199
+ children: "·"
200
+ }), e === Y.homeVenue ? /* @__PURE__ */ E("span", {
201
+ className: "flex items-center gap-1",
202
+ children: [
203
+ /* @__PURE__ */ T(_, {
204
+ className: "h-3.5 w-3.5",
205
+ "aria-hidden": "true"
206
+ }),
207
+ " ",
208
+ e
209
+ ]
210
+ }) : e]
211
+ }, e))
212
+ })]
213
+ })]
101
214
  }),
102
- Z.description && /* @__PURE__ */ D("p", {
215
+ Y.description && /* @__PURE__ */ T("p", {
103
216
  className: "mt-4 text-sm text-text-secondary",
104
- children: Z.description
217
+ children: Y.description
105
218
  }),
106
- Z.tags.length > 0 && /* @__PURE__ */ D("div", {
219
+ Y.tags.length > 0 && /* @__PURE__ */ T("div", {
107
220
  className: "mt-4 flex flex-wrap gap-1.5",
108
- children: Z.tags.map((e) => /* @__PURE__ */ D("span", {
221
+ children: Y.tags.map((e) => /* @__PURE__ */ T("span", {
109
222
  className: "inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary",
110
223
  children: e
111
224
  }, e))
112
225
  })
113
226
  ]
114
227
  }),
115
- /* @__PURE__ */ O("section", {
228
+ /* @__PURE__ */ E("section", {
116
229
  className: "mb-8",
117
- children: [/* @__PURE__ */ O("div", {
230
+ children: [/* @__PURE__ */ E("div", {
118
231
  className: "mb-4 flex items-center justify-between",
119
- children: [/* @__PURE__ */ O("h2", {
232
+ children: [/* @__PURE__ */ E("h2", {
120
233
  className: "text-lg font-semibold text-text-primary",
121
234
  children: [
122
235
  "Roster (",
123
- Q.length,
236
+ X.length,
124
237
  ")"
125
238
  ]
126
- }), /* @__PURE__ */ O("button", {
239
+ }), /* @__PURE__ */ E("button", {
127
240
  type: "button",
128
241
  onClick: () => {
129
- X(null), K(!0);
242
+ U(null), z(!0);
130
243
  },
131
- className: "inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-1.5 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90",
132
- children: [/* @__PURE__ */ D(T, { className: "h-4 w-4" }), " Add member"]
244
+ className: "inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-3 py-1.5 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90",
245
+ children: [/* @__PURE__ */ T(x, { className: "h-4 w-4" }), " Add member"]
133
246
  })]
134
- }), Q.length === 0 ? /* @__PURE__ */ D(o, {
247
+ }), X.length === 0 ? /* @__PURE__ */ T(a, {
135
248
  illustration: "empty-data",
136
- icon: /* @__PURE__ */ D(T, { className: "h-10 w-10" }),
249
+ icon: /* @__PURE__ */ T(x, { className: "h-10 w-10" }),
137
250
  title: "No members yet",
138
251
  description: "Add players, coaches and staff to build the roster."
139
- }) : /* @__PURE__ */ D(k, { children: /* @__PURE__ */ D("div", {
140
- className: "divide-y divide-border-seam",
141
- children: Q.map((e) => /* @__PURE__ */ O("div", {
142
- className: "flex items-center gap-4 py-3",
143
- children: [
144
- /* @__PURE__ */ D("div", {
145
- className: "flex h-9 w-9 shrink-0 items-center justify-center rounded-full bg-bg-sunken text-sm font-semibold tabular-nums text-text-primary",
146
- children: e.jerseyNumber ?? e.displayName.charAt(0).toUpperCase()
147
- }),
148
- /* @__PURE__ */ O("div", {
149
- className: "min-w-0 flex-1",
150
- children: [/* @__PURE__ */ D("p", {
151
- className: "truncate text-sm font-medium text-text-primary",
152
- children: e.displayName
153
- }), /* @__PURE__ */ O("p", {
154
- className: "text-xs text-text-secondary",
155
- children: [r[e.role], e.position ? ` · ${e.position}` : ""]
156
- })]
157
- }),
158
- /* @__PURE__ */ D(n, { status: e.status }),
159
- /* @__PURE__ */ D("button", {
160
- type: "button",
161
- onClick: () => void W.mutate(e.id),
162
- disabled: W.isPending,
163
- "aria-label": `Remove ${e.displayName}`,
164
- className: "rounded-lg p-2 text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text disabled:opacity-60",
165
- children: /* @__PURE__ */ D(w, { className: "h-4 w-4" })
166
- })
167
- ]
168
- }, e.id))
169
- }) })]
252
+ }) : /* @__PURE__ */ E(D, {
253
+ treatment: "insight",
254
+ className: "overflow-hidden p-0",
255
+ children: [/* @__PURE__ */ T("div", {
256
+ className: "overflow-x-auto",
257
+ children: /* @__PURE__ */ E("table", {
258
+ className: "w-full min-w-[720px] border-collapse text-sm",
259
+ children: [/* @__PURE__ */ T("thead", { children: /* @__PURE__ */ E("tr", {
260
+ className: "border-b border-border-seam text-left text-xs uppercase tracking-wide text-text-secondary",
261
+ children: [
262
+ /* @__PURE__ */ T("th", {
263
+ className: "px-4 py-3 font-medium",
264
+ children: "Player"
265
+ }),
266
+ /* @__PURE__ */ T("th", {
267
+ className: "px-4 py-3 font-medium",
268
+ children: "Role"
269
+ }),
270
+ /* @__PURE__ */ T("th", {
271
+ className: "px-4 py-3 font-medium",
272
+ children: "Position"
273
+ }),
274
+ /* @__PURE__ */ T("th", {
275
+ className: "px-4 py-3 font-medium",
276
+ children: "Jersey #"
277
+ }),
278
+ /* @__PURE__ */ T("th", {
279
+ className: "px-4 py-3 font-medium",
280
+ children: "Status"
281
+ }),
282
+ /* @__PURE__ */ T("th", {
283
+ className: "px-4 py-3 text-right font-medium",
284
+ children: "Actions"
285
+ })
286
+ ]
287
+ }) }), /* @__PURE__ */ T("tbody", {
288
+ className: "divide-y divide-border-seam",
289
+ children: X.map((e) => {
290
+ let t = he === e.id, i = L.isPending && t;
291
+ return /* @__PURE__ */ E("tr", {
292
+ className: "align-middle transition-colors hover:bg-bg-sunken/60",
293
+ children: [
294
+ /* @__PURE__ */ T("td", {
295
+ className: "px-4 py-3",
296
+ children: /* @__PURE__ */ E("button", {
297
+ type: "button",
298
+ onClick: () => be(e.id),
299
+ className: "group flex items-center gap-3 text-left focus-visible:outline-none",
300
+ title: `View ${e.displayName}'s profile`,
301
+ children: [/* @__PURE__ */ T(ne, {
302
+ name: e.displayName,
303
+ id: e.userId,
304
+ jersey: e.jerseyNumber,
305
+ size: "sm"
306
+ }), /* @__PURE__ */ E("span", {
307
+ className: "min-w-0",
308
+ children: [/* @__PURE__ */ T("span", {
309
+ className: "block truncate font-medium text-text-primary group-hover:text-text-link",
310
+ children: e.displayName
311
+ }), /* @__PURE__ */ T("span", {
312
+ className: "block truncate text-xs text-text-secondary group-hover:text-text-link",
313
+ children: "View profile"
314
+ })]
315
+ })]
316
+ })
317
+ }),
318
+ /* @__PURE__ */ T("td", {
319
+ className: "px-4 py-3",
320
+ children: t && G ? /* @__PURE__ */ T("select", {
321
+ "aria-label": "Role",
322
+ className: c,
323
+ value: G.role,
324
+ onChange: (e) => K((t) => t && {
325
+ ...t,
326
+ role: e.target.value
327
+ }),
328
+ children: A.map((e) => /* @__PURE__ */ T("option", {
329
+ value: e,
330
+ children: r[e]
331
+ }, e))
332
+ }) : /* @__PURE__ */ T("span", {
333
+ className: "text-text-secondary",
334
+ children: r[e.role]
335
+ })
336
+ }),
337
+ /* @__PURE__ */ T("td", {
338
+ className: "px-4 py-3",
339
+ children: t && G ? /* @__PURE__ */ T("input", {
340
+ "aria-label": "Position",
341
+ className: c,
342
+ value: G.position,
343
+ onChange: (e) => K((t) => t && {
344
+ ...t,
345
+ position: e.target.value
346
+ }),
347
+ placeholder: "e.g. Striker"
348
+ }) : /* @__PURE__ */ T("span", {
349
+ className: "text-text-secondary",
350
+ children: e.position || "—"
351
+ })
352
+ }),
353
+ /* @__PURE__ */ T("td", {
354
+ className: "px-4 py-3",
355
+ children: t && G ? /* @__PURE__ */ T("input", {
356
+ "aria-label": "Jersey number",
357
+ inputMode: "numeric",
358
+ className: `${c} w-20`,
359
+ value: G.jerseyNumber,
360
+ onChange: (e) => K((t) => t && {
361
+ ...t,
362
+ jerseyNumber: e.target.value
363
+ }),
364
+ placeholder: "9"
365
+ }) : /* @__PURE__ */ T("span", {
366
+ className: "tabular-nums text-text-primary",
367
+ children: e.jerseyNumber ?? "—"
368
+ })
369
+ }),
370
+ /* @__PURE__ */ T("td", {
371
+ className: "px-4 py-3",
372
+ children: t && G ? /* @__PURE__ */ T("select", {
373
+ "aria-label": "Status",
374
+ className: c,
375
+ value: G.status,
376
+ onChange: (e) => K((t) => t && {
377
+ ...t,
378
+ status: e.target.value
379
+ }),
380
+ children: j.map((e) => /* @__PURE__ */ T("option", {
381
+ value: e,
382
+ children: M(e)
383
+ }, e))
384
+ }) : /* @__PURE__ */ T(n, { status: e.status })
385
+ }),
386
+ /* @__PURE__ */ T("td", {
387
+ className: "px-4 py-3",
388
+ children: /* @__PURE__ */ T("div", {
389
+ className: "flex items-center justify-end gap-1",
390
+ children: t ? /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ T("button", {
391
+ type: "button",
392
+ onClick: () => void ve(e.id),
393
+ disabled: i,
394
+ "aria-label": "Save changes",
395
+ className: "rounded-lg p-2 text-status-success-text transition-colors hover:bg-status-success-bg-subtle disabled:opacity-60",
396
+ children: i ? /* @__PURE__ */ T(g, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ T(h, { className: "h-4 w-4" })
397
+ }), /* @__PURE__ */ T("button", {
398
+ type: "button",
399
+ onClick: $,
400
+ disabled: i,
401
+ "aria-label": "Cancel editing",
402
+ className: "rounded-lg p-2 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary disabled:opacity-60",
403
+ children: /* @__PURE__ */ T(S, { className: "h-4 w-4" })
404
+ })] }) : /* @__PURE__ */ E(w, { children: [/* @__PURE__ */ T("button", {
405
+ type: "button",
406
+ onClick: () => _e(e),
407
+ "aria-label": `Edit ${e.displayName}`,
408
+ className: "rounded-lg p-2 text-text-secondary transition-colors hover:bg-bg-sunken hover:text-text-primary",
409
+ children: /* @__PURE__ */ T(v, { className: "h-4 w-4" })
410
+ }), /* @__PURE__ */ T("button", {
411
+ type: "button",
412
+ onClick: () => void I.mutate(e.id),
413
+ disabled: I.isPending,
414
+ "aria-label": `Remove ${e.displayName}`,
415
+ className: "rounded-lg p-2 text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text disabled:opacity-60",
416
+ children: /* @__PURE__ */ T(b, { className: "h-4 w-4" })
417
+ })] })
418
+ })
419
+ })
420
+ ]
421
+ }, e.id);
422
+ })
423
+ })]
424
+ })
425
+ }), q && /* @__PURE__ */ T("p", {
426
+ className: "border-t border-border-seam px-4 py-2 text-sm text-status-error-text",
427
+ children: q
428
+ })]
429
+ })]
170
430
  }),
171
- /* @__PURE__ */ O("section", { children: [/* @__PURE__ */ O("div", {
431
+ /* @__PURE__ */ E("section", { children: [/* @__PURE__ */ E("div", {
172
432
  className: "mb-4 flex items-center justify-between",
173
- children: [/* @__PURE__ */ O("h2", {
433
+ children: [/* @__PURE__ */ E("h2", {
174
434
  className: "text-lg font-semibold text-text-primary",
175
435
  children: [
176
436
  "Fixtures (",
177
- $.length,
437
+ Z.length,
178
438
  ")"
179
439
  ]
180
- }), /* @__PURE__ */ O("button", {
181
- type: "button",
182
- onClick: () => B(`/fixtures/new?homeTeamId=${Z.id}`),
183
- className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
184
- children: [/* @__PURE__ */ D(C, { className: "h-4 w-4" }), " Schedule"]
440
+ }), /* @__PURE__ */ E("div", {
441
+ className: "flex items-center gap-2",
442
+ children: [Z.length > 0 && /* @__PURE__ */ T("button", {
443
+ type: "button",
444
+ onClick: () => f("/fixtures"),
445
+ className: "text-sm font-medium text-text-link transition-colors hover:underline",
446
+ children: "View all"
447
+ }), /* @__PURE__ */ E("button", {
448
+ type: "button",
449
+ onClick: () => f(`/fixtures/new?homeTeamId=${Y.id}`),
450
+ className: "inline-flex items-center gap-1.5 rounded-lg border border-border-seam px-3 py-1.5 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
451
+ children: [/* @__PURE__ */ T(y, { className: "h-4 w-4" }), " Schedule"]
452
+ })]
185
453
  })]
186
- }), $.length === 0 ? /* @__PURE__ */ D(o, {
454
+ }), Z.length === 0 ? /* @__PURE__ */ T(a, {
187
455
  illustration: "empty-calendar",
188
- icon: /* @__PURE__ */ D(y, { className: "h-10 w-10" }),
456
+ icon: /* @__PURE__ */ T(m, { className: "h-10 w-10" }),
189
457
  title: "No fixtures scheduled",
190
458
  description: "Schedule a match for this team to start tracking results."
191
- }) : /* @__PURE__ */ D("div", {
192
- className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3",
193
- children: $.map((e) => /* @__PURE__ */ D(a, {
194
- fixture: e,
195
- onClick: () => B(`/fixtures/${e.id}`)
196
- }, e.id))
459
+ }) : /* @__PURE__ */ T(D, {
460
+ treatment: "insight",
461
+ className: "px-4 py-1",
462
+ children: /* @__PURE__ */ T("div", {
463
+ className: "divide-y divide-border-seam",
464
+ children: Z.map((e) => /* @__PURE__ */ T(te, {
465
+ fixture: e,
466
+ onClick: () => f(`/fixtures/${e.id}`)
467
+ }, e.id))
468
+ })
197
469
  })] }),
198
- /* @__PURE__ */ D(j, {
199
- open: G,
200
- onOpenChange: K,
201
- children: /* @__PURE__ */ O(M, { children: [/* @__PURE__ */ D(P, { children: /* @__PURE__ */ D(F, { children: "Add member" }) }), /* @__PURE__ */ O("form", {
202
- onSubmit: async (e) => {
203
- if (e.preventDefault(), X(null), !z) return;
204
- if (!q.userId.trim() || !q.displayName.trim()) {
205
- X("User ID and display name are required.");
206
- return;
207
- }
208
- let t = q.jerseyNumber.trim() ? Number.parseInt(q.jerseyNumber, 10) : void 0;
209
- if (t !== void 0 && Number.isNaN(t)) {
210
- X("Jersey number must be a number.");
211
- return;
212
- }
213
- try {
214
- await U.mutateAsync({
215
- teamId: z,
216
- userId: q.userId.trim(),
217
- displayName: q.displayName.trim(),
218
- role: q.role,
219
- status: q.status,
220
- position: q.position.trim() || void 0,
221
- jerseyNumber: t
222
- }), J(R), K(!1);
223
- } catch (e) {
224
- X(e instanceof Error ? e.message : "Failed to add member.");
225
- }
226
- },
470
+ /* @__PURE__ */ T(ue, {
471
+ open: R,
472
+ onOpenChange: z,
473
+ children: /* @__PURE__ */ E(de, { children: [/* @__PURE__ */ T(pe, { children: /* @__PURE__ */ T(me, { children: "Add member" }) }), /* @__PURE__ */ E("form", {
474
+ onSubmit: ye,
227
475
  className: "space-y-4 px-1",
228
476
  children: [
229
- /* @__PURE__ */ D(h, {
230
- userId: q.userId,
231
- displayName: q.displayName,
232
- onSelect: ({ userId: e, displayName: t }) => J((n) => ({
477
+ /* @__PURE__ */ T(l, {
478
+ userId: B.userId,
479
+ displayName: B.displayName,
480
+ onSelect: ({ userId: e, displayName: t }) => V((n) => ({
233
481
  ...n,
234
482
  userId: e,
235
483
  displayName: t || n.displayName
236
484
  })),
237
485
  required: !0
238
486
  }),
239
- /* @__PURE__ */ D(p, {
487
+ /* @__PURE__ */ T(s, {
240
488
  label: "Display name",
241
489
  htmlFor: "displayName",
242
490
  required: !0,
243
- children: /* @__PURE__ */ D("input", {
491
+ children: /* @__PURE__ */ T("input", {
244
492
  id: "displayName",
245
- className: m,
246
- value: q.displayName,
247
- onChange: (e) => J((t) => ({
493
+ className: c,
494
+ value: B.displayName,
495
+ onChange: (e) => V((t) => ({
248
496
  ...t,
249
497
  displayName: e.target.value
250
498
  })),
251
499
  placeholder: "e.g. Alex Morgan"
252
500
  })
253
501
  }),
254
- /* @__PURE__ */ O("div", {
502
+ /* @__PURE__ */ E("div", {
255
503
  className: "grid grid-cols-2 gap-4",
256
- children: [/* @__PURE__ */ D(p, {
504
+ children: [/* @__PURE__ */ T(s, {
257
505
  label: "Role",
258
506
  htmlFor: "role",
259
- children: /* @__PURE__ */ D("select", {
507
+ children: /* @__PURE__ */ T("select", {
260
508
  id: "role",
261
- className: m,
262
- value: q.role,
263
- onChange: (e) => J((t) => ({
509
+ className: c,
510
+ value: B.role,
511
+ onChange: (e) => V((t) => ({
264
512
  ...t,
265
513
  role: e.target.value
266
514
  })),
267
- children: I.map((e) => /* @__PURE__ */ D("option", {
515
+ children: A.map((e) => /* @__PURE__ */ T("option", {
268
516
  value: e,
269
517
  children: r[e]
270
518
  }, e))
271
519
  })
272
- }), /* @__PURE__ */ D(p, {
520
+ }), /* @__PURE__ */ T(s, {
273
521
  label: "Status",
274
522
  htmlFor: "memberStatus",
275
- children: /* @__PURE__ */ D("select", {
523
+ children: /* @__PURE__ */ T("select", {
276
524
  id: "memberStatus",
277
- className: m,
278
- value: q.status,
279
- onChange: (e) => J((t) => ({
525
+ className: c,
526
+ value: B.status,
527
+ onChange: (e) => V((t) => ({
280
528
  ...t,
281
529
  status: e.target.value
282
530
  })),
283
- children: L.map((e) => /* @__PURE__ */ D("option", {
531
+ children: j.map((e) => /* @__PURE__ */ T("option", {
284
532
  value: e,
285
- children: e.charAt(0) + e.slice(1).toLowerCase()
533
+ children: M(e)
286
534
  }, e))
287
535
  })
288
536
  })]
289
537
  }),
290
- /* @__PURE__ */ O("div", {
538
+ /* @__PURE__ */ E("div", {
291
539
  className: "grid grid-cols-2 gap-4",
292
- children: [/* @__PURE__ */ D(p, {
540
+ children: [/* @__PURE__ */ T(s, {
293
541
  label: "Position",
294
542
  htmlFor: "position",
295
- children: /* @__PURE__ */ D("input", {
543
+ children: /* @__PURE__ */ T("input", {
296
544
  id: "position",
297
- className: m,
298
- value: q.position,
299
- onChange: (e) => J((t) => ({
545
+ className: c,
546
+ value: B.position,
547
+ onChange: (e) => V((t) => ({
300
548
  ...t,
301
549
  position: e.target.value
302
550
  })),
303
551
  placeholder: "e.g. Striker"
304
552
  })
305
- }), /* @__PURE__ */ D(p, {
553
+ }), /* @__PURE__ */ T(s, {
306
554
  label: "Jersey #",
307
555
  htmlFor: "jersey",
308
- children: /* @__PURE__ */ D("input", {
556
+ children: /* @__PURE__ */ T("input", {
309
557
  id: "jersey",
310
- className: m,
558
+ className: c,
311
559
  inputMode: "numeric",
312
- value: q.jerseyNumber,
313
- onChange: (e) => J((t) => ({
560
+ value: B.jerseyNumber,
561
+ onChange: (e) => V((t) => ({
314
562
  ...t,
315
563
  jerseyNumber: e.target.value
316
564
  })),
@@ -318,20 +566,20 @@ function z() {
318
566
  })
319
567
  })]
320
568
  }),
321
- Y && /* @__PURE__ */ D("p", {
569
+ H && /* @__PURE__ */ T("p", {
322
570
  className: "text-sm text-status-error-text",
323
- children: Y
571
+ children: H
324
572
  }),
325
- /* @__PURE__ */ O(N, { children: [/* @__PURE__ */ D("button", {
573
+ /* @__PURE__ */ E(fe, { children: [/* @__PURE__ */ T("button", {
326
574
  type: "button",
327
- onClick: () => K(!1),
575
+ onClick: () => z(!1),
328
576
  className: "rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
329
577
  children: "Cancel"
330
- }), /* @__PURE__ */ O("button", {
578
+ }), /* @__PURE__ */ E("button", {
331
579
  type: "submit",
332
- disabled: U.isPending,
333
- className: "inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60",
334
- children: [U.isPending && /* @__PURE__ */ D(x, { className: "h-4 w-4 animate-spin" }), "Add member"]
580
+ disabled: F.isPending,
581
+ className: "inline-flex items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 py-2 text-sm font-semibold text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60",
582
+ children: [F.isPending && /* @__PURE__ */ T(g, { className: "h-4 w-4 animate-spin" }), "Add member"]
335
583
  })] })
336
584
  ]
337
585
  })] })
@@ -340,6 +588,6 @@ function z() {
340
588
  });
341
589
  }
342
590
  //#endregion
343
- export { z as TeamDetailPage };
591
+ export { F as TeamDetailPage };
344
592
 
345
593
  //# sourceMappingURL=TeamDetailPage.js.map