@burdenoff/microfe-atheletebridge 2026.626.1 → 2026.629.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 (162) hide show
  1. package/dist/atheletebridge/AthleteBridgeRoot.js +49 -129
  2. package/dist/atheletebridge/AthleteBridgeRoot.js.map +1 -1
  3. package/dist/atheletebridge/AthleteBridgeRoutes.js +65 -184
  4. package/dist/atheletebridge/AthleteBridgeRoutes.js.map +1 -1
  5. package/dist/atheletebridge/components/CursorPager.js +34 -0
  6. package/dist/atheletebridge/components/CursorPager.js.map +1 -0
  7. package/dist/atheletebridge/components/FilterSelect.js +22 -0
  8. package/dist/atheletebridge/components/FilterSelect.js.map +1 -0
  9. package/dist/atheletebridge/components/FixtureCard.js +76 -0
  10. package/dist/atheletebridge/components/FixtureCard.js.map +1 -0
  11. package/dist/atheletebridge/components/LoadingState.js +36 -0
  12. package/dist/atheletebridge/components/LoadingState.js.map +1 -0
  13. package/dist/atheletebridge/components/ProgramCard.js +69 -0
  14. package/dist/atheletebridge/components/ProgramCard.js.map +1 -0
  15. package/dist/atheletebridge/components/SessionCard.js +76 -0
  16. package/dist/atheletebridge/components/SessionCard.js.map +1 -0
  17. package/dist/atheletebridge/components/StatusBadge.js +44 -35
  18. package/dist/atheletebridge/components/StatusBadge.js.map +1 -1
  19. package/dist/atheletebridge/components/TeamCard.js +81 -0
  20. package/dist/atheletebridge/components/TeamCard.js.map +1 -0
  21. package/dist/atheletebridge/components/domain.js +47 -0
  22. package/dist/atheletebridge/components/domain.js.map +1 -0
  23. package/dist/atheletebridge/components/form.js +29 -0
  24. package/dist/atheletebridge/components/form.js.map +1 -0
  25. package/dist/atheletebridge/context/AthleteBridgeContext.js +6 -6
  26. package/dist/atheletebridge/context/AthleteBridgeContext.js.map +1 -1
  27. package/dist/atheletebridge/hooks/useAthleteBridgeApi.js +342 -165
  28. package/dist/atheletebridge/hooks/useAthleteBridgeApi.js.map +1 -1
  29. package/dist/atheletebridge/index.js +1 -1
  30. package/dist/atheletebridge/pages/DashboardPage.js +169 -0
  31. package/dist/atheletebridge/pages/DashboardPage.js.map +1 -0
  32. package/dist/atheletebridge/pages/StandingsPage.js +166 -0
  33. package/dist/atheletebridge/pages/StandingsPage.js.map +1 -0
  34. package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js +201 -0
  35. package/dist/atheletebridge/pages/fixtures/FixtureDetailPage.js.map +1 -0
  36. package/dist/atheletebridge/pages/fixtures/FixtureFormPage.js +205 -0
  37. package/dist/atheletebridge/pages/fixtures/FixtureFormPage.js.map +1 -0
  38. package/dist/atheletebridge/pages/fixtures/FixturesListPage.js +92 -0
  39. package/dist/atheletebridge/pages/fixtures/FixturesListPage.js.map +1 -0
  40. package/dist/atheletebridge/pages/programs/ProgramDetailPage.js +374 -0
  41. package/dist/atheletebridge/pages/programs/ProgramDetailPage.js.map +1 -0
  42. package/dist/atheletebridge/pages/programs/ProgramFormPage.js +207 -0
  43. package/dist/atheletebridge/pages/programs/ProgramFormPage.js.map +1 -0
  44. package/dist/atheletebridge/pages/programs/ProgramsListPage.js +113 -0
  45. package/dist/atheletebridge/pages/programs/ProgramsListPage.js.map +1 -0
  46. package/dist/atheletebridge/pages/sessions/SessionDetailPage.js +224 -0
  47. package/dist/atheletebridge/pages/sessions/SessionDetailPage.js.map +1 -0
  48. package/dist/atheletebridge/pages/sessions/SessionFormPage.js +206 -0
  49. package/dist/atheletebridge/pages/sessions/SessionFormPage.js.map +1 -0
  50. package/dist/atheletebridge/pages/sessions/SessionsListPage.js +92 -0
  51. package/dist/atheletebridge/pages/sessions/SessionsListPage.js.map +1 -0
  52. package/dist/atheletebridge/pages/teams/TeamDetailPage.js +350 -0
  53. package/dist/atheletebridge/pages/teams/TeamDetailPage.js.map +1 -0
  54. package/dist/atheletebridge/pages/teams/TeamFormPage.js +222 -0
  55. package/dist/atheletebridge/pages/teams/TeamFormPage.js.map +1 -0
  56. package/dist/atheletebridge/pages/teams/TeamsListPage.js +101 -0
  57. package/dist/atheletebridge/pages/teams/TeamsListPage.js.map +1 -0
  58. package/dist/atheletebridge/store/atheletebridgeStore.js +2 -13
  59. package/dist/atheletebridge/store/atheletebridgeStore.js.map +1 -1
  60. package/dist/atheletebridge/utils/datetime.js +10 -0
  61. package/dist/atheletebridge/utils/datetime.js.map +1 -0
  62. package/dist/atheletebridge/utils/formatters.js +1 -4
  63. package/dist/atheletebridge/utils/formatters.js.map +1 -1
  64. package/package.json +1 -1
  65. package/dist/atheletebridge/components/InvestmentCard.js +0 -96
  66. package/dist/atheletebridge/components/InvestmentCard.js.map +0 -1
  67. package/dist/atheletebridge/components/RatingDisplay.js +0 -35
  68. package/dist/atheletebridge/components/RatingDisplay.js.map +0 -1
  69. package/dist/atheletebridge/mocks/data.js +0 -1517
  70. package/dist/atheletebridge/mocks/data.js.map +0 -1
  71. package/dist/atheletebridge/mocks/users.js +0 -34
  72. package/dist/atheletebridge/mocks/users.js.map +0 -1
  73. package/dist/atheletebridge/pages/HomePage.js +0 -936
  74. package/dist/atheletebridge/pages/HomePage.js.map +0 -1
  75. package/dist/atheletebridge/pages/admin/AdminAnalyticsPage.js +0 -653
  76. package/dist/atheletebridge/pages/admin/AdminAnalyticsPage.js.map +0 -1
  77. package/dist/atheletebridge/pages/admin/AdminDashboard.js +0 -671
  78. package/dist/atheletebridge/pages/admin/AdminDashboard.js.map +0 -1
  79. package/dist/atheletebridge/pages/admin/AdminFinancialPage.js +0 -429
  80. package/dist/atheletebridge/pages/admin/AdminFinancialPage.js.map +0 -1
  81. package/dist/atheletebridge/pages/admin/AdminOrdersPage.js +0 -667
  82. package/dist/atheletebridge/pages/admin/AdminOrdersPage.js.map +0 -1
  83. package/dist/atheletebridge/pages/admin/AdminProfilePage.js +0 -261
  84. package/dist/atheletebridge/pages/admin/AdminProfilePage.js.map +0 -1
  85. package/dist/atheletebridge/pages/admin/AdminSettingsPage.js +0 -653
  86. package/dist/atheletebridge/pages/admin/AdminSettingsPage.js.map +0 -1
  87. package/dist/atheletebridge/pages/admin/CartManagementPage.js +0 -876
  88. package/dist/atheletebridge/pages/admin/CartManagementPage.js.map +0 -1
  89. package/dist/atheletebridge/pages/admin/UserManagementPage.js +0 -900
  90. package/dist/atheletebridge/pages/admin/UserManagementPage.js.map +0 -1
  91. package/dist/atheletebridge/pages/cart-owner/AnalyticsDashboard.js +0 -839
  92. package/dist/atheletebridge/pages/cart-owner/AnalyticsDashboard.js.map +0 -1
  93. package/dist/atheletebridge/pages/cart-owner/BusinessSettingsPage.js +0 -704
  94. package/dist/atheletebridge/pages/cart-owner/BusinessSettingsPage.js.map +0 -1
  95. package/dist/atheletebridge/pages/cart-owner/CartOwnerDashboard.js +0 -792
  96. package/dist/atheletebridge/pages/cart-owner/CartOwnerDashboard.js.map +0 -1
  97. package/dist/atheletebridge/pages/cart-owner/CartOwnerProfilePage.js +0 -891
  98. package/dist/atheletebridge/pages/cart-owner/CartOwnerProfilePage.js.map +0 -1
  99. package/dist/atheletebridge/pages/cart-owner/CartServiceConfigPage.js +0 -633
  100. package/dist/atheletebridge/pages/cart-owner/CartServiceConfigPage.js.map +0 -1
  101. package/dist/atheletebridge/pages/cart-owner/InventoryManagementPage.js +0 -913
  102. package/dist/atheletebridge/pages/cart-owner/InventoryManagementPage.js.map +0 -1
  103. package/dist/atheletebridge/pages/cart-owner/OrderManagementPage.js +0 -881
  104. package/dist/atheletebridge/pages/cart-owner/OrderManagementPage.js.map +0 -1
  105. package/dist/atheletebridge/pages/cart-owner/StaffManagementPage.js +0 -841
  106. package/dist/atheletebridge/pages/cart-owner/StaffManagementPage.js.map +0 -1
  107. package/dist/atheletebridge/pages/common/HelpSupportPage.js +0 -1319
  108. package/dist/atheletebridge/pages/common/HelpSupportPage.js.map +0 -1
  109. package/dist/atheletebridge/pages/common/NotificationCenterPage.js +0 -674
  110. package/dist/atheletebridge/pages/common/NotificationCenterPage.js.map +0 -1
  111. package/dist/atheletebridge/pages/common/SettingsPage.js +0 -972
  112. package/dist/atheletebridge/pages/common/SettingsPage.js.map +0 -1
  113. package/dist/atheletebridge/pages/customer/BookingDetailsPage.js +0 -602
  114. package/dist/atheletebridge/pages/customer/BookingDetailsPage.js.map +0 -1
  115. package/dist/atheletebridge/pages/customer/CartDetailPage.js +0 -656
  116. package/dist/atheletebridge/pages/customer/CartDetailPage.js.map +0 -1
  117. package/dist/atheletebridge/pages/customer/CartDiscoveryPage.js +0 -558
  118. package/dist/atheletebridge/pages/customer/CartDiscoveryPage.js.map +0 -1
  119. package/dist/atheletebridge/pages/customer/CheckoutPage.js +0 -536
  120. package/dist/atheletebridge/pages/customer/CheckoutPage.js.map +0 -1
  121. package/dist/atheletebridge/pages/customer/CustomerDashboard.js +0 -539
  122. package/dist/atheletebridge/pages/customer/CustomerDashboard.js.map +0 -1
  123. package/dist/atheletebridge/pages/customer/CustomerProfilePage.js +0 -657
  124. package/dist/atheletebridge/pages/customer/CustomerProfilePage.js.map +0 -1
  125. package/dist/atheletebridge/pages/customer/DirectServiceBookingPage.js +0 -635
  126. package/dist/atheletebridge/pages/customer/DirectServiceBookingPage.js.map +0 -1
  127. package/dist/atheletebridge/pages/customer/FavoritesPage.js +0 -486
  128. package/dist/atheletebridge/pages/customer/FavoritesPage.js.map +0 -1
  129. package/dist/atheletebridge/pages/customer/OrderHistoryPage.js +0 -447
  130. package/dist/atheletebridge/pages/customer/OrderHistoryPage.js.map +0 -1
  131. package/dist/atheletebridge/pages/customer/OrderTrackingPage.js +0 -393
  132. package/dist/atheletebridge/pages/customer/OrderTrackingPage.js.map +0 -1
  133. package/dist/atheletebridge/pages/customer/PaymentMethodsPage.js +0 -494
  134. package/dist/atheletebridge/pages/customer/PaymentMethodsPage.js.map +0 -1
  135. package/dist/atheletebridge/pages/customer/ReviewsPage.js +0 -615
  136. package/dist/atheletebridge/pages/customer/ReviewsPage.js.map +0 -1
  137. package/dist/atheletebridge/pages/customer/SavedAddressesPage.js +0 -451
  138. package/dist/atheletebridge/pages/customer/SavedAddressesPage.js.map +0 -1
  139. package/dist/atheletebridge/pages/investor/InvestmentDetailsPage.js +0 -881
  140. package/dist/atheletebridge/pages/investor/InvestmentDetailsPage.js.map +0 -1
  141. package/dist/atheletebridge/pages/investor/InvestmentOpportunitiesPage.js +0 -945
  142. package/dist/atheletebridge/pages/investor/InvestmentOpportunitiesPage.js.map +0 -1
  143. package/dist/atheletebridge/pages/investor/InvestorAnalyticsPage.js +0 -686
  144. package/dist/atheletebridge/pages/investor/InvestorAnalyticsPage.js.map +0 -1
  145. package/dist/atheletebridge/pages/investor/InvestorDashboard.js +0 -453
  146. package/dist/atheletebridge/pages/investor/InvestorDashboard.js.map +0 -1
  147. package/dist/atheletebridge/pages/investor/InvestorInvestmentsPage.js +0 -405
  148. package/dist/atheletebridge/pages/investor/InvestorInvestmentsPage.js.map +0 -1
  149. package/dist/atheletebridge/pages/investor/InvestorPortfolioPage.js +0 -577
  150. package/dist/atheletebridge/pages/investor/InvestorPortfolioPage.js.map +0 -1
  151. package/dist/atheletebridge/pages/investor/InvestorProfilePage.js +0 -1069
  152. package/dist/atheletebridge/pages/investor/InvestorProfilePage.js.map +0 -1
  153. package/dist/atheletebridge/pages/worker/TaskDetailsPage.js +0 -530
  154. package/dist/atheletebridge/pages/worker/TaskDetailsPage.js.map +0 -1
  155. package/dist/atheletebridge/pages/worker/WorkerDashboard.js +0 -669
  156. package/dist/atheletebridge/pages/worker/WorkerDashboard.js.map +0 -1
  157. package/dist/atheletebridge/pages/worker/WorkerOrdersPage.js +0 -681
  158. package/dist/atheletebridge/pages/worker/WorkerOrdersPage.js.map +0 -1
  159. package/dist/atheletebridge/pages/worker/WorkerProfilePage.js +0 -691
  160. package/dist/atheletebridge/pages/worker/WorkerProfilePage.js.map +0 -1
  161. package/dist/atheletebridge/pages/worker/WorkerSchedulePage.js +0 -588
  162. package/dist/atheletebridge/pages/worker/WorkerSchedulePage.js.map +0 -1
@@ -0,0 +1,201 @@
1
+ import { useAthleteBridge as e } from "../../context/AthleteBridgeContext.js";
2
+ import { PageLayout as t } from "../../components/PageLayout.js";
3
+ import { StatusBadge as n } from "../../components/StatusBadge.js";
4
+ import { FIXTURE_TYPE_LABELS as r } from "../../components/domain.js";
5
+ import { formatDate as i } from "../../utils/formatters.js";
6
+ import { ErrorState as a, LoadingState as o } from "../../components/LoadingState.js";
7
+ import { useFixture as s, useRecordFixtureResult as c } from "../../hooks/useAthleteBridgeApi.js";
8
+ import { FormField as l, fieldInputClass as u } from "../../components/form.js";
9
+ import { useState as d } from "react";
10
+ import { ArrowLeft as f, CalendarClock as p, Flag as m, Loader2 as h, MapPin as g, Trophy as _ } from "lucide-react";
11
+ import { useParams as v } from "react-router-dom";
12
+ import { jsx as y, jsxs as b } from "react/jsx-runtime";
13
+ import { EmphasisPanel as x, GlassCard as S } from "@burdenoff/fe-libs/ui";
14
+ //#region src/atheletebridge/pages/fixtures/FixtureDetailPage.tsx
15
+ function C() {
16
+ let { id: C } = v(), { navigateTo: w } = e(), T = s(C), E = c(), [D, O] = d(""), [k, A] = d(""), [j, M] = d(null);
17
+ if (T.isLoading) return /* @__PURE__ */ y(t, {
18
+ title: "Fixture",
19
+ children: /* @__PURE__ */ y(o, { label: "Loading fixture…" })
20
+ });
21
+ if (T.isError || !T.data) return /* @__PURE__ */ y(t, {
22
+ title: "Fixture",
23
+ children: /* @__PURE__ */ y(a, {
24
+ title: "Fixture not found",
25
+ message: "This fixture does not exist or you do not have access to it.",
26
+ onRetry: () => w("/fixtures")
27
+ })
28
+ });
29
+ let N = T.data, P = N.homeScore !== null && N.awayScore !== null, F = N.homeTeam?.name ?? "Home", I = N.awayTeam?.name ?? (N.awayTeamId ? "Away" : "TBD"), L = !!N.awayTeamId && (N.status === "SCHEDULED" || N.status === "LIVE");
30
+ return /* @__PURE__ */ b(t, {
31
+ title: `${F} vs ${I}`,
32
+ description: `${r[N.type]}${N.competition ? ` · ${N.competition}` : ""}`,
33
+ actions: /* @__PURE__ */ b("button", {
34
+ type: "button",
35
+ onClick: () => w("/fixtures"),
36
+ 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",
37
+ children: [/* @__PURE__ */ y(f, { className: "h-4 w-4" }), " Back"]
38
+ }),
39
+ children: [
40
+ /* @__PURE__ */ b(S, {
41
+ treatment: "glass",
42
+ glow: !0,
43
+ className: "mb-8 p-8",
44
+ children: [
45
+ /* @__PURE__ */ y("div", {
46
+ className: "mb-4 flex items-center justify-center",
47
+ children: /* @__PURE__ */ y(n, { status: N.status })
48
+ }),
49
+ /* @__PURE__ */ b("div", {
50
+ className: "flex items-center justify-center gap-6",
51
+ children: [
52
+ /* @__PURE__ */ y("span", {
53
+ className: "flex-1 text-right text-lg font-semibold text-text-primary",
54
+ children: F
55
+ }),
56
+ /* @__PURE__ */ y("span", {
57
+ className: "rounded-xl bg-bg-sunken px-5 py-2 text-3xl font-bold tabular-nums text-text-primary",
58
+ children: P ? `${N.homeScore} : ${N.awayScore}` : "vs"
59
+ }),
60
+ /* @__PURE__ */ y("span", {
61
+ className: "flex-1 text-left text-lg font-semibold text-text-primary",
62
+ children: I
63
+ })
64
+ ]
65
+ }),
66
+ /* @__PURE__ */ b("div", {
67
+ className: "mt-6 flex flex-wrap items-center justify-center gap-x-6 gap-y-2 text-sm text-text-secondary",
68
+ children: [
69
+ /* @__PURE__ */ b("span", {
70
+ className: "flex items-center gap-1.5",
71
+ children: [
72
+ /* @__PURE__ */ y(p, { className: "h-4 w-4" }),
73
+ " ",
74
+ i(N.scheduledAt)
75
+ ]
76
+ }),
77
+ N.venue && /* @__PURE__ */ b("span", {
78
+ className: "flex items-center gap-1.5",
79
+ children: [
80
+ /* @__PURE__ */ y(g, { className: "h-4 w-4" }),
81
+ " ",
82
+ N.venue
83
+ ]
84
+ }),
85
+ N.round && /* @__PURE__ */ y("span", { children: N.round })
86
+ ]
87
+ })
88
+ ]
89
+ }),
90
+ N.notes && /* @__PURE__ */ b(x, {
91
+ className: "mb-8",
92
+ children: [/* @__PURE__ */ y("h2", {
93
+ className: "mb-2 text-sm font-semibold text-text-primary",
94
+ children: "Notes"
95
+ }), /* @__PURE__ */ y("p", {
96
+ className: "text-sm text-text-secondary",
97
+ children: N.notes
98
+ })]
99
+ }),
100
+ L && /* @__PURE__ */ b("section", {
101
+ className: "mb-8",
102
+ children: [/* @__PURE__ */ b("h2", {
103
+ className: "mb-4 flex items-center gap-2 text-lg font-semibold text-text-primary",
104
+ children: [/* @__PURE__ */ y(m, { className: "h-5 w-5" }), " Record result"]
105
+ }), /* @__PURE__ */ b(S, {
106
+ treatment: "insight",
107
+ className: "p-6",
108
+ children: [
109
+ /* @__PURE__ */ b("p", {
110
+ className: "mb-4 text-sm text-text-secondary",
111
+ children: [
112
+ "Recording a final score marks this fixture ",
113
+ /* @__PURE__ */ y("strong", { children: "Completed" }),
114
+ " and recomputes the competition standings for both teams."
115
+ ]
116
+ }),
117
+ /* @__PURE__ */ b("form", {
118
+ onSubmit: async (e) => {
119
+ if (e.preventDefault(), M(null), !C) return;
120
+ let t = Number.parseInt(D, 10), n = Number.parseInt(k, 10);
121
+ if (Number.isNaN(t) || Number.isNaN(n)) {
122
+ M("Both scores are required and must be numbers.");
123
+ return;
124
+ }
125
+ if (t < 0 || n < 0) {
126
+ M("Scores cannot be negative.");
127
+ return;
128
+ }
129
+ try {
130
+ await E.mutateAsync({
131
+ id: C,
132
+ input: {
133
+ homeScore: t,
134
+ awayScore: n
135
+ }
136
+ }), O(""), A("");
137
+ } catch (e) {
138
+ M(e instanceof Error ? e.message : "Failed to record result.");
139
+ }
140
+ },
141
+ className: "flex flex-wrap items-end gap-4",
142
+ children: [
143
+ /* @__PURE__ */ y(l, {
144
+ label: `${F} score`,
145
+ htmlFor: "homeScore",
146
+ className: "w-32",
147
+ children: /* @__PURE__ */ y("input", {
148
+ id: "homeScore",
149
+ inputMode: "numeric",
150
+ className: u,
151
+ value: D,
152
+ onChange: (e) => O(e.target.value),
153
+ placeholder: "0"
154
+ })
155
+ }),
156
+ /* @__PURE__ */ y(l, {
157
+ label: `${I} score`,
158
+ htmlFor: "awayScore",
159
+ className: "w-32",
160
+ children: /* @__PURE__ */ y("input", {
161
+ id: "awayScore",
162
+ inputMode: "numeric",
163
+ className: u,
164
+ value: k,
165
+ onChange: (e) => A(e.target.value),
166
+ placeholder: "0"
167
+ })
168
+ }),
169
+ /* @__PURE__ */ b("button", {
170
+ type: "submit",
171
+ disabled: E.isPending,
172
+ className: "inline-flex h-[38px] items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60",
173
+ children: [E.isPending ? /* @__PURE__ */ y(h, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ y(_, { className: "h-4 w-4" }), "Record"]
174
+ })
175
+ ]
176
+ }),
177
+ j && /* @__PURE__ */ y("p", {
178
+ className: "mt-3 text-sm text-status-error-text",
179
+ children: j
180
+ })
181
+ ]
182
+ })]
183
+ }),
184
+ N.competition && /* @__PURE__ */ b("button", {
185
+ type: "button",
186
+ onClick: () => w(`/standings?competition=${encodeURIComponent(N.competition ?? "")}`),
187
+ 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",
188
+ children: [
189
+ /* @__PURE__ */ y(_, { className: "h-4 w-4" }),
190
+ " View ",
191
+ N.competition,
192
+ " standings"
193
+ ]
194
+ })
195
+ ]
196
+ });
197
+ }
198
+ //#endregion
199
+ export { C as FixtureDetailPage };
200
+
201
+ //# sourceMappingURL=FixtureDetailPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FixtureDetailPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/fixtures/FixtureDetailPage.tsx"],"sourcesContent":["/**\n * Fixture Detail\n * @module atheletebridge/pages/fixtures\n *\n * Reads a single fixture (athFixture) and lets the user record a final result\n * (athRecordFixtureResult) which marks it COMPLETED and recomputes standings.\n */\n\nimport { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport { ArrowLeft, CalendarClock, MapPin, Trophy, Loader2, Flag } from 'lucide-react';\nimport { GlassCard, EmphasisPanel } from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { LoadingState, ErrorState } from '../../components/LoadingState';\nimport { FormField, fieldInputClass } from '../../components/form';\nimport { FIXTURE_TYPE_LABELS } from '../../components/domain';\nimport { formatDate } from '../../utils/formatters';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { useFixture, useRecordFixtureResult } from '../../hooks/useAthleteBridgeApi';\n\nexport function FixtureDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useAthleteBridge();\n\n const fixture = useFixture(id);\n const recordResult = useRecordFixtureResult();\n\n const [homeScore, setHomeScore] = useState('');\n const [awayScore, setAwayScore] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n if (fixture.isLoading) {\n return (\n <PageLayout title=\"Fixture\">\n <LoadingState label=\"Loading fixture…\" />\n </PageLayout>\n );\n }\n\n if (fixture.isError || !fixture.data) {\n return (\n <PageLayout title=\"Fixture\">\n <ErrorState\n title=\"Fixture not found\"\n message=\"This fixture does not exist or you do not have access to it.\"\n onRetry={() => navigateTo('/fixtures')}\n />\n </PageLayout>\n );\n }\n\n const f = fixture.data;\n const hasScore = f.homeScore !== null && f.awayScore !== null;\n const homeName = f.homeTeam?.name ?? 'Home';\n const awayName = f.awayTeam?.name ?? (f.awayTeamId ? 'Away' : 'TBD');\n const canRecordResult =\n Boolean(f.awayTeamId) && (f.status === 'SCHEDULED' || f.status === 'LIVE');\n\n const handleRecord = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n if (!id) return;\n const home = Number.parseInt(homeScore, 10);\n const away = Number.parseInt(awayScore, 10);\n if (Number.isNaN(home) || Number.isNaN(away)) {\n setError('Both scores are required and must be numbers.');\n return;\n }\n if (home < 0 || away < 0) {\n setError('Scores cannot be negative.');\n return;\n }\n try {\n await recordResult.mutateAsync({ id, input: { homeScore: home, awayScore: away } });\n setHomeScore('');\n setAwayScore('');\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to record result.');\n }\n };\n\n return (\n <PageLayout\n title={`${homeName} vs ${awayName}`}\n description={`${FIXTURE_TYPE_LABELS[f.type]}${f.competition ? ` · ${f.competition}` : ''}`}\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures')}\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 <ArrowLeft className=\"h-4 w-4\" /> Back\n </button>\n }\n >\n {/* Scoreboard */}\n <GlassCard treatment=\"glass\" glow className=\"mb-8 p-8\">\n <div className=\"mb-4 flex items-center justify-center\">\n <StatusBadge status={f.status} />\n </div>\n <div className=\"flex items-center justify-center gap-6\">\n <span className=\"flex-1 text-right text-lg font-semibold text-text-primary\">\n {homeName}\n </span>\n <span className=\"rounded-xl bg-bg-sunken px-5 py-2 text-3xl font-bold tabular-nums text-text-primary\">\n {hasScore ? `${f.homeScore} : ${f.awayScore}` : 'vs'}\n </span>\n <span className=\"flex-1 text-left text-lg font-semibold text-text-primary\">\n {awayName}\n </span>\n </div>\n <div className=\"mt-6 flex flex-wrap items-center justify-center gap-x-6 gap-y-2 text-sm text-text-secondary\">\n <span className=\"flex items-center gap-1.5\">\n <CalendarClock className=\"h-4 w-4\" /> {formatDate(f.scheduledAt)}\n </span>\n {f.venue && (\n <span className=\"flex items-center gap-1.5\">\n <MapPin className=\"h-4 w-4\" /> {f.venue}\n </span>\n )}\n {f.round && <span>{f.round}</span>}\n </div>\n </GlassCard>\n\n {f.notes && (\n <EmphasisPanel className=\"mb-8\">\n <h2 className=\"mb-2 text-sm font-semibold text-text-primary\">Notes</h2>\n <p className=\"text-sm text-text-secondary\">{f.notes}</p>\n </EmphasisPanel>\n )}\n\n {/* Record result */}\n {canRecordResult && (\n <section className=\"mb-8\">\n <h2 className=\"mb-4 flex items-center gap-2 text-lg font-semibold text-text-primary\">\n <Flag className=\"h-5 w-5\" /> Record result\n </h2>\n <GlassCard treatment=\"insight\" className=\"p-6\">\n <p className=\"mb-4 text-sm text-text-secondary\">\n Recording a final score marks this fixture <strong>Completed</strong> and recomputes\n the competition standings for both teams.\n </p>\n <form onSubmit={handleRecord} className=\"flex flex-wrap items-end gap-4\">\n <FormField label={`${homeName} score`} htmlFor=\"homeScore\" className=\"w-32\">\n <input\n id=\"homeScore\"\n inputMode=\"numeric\"\n className={fieldInputClass}\n value={homeScore}\n onChange={(e) => setHomeScore(e.target.value)}\n placeholder=\"0\"\n />\n </FormField>\n <FormField label={`${awayName} score`} htmlFor=\"awayScore\" className=\"w-32\">\n <input\n id=\"awayScore\"\n inputMode=\"numeric\"\n className={fieldInputClass}\n value={awayScore}\n onChange={(e) => setAwayScore(e.target.value)}\n placeholder=\"0\"\n />\n </FormField>\n <button\n type=\"submit\"\n disabled={recordResult.isPending}\n className=\"inline-flex h-[38px] items-center gap-1.5 rounded-lg bg-action-primary-bg px-4 text-sm font-medium text-action-primary-text transition-colors hover:bg-action-primary-bg/90 disabled:opacity-60\"\n >\n {recordResult.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Trophy className=\"h-4 w-4\" />\n )}\n Record\n </button>\n </form>\n {error && <p className=\"mt-3 text-sm text-status-error-text\">{error}</p>}\n </GlassCard>\n </section>\n )}\n\n {f.competition && (\n <button\n type=\"button\"\n onClick={() =>\n navigateTo(`/standings?competition=${encodeURIComponent(f.competition ?? '')}`)\n }\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 <Trophy className=\"h-4 w-4\" /> View {f.competition} standings\n </button>\n )}\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,205 @@
1
+ import { useAthleteBridge as e } from "../../context/AthleteBridgeContext.js";
2
+ import { PageLayout as t } from "../../components/PageLayout.js";
3
+ import { FIXTURE_TYPE_LABELS as n } from "../../components/domain.js";
4
+ import { LoadingState as r } from "../../components/LoadingState.js";
5
+ import { useScheduleFixture as i, useTeams as a } from "../../hooks/useAthleteBridgeApi.js";
6
+ import { FormField as o, fieldInputClass as s } from "../../components/form.js";
7
+ import { toIsoOrUndefined as c } from "../../utils/datetime.js";
8
+ import { useState as l } from "react";
9
+ import { ArrowLeft as u, Loader2 as d, Save as f } from "lucide-react";
10
+ import { useSearchParams as p } from "react-router-dom";
11
+ import { jsx as m, jsxs as h } from "react/jsx-runtime";
12
+ //#region src/atheletebridge/pages/fixtures/FixtureFormPage.tsx
13
+ var g = Object.keys(n);
14
+ function _() {
15
+ let [_] = p(), { navigateTo: v } = e(), y = a({ pagination: { limit: 100 } }), b = i(), [x, S] = l(_.get("homeTeamId") ?? ""), [C, w] = l(""), [T, E] = l("FRIENDLY"), [D, O] = l(""), [k, A] = l(""), [j, M] = l(""), [N, P] = l(""), [F, I] = l(""), [L, R] = l(""), [z, B] = l(null), V = y.data?.items ?? [];
16
+ return y.isLoading ? /* @__PURE__ */ m(t, {
17
+ title: "Schedule fixture",
18
+ children: /* @__PURE__ */ m(r, { label: "Loading teams…" })
19
+ }) : /* @__PURE__ */ m(t, {
20
+ title: "Schedule fixture",
21
+ description: "Set up a match between a home team and an optional away team.",
22
+ actions: /* @__PURE__ */ h("button", {
23
+ type: "button",
24
+ onClick: () => v("/fixtures"),
25
+ 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",
26
+ children: [/* @__PURE__ */ m(u, { className: "h-4 w-4" }), " Cancel"]
27
+ }),
28
+ children: /* @__PURE__ */ h("form", {
29
+ onSubmit: async (e) => {
30
+ if (e.preventDefault(), B(null), !x) {
31
+ B("A home team is required.");
32
+ return;
33
+ }
34
+ if (!N) {
35
+ B("A scheduled date and time is required.");
36
+ return;
37
+ }
38
+ if (C && C === x) {
39
+ B("Home and away teams must be different.");
40
+ return;
41
+ }
42
+ try {
43
+ v(`/fixtures/${(await b.mutateAsync({
44
+ homeTeamId: x,
45
+ awayTeamId: C || void 0,
46
+ type: T,
47
+ competition: D.trim() || void 0,
48
+ round: k.trim() || void 0,
49
+ venue: j.trim() || void 0,
50
+ scheduledAt: new Date(N).toISOString(),
51
+ kickoffAt: c(F),
52
+ notes: L.trim() || void 0
53
+ })).id}`);
54
+ } catch (e) {
55
+ B(e instanceof Error ? e.message : "Failed to schedule fixture.");
56
+ }
57
+ },
58
+ className: "max-w-2xl space-y-5",
59
+ children: [
60
+ /* @__PURE__ */ h("div", {
61
+ className: "grid grid-cols-1 gap-5 sm:grid-cols-2",
62
+ children: [/* @__PURE__ */ m(o, {
63
+ label: "Home team",
64
+ htmlFor: "homeTeam",
65
+ required: !0,
66
+ children: /* @__PURE__ */ h("select", {
67
+ id: "homeTeam",
68
+ className: s,
69
+ value: x,
70
+ onChange: (e) => S(e.target.value),
71
+ children: [/* @__PURE__ */ m("option", {
72
+ value: "",
73
+ children: "Select a team"
74
+ }), V.map((e) => /* @__PURE__ */ m("option", {
75
+ value: e.id,
76
+ children: e.name
77
+ }, e.id))]
78
+ })
79
+ }), /* @__PURE__ */ m(o, {
80
+ label: "Away team",
81
+ htmlFor: "awayTeam",
82
+ hint: "Optional for trials / open events.",
83
+ children: /* @__PURE__ */ h("select", {
84
+ id: "awayTeam",
85
+ className: s,
86
+ value: C,
87
+ onChange: (e) => w(e.target.value),
88
+ children: [/* @__PURE__ */ m("option", {
89
+ value: "",
90
+ children: "No away team"
91
+ }), V.map((e) => /* @__PURE__ */ m("option", {
92
+ value: e.id,
93
+ children: e.name
94
+ }, e.id))]
95
+ })
96
+ })]
97
+ }),
98
+ /* @__PURE__ */ m(o, {
99
+ label: "Type",
100
+ htmlFor: "type",
101
+ children: /* @__PURE__ */ m("select", {
102
+ id: "type",
103
+ className: s,
104
+ value: T,
105
+ onChange: (e) => E(e.target.value),
106
+ children: g.map((e) => /* @__PURE__ */ m("option", {
107
+ value: e,
108
+ children: n[e]
109
+ }, e))
110
+ })
111
+ }),
112
+ /* @__PURE__ */ h("div", {
113
+ className: "grid grid-cols-1 gap-5 sm:grid-cols-2",
114
+ children: [/* @__PURE__ */ m(o, {
115
+ label: "Competition",
116
+ htmlFor: "competition",
117
+ hint: "Used to group standings.",
118
+ children: /* @__PURE__ */ m("input", {
119
+ id: "competition",
120
+ className: s,
121
+ value: D,
122
+ onChange: (e) => O(e.target.value),
123
+ placeholder: "e.g. Spring League 2026"
124
+ })
125
+ }), /* @__PURE__ */ m(o, {
126
+ label: "Round",
127
+ htmlFor: "round",
128
+ children: /* @__PURE__ */ m("input", {
129
+ id: "round",
130
+ className: s,
131
+ value: k,
132
+ onChange: (e) => A(e.target.value),
133
+ placeholder: "e.g. Round 4"
134
+ })
135
+ })]
136
+ }),
137
+ /* @__PURE__ */ m(o, {
138
+ label: "Venue",
139
+ htmlFor: "venue",
140
+ children: /* @__PURE__ */ m("input", {
141
+ id: "venue",
142
+ className: s,
143
+ value: j,
144
+ onChange: (e) => M(e.target.value),
145
+ placeholder: "e.g. Riverside Stadium"
146
+ })
147
+ }),
148
+ /* @__PURE__ */ h("div", {
149
+ className: "grid grid-cols-1 gap-5 sm:grid-cols-2",
150
+ children: [/* @__PURE__ */ m(o, {
151
+ label: "Scheduled at",
152
+ htmlFor: "scheduledAt",
153
+ required: !0,
154
+ children: /* @__PURE__ */ m("input", {
155
+ id: "scheduledAt",
156
+ type: "datetime-local",
157
+ className: s,
158
+ value: N,
159
+ onChange: (e) => P(e.target.value)
160
+ })
161
+ }), /* @__PURE__ */ m(o, {
162
+ label: "Kick-off at",
163
+ htmlFor: "kickoffAt",
164
+ children: /* @__PURE__ */ m("input", {
165
+ id: "kickoffAt",
166
+ type: "datetime-local",
167
+ className: s,
168
+ value: F,
169
+ onChange: (e) => I(e.target.value)
170
+ })
171
+ })]
172
+ }),
173
+ /* @__PURE__ */ m(o, {
174
+ label: "Notes",
175
+ htmlFor: "notes",
176
+ children: /* @__PURE__ */ m("textarea", {
177
+ id: "notes",
178
+ className: s,
179
+ rows: 3,
180
+ value: L,
181
+ onChange: (e) => R(e.target.value),
182
+ placeholder: "Any extra context for this fixture."
183
+ })
184
+ }),
185
+ z && /* @__PURE__ */ m("p", {
186
+ className: "text-sm text-status-error-text",
187
+ children: z
188
+ }),
189
+ /* @__PURE__ */ m("div", {
190
+ className: "pt-2",
191
+ children: /* @__PURE__ */ h("button", {
192
+ type: "submit",
193
+ disabled: b.isPending,
194
+ 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",
195
+ children: [b.isPending ? /* @__PURE__ */ m(d, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ m(f, { className: "h-4 w-4" }), "Schedule fixture"]
196
+ })
197
+ })
198
+ ]
199
+ })
200
+ });
201
+ }
202
+ //#endregion
203
+ export { _ as FixtureFormPage };
204
+
205
+ //# sourceMappingURL=FixtureFormPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FixtureFormPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/fixtures/FixtureFormPage.tsx"],"sourcesContent":["/**\n * Fixture Schedule Form\n * @module atheletebridge/pages/fixtures\n */\n\nimport { useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { ArrowLeft, Loader2, Save } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { FormField, fieldInputClass } from '../../components/form';\nimport { LoadingState } from '../../components/LoadingState';\nimport { FIXTURE_TYPE_LABELS } from '../../components/domain';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { useScheduleFixture, useTeams } from '../../hooks/useAthleteBridgeApi';\nimport { toIsoOrUndefined } from '../../utils/datetime';\nimport type { AthFixtureType } from '../../types';\n\nconst TYPES = Object.keys(FIXTURE_TYPE_LABELS) as AthFixtureType[];\n\nexport function FixtureFormPage() {\n const [searchParams] = useSearchParams();\n const { navigateTo } = useAthleteBridge();\n\n const teams = useTeams({ pagination: { limit: 100 } });\n const scheduleFixture = useScheduleFixture();\n\n const [homeTeamId, setHomeTeamId] = useState(searchParams.get('homeTeamId') ?? '');\n const [awayTeamId, setAwayTeamId] = useState('');\n const [type, setType] = useState<AthFixtureType>('FRIENDLY');\n const [competition, setCompetition] = useState('');\n const [round, setRound] = useState('');\n const [venue, setVenue] = useState('');\n const [scheduledAt, setScheduledAt] = useState('');\n const [kickoffAt, setKickoffAt] = useState('');\n const [notes, setNotes] = useState('');\n const [error, setError] = useState<string | null>(null);\n\n const teamOptions = teams.data?.items ?? [];\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n\n if (!homeTeamId) {\n setError('A home team is required.');\n return;\n }\n if (!scheduledAt) {\n setError('A scheduled date and time is required.');\n return;\n }\n if (awayTeamId && awayTeamId === homeTeamId) {\n setError('Home and away teams must be different.');\n return;\n }\n\n try {\n const created = await scheduleFixture.mutateAsync({\n homeTeamId,\n awayTeamId: awayTeamId || undefined,\n type,\n competition: competition.trim() || undefined,\n round: round.trim() || undefined,\n venue: venue.trim() || undefined,\n scheduledAt: new Date(scheduledAt).toISOString(),\n kickoffAt: toIsoOrUndefined(kickoffAt),\n notes: notes.trim() || undefined,\n });\n navigateTo(`/fixtures/${created.id}`);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to schedule fixture.');\n }\n };\n\n if (teams.isLoading) {\n return (\n <PageLayout title=\"Schedule fixture\">\n <LoadingState label=\"Loading teams…\" />\n </PageLayout>\n );\n }\n\n return (\n <PageLayout\n title=\"Schedule fixture\"\n description=\"Set up a match between a home team and an optional away team.\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures')}\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 <ArrowLeft className=\"h-4 w-4\" /> Cancel\n </button>\n }\n >\n <form onSubmit={handleSubmit} className=\"max-w-2xl space-y-5\">\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n <FormField label=\"Home team\" htmlFor=\"homeTeam\" required>\n <select\n id=\"homeTeam\"\n className={fieldInputClass}\n value={homeTeamId}\n onChange={(e) => setHomeTeamId(e.target.value)}\n >\n <option value=\"\">Select a team</option>\n {teamOptions.map((tm) => (\n <option key={tm.id} value={tm.id}>\n {tm.name}\n </option>\n ))}\n </select>\n </FormField>\n\n <FormField label=\"Away team\" htmlFor=\"awayTeam\" hint=\"Optional for trials / open events.\">\n <select\n id=\"awayTeam\"\n className={fieldInputClass}\n value={awayTeamId}\n onChange={(e) => setAwayTeamId(e.target.value)}\n >\n <option value=\"\">No away team</option>\n {teamOptions.map((tm) => (\n <option key={tm.id} value={tm.id}>\n {tm.name}\n </option>\n ))}\n </select>\n </FormField>\n </div>\n\n <FormField label=\"Type\" htmlFor=\"type\">\n <select\n id=\"type\"\n className={fieldInputClass}\n value={type}\n onChange={(e) => setType(e.target.value as AthFixtureType)}\n >\n {TYPES.map((tp) => (\n <option key={tp} value={tp}>\n {FIXTURE_TYPE_LABELS[tp]}\n </option>\n ))}\n </select>\n </FormField>\n\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n <FormField label=\"Competition\" htmlFor=\"competition\" hint=\"Used to group standings.\">\n <input\n id=\"competition\"\n className={fieldInputClass}\n value={competition}\n onChange={(e) => setCompetition(e.target.value)}\n placeholder=\"e.g. Spring League 2026\"\n />\n </FormField>\n\n <FormField label=\"Round\" htmlFor=\"round\">\n <input\n id=\"round\"\n className={fieldInputClass}\n value={round}\n onChange={(e) => setRound(e.target.value)}\n placeholder=\"e.g. Round 4\"\n />\n </FormField>\n </div>\n\n <FormField label=\"Venue\" htmlFor=\"venue\">\n <input\n id=\"venue\"\n className={fieldInputClass}\n value={venue}\n onChange={(e) => setVenue(e.target.value)}\n placeholder=\"e.g. Riverside Stadium\"\n />\n </FormField>\n\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\n <FormField label=\"Scheduled at\" htmlFor=\"scheduledAt\" required>\n <input\n id=\"scheduledAt\"\n type=\"datetime-local\"\n className={fieldInputClass}\n value={scheduledAt}\n onChange={(e) => setScheduledAt(e.target.value)}\n />\n </FormField>\n\n <FormField label=\"Kick-off at\" htmlFor=\"kickoffAt\">\n <input\n id=\"kickoffAt\"\n type=\"datetime-local\"\n className={fieldInputClass}\n value={kickoffAt}\n onChange={(e) => setKickoffAt(e.target.value)}\n />\n </FormField>\n </div>\n\n <FormField label=\"Notes\" htmlFor=\"notes\">\n <textarea\n id=\"notes\"\n className={fieldInputClass}\n rows={3}\n value={notes}\n onChange={(e) => setNotes(e.target.value)}\n placeholder=\"Any extra context for this fixture.\"\n />\n </FormField>\n\n {error && <p className=\"text-sm text-status-error-text\">{error}</p>}\n\n <div className=\"pt-2\">\n <button\n type=\"submit\"\n disabled={scheduleFixture.isPending}\n 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\"\n >\n {scheduleFixture.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}\n Schedule fixture\n </button>\n </div>\n </form>\n </PageLayout>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ import { useAthleteBridge as e } from "../../context/AthleteBridgeContext.js";
2
+ import { PageLayout as t } from "../../components/PageLayout.js";
3
+ import { FixtureCard as n } from "../../components/FixtureCard.js";
4
+ import { EmptyState as r } from "../../components/EmptyState.js";
5
+ import { ErrorState as i, LoadingState as a } from "../../components/LoadingState.js";
6
+ import { useFixtures as o } from "../../hooks/useAthleteBridgeApi.js";
7
+ import { FilterSelect as s } from "../../components/FilterSelect.js";
8
+ import { CursorPager as c } from "../../components/CursorPager.js";
9
+ import { useState as l } from "react";
10
+ import { CalendarDays as u, Plus as d } from "lucide-react";
11
+ import { Fragment as f, jsx as p, jsxs as m } from "react/jsx-runtime";
12
+ //#region src/atheletebridge/pages/fixtures/FixturesListPage.tsx
13
+ var h = 12, g = [
14
+ {
15
+ value: "SCHEDULED",
16
+ label: "Scheduled"
17
+ },
18
+ {
19
+ value: "LIVE",
20
+ label: "Live"
21
+ },
22
+ {
23
+ value: "COMPLETED",
24
+ label: "Completed"
25
+ },
26
+ {
27
+ value: "POSTPONED",
28
+ label: "Postponed"
29
+ },
30
+ {
31
+ value: "CANCELLED",
32
+ label: "Cancelled"
33
+ }
34
+ ];
35
+ function _() {
36
+ let { navigateTo: _ } = e(), [v, y] = l(""), [b, x] = l(0), S = o({
37
+ status: v || void 0,
38
+ pagination: {
39
+ limit: h,
40
+ offset: b * h
41
+ }
42
+ }), C = S.data?.items ?? [], w = S.data?.pageInfo.hasMore ?? !1;
43
+ return /* @__PURE__ */ m(t, {
44
+ title: "Fixtures",
45
+ description: "Matches across friendlies, league games, cups, tournaments and scrimmages.",
46
+ actions: /* @__PURE__ */ m("button", {
47
+ type: "button",
48
+ onClick: () => _("/fixtures/new"),
49
+ 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",
50
+ children: [/* @__PURE__ */ p(d, { className: "h-4 w-4" }), " Schedule fixture"]
51
+ }),
52
+ children: [/* @__PURE__ */ p("div", {
53
+ className: "mb-6 flex flex-wrap items-center gap-3",
54
+ children: /* @__PURE__ */ p(s, {
55
+ ariaLabel: "Filter by status",
56
+ allLabel: "All statuses",
57
+ value: v,
58
+ onChange: (e) => {
59
+ y(e), x(0);
60
+ },
61
+ options: g
62
+ })
63
+ }), S.isLoading ? /* @__PURE__ */ p(a, { label: "Loading fixtures…" }) : S.isError ? /* @__PURE__ */ p(i, { onRetry: () => void S.refetch() }) : C.length === 0 ? /* @__PURE__ */ p(r, {
64
+ illustration: "empty-calendar",
65
+ icon: /* @__PURE__ */ p(u, { className: "h-10 w-10" }),
66
+ title: "No fixtures found",
67
+ description: v ? "Try clearing your filter to see all fixtures." : "Schedule a match to start tracking results and standings.",
68
+ action: /* @__PURE__ */ p("button", {
69
+ type: "button",
70
+ onClick: () => _("/fixtures/new"),
71
+ className: "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",
72
+ children: "Schedule fixture"
73
+ })
74
+ }) : /* @__PURE__ */ m(f, { children: [/* @__PURE__ */ p("div", {
75
+ className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3",
76
+ children: C.map((e) => /* @__PURE__ */ p(n, {
77
+ fixture: e,
78
+ onClick: () => _(`/fixtures/${e.id}`)
79
+ }, e.id))
80
+ }), /* @__PURE__ */ p(c, {
81
+ className: "mt-6",
82
+ page: b,
83
+ hasMore: w,
84
+ onPrev: () => x((e) => Math.max(0, e - 1)),
85
+ onNext: () => x((e) => e + 1)
86
+ })] })]
87
+ });
88
+ }
89
+ //#endregion
90
+ export { _ as FixturesListPage };
91
+
92
+ //# sourceMappingURL=FixturesListPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FixturesListPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/fixtures/FixturesListPage.tsx"],"sourcesContent":["/**\n * Fixtures List\n * @module atheletebridge/pages/fixtures\n */\n\nimport { useState } from 'react';\nimport { CalendarDays, Plus } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { FixtureCard } from '../../components/FixtureCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingState, ErrorState } from '../../components/LoadingState';\nimport { FilterSelect } from '../../components/FilterSelect';\nimport { CursorPager } from '../../components/CursorPager';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { useFixtures } from '../../hooks/useAthleteBridgeApi';\nimport type { AthFixtureStatus } from '../../types';\n\nconst PAGE_SIZE = 12;\n\nconst STATUS_OPTS: ReadonlyArray<{ value: AthFixtureStatus; label: string }> = [\n { value: 'SCHEDULED', label: 'Scheduled' },\n { value: 'LIVE', label: 'Live' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'POSTPONED', label: 'Postponed' },\n { value: 'CANCELLED', label: 'Cancelled' },\n];\n\nexport function FixturesListPage() {\n const { navigateTo } = useAthleteBridge();\n const [status, setStatus] = useState<AthFixtureStatus | ''>('');\n const [page, setPage] = useState(0);\n\n const fixtures = useFixtures({\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = fixtures.data?.items ?? [];\n const hasMore = fixtures.data?.pageInfo.hasMore ?? false;\n\n return (\n <PageLayout\n title=\"Fixtures\"\n description=\"Matches across friendlies, league games, cups, tournaments and scrimmages.\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/fixtures/new')}\n 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\"\n >\n <Plus className=\"h-4 w-4\" /> Schedule fixture\n </button>\n }\n >\n <div className=\"mb-6 flex flex-wrap items-center gap-3\">\n <FilterSelect\n ariaLabel=\"Filter by status\"\n allLabel=\"All statuses\"\n value={status}\n onChange={(v) => {\n setStatus(v);\n setPage(0);\n }}\n options={STATUS_OPTS}\n />\n </div>\n\n {fixtures.isLoading ? (\n <LoadingState label=\"Loading fixtures…\" />\n ) : fixtures.isError ? (\n <ErrorState onRetry={() => void fixtures.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<CalendarDays className=\"h-10 w-10\" />}\n title=\"No fixtures found\"\n description={\n status\n ? 'Try clearing your filter to see all fixtures.'\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=\"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\"\n >\n Schedule fixture\n </button>\n }\n />\n ) : (\n <>\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {items.map((fixture) => (\n <FixtureCard\n key={fixture.id}\n fixture={fixture}\n onClick={() => navigateTo(`/fixtures/${fixture.id}`)}\n />\n ))}\n </div>\n <CursorPager\n className=\"mt-6\"\n page={page}\n hasMore={hasMore}\n onPrev={() => setPage((p) => Math.max(0, p - 1))}\n onNext={() => setPage((p) => p + 1)}\n />\n </>\n )}\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;AAiBA,IAAM,IAAY,IAEZ,IAAyE;CAC7E;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAQ,OAAO;EAAQ;CAChC;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAa,OAAO;EAAa;CAC3C;AAED,SAAgB,IAAmB;CACjC,IAAM,EAAE,kBAAe,GAAkB,EACnC,CAAC,GAAQ,KAAa,EAAgC,GAAG,EACzD,CAAC,GAAM,KAAW,EAAS,EAAE,EAE7B,IAAW,EAAY;EAC3B,QAAQ,KAAU,KAAA;EAClB,YAAY;GAAE,OAAO;GAAW,QAAQ,IAAO;GAAW;EAC3D,CAAC,EAEI,IAAQ,EAAS,MAAM,SAAS,EAAE,EAClC,IAAU,EAAS,MAAM,SAAS,WAAW;AAEnD,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,gBAAgB;GAC1C,WAAU;aAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,oBACrB;;YAVb,CAaE,kBAAC,OAAD;GAAK,WAAU;aACb,kBAAC,GAAD;IACE,WAAU;IACV,UAAS;IACT,OAAO;IACP,WAAW,MAAM;AAEf,KADA,EAAU,EAAE,EACZ,EAAQ,EAAE;;IAEZ,SAAS;IACT,CAAA;GACE,CAAA,EAEL,EAAS,YACR,kBAAC,GAAD,EAAc,OAAM,qBAAsB,CAAA,GACxC,EAAS,UACX,kBAAC,GAAD,EAAY,eAAe,KAAK,EAAS,SAAS,EAAI,CAAA,GACpD,EAAM,WAAW,IACnB,kBAAC,GAAD;GACE,cAAa;GACb,MAAM,kBAAC,GAAD,EAAc,WAAU,aAAc,CAAA;GAC5C,OAAM;GACN,aACE,IACI,kDACA;GAEN,QACE,kBAAC,UAAD;IACE,MAAK;IACL,eAAe,EAAW,gBAAgB;IAC1C,WAAU;cACX;IAEQ,CAAA;GAEX,CAAA,GAEF,kBAAA,GAAA,EAAA,UAAA,CACE,kBAAC,OAAD;GAAK,WAAU;aACZ,EAAM,KAAK,MACV,kBAAC,GAAD;IAEW;IACT,eAAe,EAAW,aAAa,EAAQ,KAAK;IACpD,EAHK,EAAQ,GAGb,CACF;GACE,CAAA,EACN,kBAAC,GAAD;GACE,WAAU;GACJ;GACG;GACT,cAAc,GAAS,MAAM,KAAK,IAAI,GAAG,IAAI,EAAE,CAAC;GAChD,cAAc,GAAS,MAAM,IAAI,EAAE;GACnC,CAAA,CACD,EAAA,CAAA,CAEM"}