@burdenoff/microfe-atheletebridge 2026.626.1 → 2026.628.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 @@
1
+ {"version":3,"file":"SessionFormPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/sessions/SessionFormPage.tsx"],"sourcesContent":["/**\n * Book Session Form\n * @module atheletebridge/pages/sessions\n */\n\nimport { useState } from 'react';\nimport { ArrowLeft, Loader2, Save } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { FormField, fieldInputClass } from '../../components/form';\nimport { SESSION_TYPE_LABELS } from '../../components/domain';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport { useBookSession, usePrograms } from '../../hooks/useAthleteBridgeApi';\nimport type { AthSessionType } from '../../types';\n\nconst TYPES = Object.keys(SESSION_TYPE_LABELS) as AthSessionType[];\n\nexport function SessionFormPage() {\n const { navigateTo, currentUser } = useAthleteBridge();\n\n const programs = usePrograms({ status: 'PUBLISHED', pagination: { limit: 100 } });\n const bookSession = useBookSession();\n\n const [coachId, setCoachId] = useState(currentUser?.id ?? '');\n const [athleteId, setAthleteId] = useState('');\n const [programId, setProgramId] = useState('');\n const [title, setTitle] = useState('');\n const [type, setType] = useState<AthSessionType>('IN_PERSON');\n const [location, setLocation] = useState('');\n const [meetingUrl, setMeetingUrl] = useState('');\n const [scheduledAt, setScheduledAt] = useState('');\n const [durationMin, setDurationMin] = useState('60');\n const [error, setError] = useState<string | null>(null);\n\n const programOptions = programs.data?.items ?? [];\n\n const handleSubmit = async (e: React.FormEvent) => {\n e.preventDefault();\n setError(null);\n\n if (!coachId.trim()) {\n setError('Coach ID is required.');\n return;\n }\n if (!athleteId.trim()) {\n setError('Athlete ID is required.');\n return;\n }\n if (!title.trim()) {\n setError('A session title is required.');\n return;\n }\n if (!scheduledAt) {\n setError('A scheduled date and time is required.');\n return;\n }\n const duration = Number.parseInt(durationMin, 10);\n if (Number.isNaN(duration) || duration <= 0) {\n setError('Duration must be a positive number of minutes.');\n return;\n }\n\n try {\n const created = await bookSession.mutateAsync({\n coachId: coachId.trim(),\n athleteId: athleteId.trim(),\n programId: programId || undefined,\n title: title.trim(),\n type,\n location: type !== 'ONLINE' ? location.trim() || undefined : undefined,\n meetingUrl: type !== 'IN_PERSON' ? meetingUrl.trim() || undefined : undefined,\n scheduledAt: new Date(scheduledAt).toISOString(),\n durationMin: duration,\n });\n navigateTo(`/sessions/${created.id}`);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to book session.');\n }\n };\n\n return (\n <PageLayout\n title=\"Book session\"\n description=\"Schedule a coaching session between a coach and an athlete.\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions')}\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=\"Coach ID\" htmlFor=\"coachId\" required hint=\"Defaults to you.\">\n <input\n id=\"coachId\"\n className={fieldInputClass}\n value={coachId}\n onChange={(e) => setCoachId(e.target.value)}\n placeholder=\"coach-uuid\"\n />\n </FormField>\n <FormField label=\"Athlete ID\" htmlFor=\"athleteId\" required>\n <input\n id=\"athleteId\"\n className={fieldInputClass}\n value={athleteId}\n onChange={(e) => setAthleteId(e.target.value)}\n placeholder=\"athlete-uuid\"\n />\n </FormField>\n </div>\n\n <FormField label=\"Title\" htmlFor=\"title\" required>\n <input\n id=\"title\"\n className={fieldInputClass}\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n placeholder=\"e.g. Sprint technique review\"\n />\n </FormField>\n\n <div className=\"grid grid-cols-1 gap-5 sm:grid-cols-2\">\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 AthSessionType)}\n >\n {TYPES.map((tp) => (\n <option key={tp} value={tp}>\n {SESSION_TYPE_LABELS[tp]}\n </option>\n ))}\n </select>\n </FormField>\n\n <FormField label=\"Program\" htmlFor=\"program\" hint=\"Optional — tie to a published plan.\">\n <select\n id=\"program\"\n className={fieldInputClass}\n value={programId}\n onChange={(e) => setProgramId(e.target.value)}\n >\n <option value=\"\">No program</option>\n {programOptions.map((pr) => (\n <option key={pr.id} value={pr.id}>\n {pr.name}\n </option>\n ))}\n </select>\n </FormField>\n </div>\n\n {type !== 'ONLINE' && (\n <FormField label=\"Location\" htmlFor=\"location\">\n <input\n id=\"location\"\n className={fieldInputClass}\n value={location}\n onChange={(e) => setLocation(e.target.value)}\n placeholder=\"e.g. Main gym, Court 2\"\n />\n </FormField>\n )}\n\n {type !== 'IN_PERSON' && (\n <FormField label=\"Meeting URL\" htmlFor=\"meetingUrl\">\n <input\n id=\"meetingUrl\"\n className={fieldInputClass}\n value={meetingUrl}\n onChange={(e) => setMeetingUrl(e.target.value)}\n placeholder=\"https://meet.example.com/…\"\n />\n </FormField>\n )}\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 <FormField label=\"Duration (minutes)\" htmlFor=\"duration\">\n <input\n id=\"duration\"\n inputMode=\"numeric\"\n className={fieldInputClass}\n value={durationMin}\n onChange={(e) => setDurationMin(e.target.value)}\n />\n </FormField>\n </div>\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={bookSession.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 {bookSession.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Save className=\"h-4 w-4\" />\n )}\n Book session\n </button>\n </div>\n </form>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;AAcA,IAAM,IAAQ,OAAO,KAAK,EAAoB;AAE9C,SAAgB,IAAkB;CAChC,IAAM,EAAE,eAAY,mBAAgB,GAAkB,EAEhD,IAAW,EAAY;EAAE,QAAQ;EAAa,YAAY,EAAE,OAAO,KAAK;EAAE,CAAC,EAC3E,IAAc,GAAgB,EAE9B,CAAC,GAAS,KAAc,EAAS,GAAa,MAAM,GAAG,EACvD,CAAC,GAAW,KAAgB,EAAS,GAAG,EACxC,CAAC,GAAW,KAAgB,EAAS,GAAG,EACxC,CAAC,GAAO,KAAY,EAAS,GAAG,EAChC,CAAC,GAAM,KAAW,EAAyB,YAAY,EACvD,CAAC,GAAU,KAAe,EAAS,GAAG,EACtC,CAAC,GAAY,KAAiB,EAAS,GAAG,EAC1C,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAa,KAAkB,EAAS,KAAK,EAC9C,CAAC,GAAO,KAAY,EAAwB,KAAK,EAEjD,IAAiB,EAAS,MAAM,SAAS,EAAE;AA8CjD,QACE,kBAAC,GAAD;EACE,OAAM;EACN,aAAY;EACZ,SACE,kBAAC,UAAD;GACE,MAAK;GACL,eAAe,EAAW,YAAY;GACtC,WAAU;aAHZ,CAKE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,UAC1B;;YAGX,kBAAC,QAAD;GAAM,UA1DW,OAAO,MAAuB;AAIjD,QAHA,EAAE,gBAAgB,EAClB,EAAS,KAAK,EAEV,CAAC,EAAQ,MAAM,EAAE;AACnB,OAAS,wBAAwB;AACjC;;AAEF,QAAI,CAAC,EAAU,MAAM,EAAE;AACrB,OAAS,0BAA0B;AACnC;;AAEF,QAAI,CAAC,EAAM,MAAM,EAAE;AACjB,OAAS,+BAA+B;AACxC;;AAEF,QAAI,CAAC,GAAa;AAChB,OAAS,yCAAyC;AAClD;;IAEF,IAAM,IAAW,OAAO,SAAS,GAAa,GAAG;AACjD,QAAI,OAAO,MAAM,EAAS,IAAI,KAAY,GAAG;AAC3C,OAAS,iDAAiD;AAC1D;;AAGF,QAAI;AAYF,OAAW,cAXK,MAAM,EAAY,YAAY;MAC5C,SAAS,EAAQ,MAAM;MACvB,WAAW,EAAU,MAAM;MAC3B,WAAW,KAAa,KAAA;MACxB,OAAO,EAAM,MAAM;MACnB;MACA,UAAU,MAAS,WAA0C,KAAA,IAA/B,EAAS,MAAM,IAAI,KAAA;MACjD,YAAY,MAAS,cAA+C,KAAA,IAAjC,EAAW,MAAM,IAAI,KAAA;MACxD,aAAa,IAAI,KAAK,EAAY,CAAC,aAAa;MAChD,aAAa;MACd,CAAC,EAC8B,KAAK;aAC9B,GAAK;AACZ,OAAS,aAAe,QAAQ,EAAI,UAAU,0BAA0B;;;GAkB1C,WAAU;aAAxC;IACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAW,OAAM;MAAW,SAAQ;MAAU,UAAA;MAAS,MAAK;gBAC1D,kBAAC,SAAD;OACE,IAAG;OACH,WAAW;OACX,OAAO;OACP,WAAW,MAAM,EAAW,EAAE,OAAO,MAAM;OAC3C,aAAY;OACZ,CAAA;MACQ,CAAA,EACZ,kBAAC,GAAD;MAAW,OAAM;MAAa,SAAQ;MAAY,UAAA;gBAChD,kBAAC,SAAD;OACE,IAAG;OACH,WAAW;OACX,OAAO;OACP,WAAW,MAAM,EAAa,EAAE,OAAO,MAAM;OAC7C,aAAY;OACZ,CAAA;MACQ,CAAA,CACR;;IAEN,kBAAC,GAAD;KAAW,OAAM;KAAQ,SAAQ;KAAQ,UAAA;eACvC,kBAAC,SAAD;MACE,IAAG;MACH,WAAW;MACX,OAAO;MACP,WAAW,MAAM,EAAS,EAAE,OAAO,MAAM;MACzC,aAAY;MACZ,CAAA;KACQ,CAAA;IAEZ,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAW,OAAM;MAAO,SAAQ;gBAC9B,kBAAC,UAAD;OACE,IAAG;OACH,WAAW;OACX,OAAO;OACP,WAAW,MAAM,EAAQ,EAAE,OAAO,MAAwB;iBAEzD,EAAM,KAAK,MACV,kBAAC,UAAD;QAAiB,OAAO;kBACrB,EAAoB;QACd,EAFI,EAEJ,CACT;OACK,CAAA;MACC,CAAA,EAEZ,kBAAC,GAAD;MAAW,OAAM;MAAU,SAAQ;MAAU,MAAK;gBAChD,kBAAC,UAAD;OACE,IAAG;OACH,WAAW;OACX,OAAO;OACP,WAAW,MAAM,EAAa,EAAE,OAAO,MAAM;iBAJ/C,CAME,kBAAC,UAAD;QAAQ,OAAM;kBAAG;QAAmB,CAAA,EACnC,EAAe,KAAK,MACnB,kBAAC,UAAD;QAAoB,OAAO,EAAG;kBAC3B,EAAG;QACG,EAFI,EAAG,GAEP,CACT,CACK;;MACC,CAAA,CACR;;IAEL,MAAS,YACR,kBAAC,GAAD;KAAW,OAAM;KAAW,SAAQ;eAClC,kBAAC,SAAD;MACE,IAAG;MACH,WAAW;MACX,OAAO;MACP,WAAW,MAAM,EAAY,EAAE,OAAO,MAAM;MAC5C,aAAY;MACZ,CAAA;KACQ,CAAA;IAGb,MAAS,eACR,kBAAC,GAAD;KAAW,OAAM;KAAc,SAAQ;eACrC,kBAAC,SAAD;MACE,IAAG;MACH,WAAW;MACX,OAAO;MACP,WAAW,MAAM,EAAc,EAAE,OAAO,MAAM;MAC9C,aAAY;MACZ,CAAA;KACQ,CAAA;IAGd,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAW,OAAM;MAAe,SAAQ;MAAc,UAAA;gBACpD,kBAAC,SAAD;OACE,IAAG;OACH,MAAK;OACL,WAAW;OACX,OAAO;OACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;OAC/C,CAAA;MACQ,CAAA,EACZ,kBAAC,GAAD;MAAW,OAAM;MAAqB,SAAQ;gBAC5C,kBAAC,SAAD;OACE,IAAG;OACH,WAAU;OACV,WAAW;OACX,OAAO;OACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;OAC/C,CAAA;MACQ,CAAA,CACR;;IAEL,KAAS,kBAAC,KAAD;KAAG,WAAU;eAAkC;KAAU,CAAA;IAEnE,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,UAAD;MACE,MAAK;MACL,UAAU,EAAY;MACtB,WAAU;gBAHZ,CAKG,EAAY,YACX,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,GAE5C,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAC5B,eAEK;;KACL,CAAA;IACD;;EACI,CAAA"}
@@ -0,0 +1,92 @@
1
+ import { useAthleteBridge as e } from "../../context/AthleteBridgeContext.js";
2
+ import { PageLayout as t } from "../../components/PageLayout.js";
3
+ import { SessionCard as n } from "../../components/SessionCard.js";
4
+ import { EmptyState as r } from "../../components/EmptyState.js";
5
+ import { ErrorState as i, LoadingState as a } from "../../components/LoadingState.js";
6
+ import { useSessions 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 { ClipboardCheck 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/sessions/SessionsListPage.tsx
13
+ var h = 12, g = [
14
+ {
15
+ value: "REQUESTED",
16
+ label: "Requested"
17
+ },
18
+ {
19
+ value: "CONFIRMED",
20
+ label: "Confirmed"
21
+ },
22
+ {
23
+ value: "COMPLETED",
24
+ label: "Completed"
25
+ },
26
+ {
27
+ value: "CANCELLED",
28
+ label: "Cancelled"
29
+ },
30
+ {
31
+ value: "NO_SHOW",
32
+ label: "No show"
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: "Sessions",
45
+ description: "One-to-one coaching sessions with a request → confirm → complete flow.",
46
+ actions: /* @__PURE__ */ m("button", {
47
+ type: "button",
48
+ onClick: () => _("/sessions/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" }), " Book session"]
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 sessions…" }) : 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 sessions found",
67
+ description: v ? "Try clearing your filter to see all sessions." : "Book a coaching session with an athlete to get started.",
68
+ action: /* @__PURE__ */ p("button", {
69
+ type: "button",
70
+ onClick: () => _("/sessions/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: "Book session"
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
+ session: e,
78
+ onClick: () => _(`/sessions/${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 SessionsListPage };
91
+
92
+ //# sourceMappingURL=SessionsListPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SessionsListPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/sessions/SessionsListPage.tsx"],"sourcesContent":["/**\n * Sessions List\n * @module atheletebridge/pages/sessions\n */\n\nimport { useState } from 'react';\nimport { ClipboardCheck, Plus } from 'lucide-react';\nimport { PageLayout } from '../../components/PageLayout';\nimport { SessionCard } from '../../components/SessionCard';\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 { useSessions } from '../../hooks/useAthleteBridgeApi';\nimport type { AthSessionStatus } from '../../types';\n\nconst PAGE_SIZE = 12;\n\nconst STATUS_OPTS: ReadonlyArray<{ value: AthSessionStatus; label: string }> = [\n { value: 'REQUESTED', label: 'Requested' },\n { value: 'CONFIRMED', label: 'Confirmed' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'CANCELLED', label: 'Cancelled' },\n { value: 'NO_SHOW', label: 'No show' },\n];\n\nexport function SessionsListPage() {\n const { navigateTo } = useAthleteBridge();\n const [status, setStatus] = useState<AthSessionStatus | ''>('');\n const [page, setPage] = useState(0);\n\n const sessions = useSessions({\n status: status || undefined,\n pagination: { limit: PAGE_SIZE, offset: page * PAGE_SIZE },\n });\n\n const items = sessions.data?.items ?? [];\n const hasMore = sessions.data?.pageInfo.hasMore ?? false;\n\n return (\n <PageLayout\n title=\"Sessions\"\n description=\"One-to-one coaching sessions with a request → confirm → complete flow.\"\n actions={\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions/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\" /> Book session\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 {sessions.isLoading ? (\n <LoadingState label=\"Loading sessions…\" />\n ) : sessions.isError ? (\n <ErrorState onRetry={() => void sessions.refetch()} />\n ) : items.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<ClipboardCheck className=\"h-10 w-10\" />}\n title=\"No sessions found\"\n description={\n status\n ? 'Try clearing your filter to see all sessions.'\n : 'Book a coaching session with an athlete to get started.'\n }\n action={\n <button\n type=\"button\"\n onClick={() => navigateTo('/sessions/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 Book session\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((session) => (\n <SessionCard\n key={session.id}\n session={session}\n onClick={() => navigateTo(`/sessions/${session.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;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAW,OAAO;EAAW;CACvC;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,gBACrB;;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,EAAgB,WAAU,aAAc,CAAA;GAC9C,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"}
@@ -0,0 +1,350 @@
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 { 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 { useState as h } from "react";
11
+ import { Archive as g, ArrowLeft as _, CalendarDays as v, Edit as y, Loader2 as b, MapPin as x, Plus as S, Trash2 as C, UserPlus as w } from "lucide-react";
12
+ import { useParams as T } from "react-router-dom";
13
+ import { jsx as E, jsxs as D } from "react/jsx-runtime";
14
+ import { EmphasisPanel as O, GlassCard as k, ResponsiveDialog as A, ResponsiveDialogContent as j, ResponsiveDialogFooter as M, ResponsiveDialogHeader as N, ResponsiveDialogTitle as P } from "@burdenoff/fe-libs/ui";
15
+ //#region src/atheletebridge/pages/teams/TeamDetailPage.tsx
16
+ var F = Object.keys(r), I = [
17
+ "TRIAL",
18
+ "ACTIVE",
19
+ "INJURED",
20
+ "SUSPENDED",
21
+ "RELEASED"
22
+ ], L = {
23
+ userId: "",
24
+ displayName: "",
25
+ role: "PLAYER",
26
+ status: "ACTIVE",
27
+ position: "",
28
+ jerseyNumber: ""
29
+ };
30
+ function R() {
31
+ let { id: R } = T(), { navigateTo: z } = e(), B = f(R), V = u(), H = l(), U = d(R), [W, G] = h(!1), [K, q] = h(L), [J, Y] = h(null);
32
+ if (B.isLoading) return /* @__PURE__ */ E(t, {
33
+ title: "Team",
34
+ children: /* @__PURE__ */ E(c, { label: "Loading team…" })
35
+ });
36
+ if (B.isError || !B.data) return /* @__PURE__ */ E(t, {
37
+ title: "Team",
38
+ children: /* @__PURE__ */ E(s, {
39
+ title: "Team not found",
40
+ message: "This team does not exist or you do not have access to it.",
41
+ onRetry: () => z("/teams")
42
+ })
43
+ });
44
+ let X = B.data, Z = X.members ?? [], Q = X.fixtures ?? [];
45
+ return /* @__PURE__ */ D(t, {
46
+ title: X.name,
47
+ description: `${i[X.sport]}${X.season ? ` · ${X.season}` : ""}`,
48
+ actions: /* @__PURE__ */ D("div", {
49
+ className: "flex flex-wrap items-center gap-2",
50
+ children: [
51
+ /* @__PURE__ */ D("button", {
52
+ type: "button",
53
+ onClick: () => z("/teams"),
54
+ 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",
55
+ children: [/* @__PURE__ */ E(_, { className: "h-4 w-4" }), " Back"]
56
+ }),
57
+ /* @__PURE__ */ D("button", {
58
+ type: "button",
59
+ onClick: () => z(`/teams/${X.id}/edit`),
60
+ 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",
61
+ children: [/* @__PURE__ */ E(y, { className: "h-4 w-4" }), " Edit"]
62
+ }),
63
+ X.status !== "ARCHIVED" && /* @__PURE__ */ D("button", {
64
+ type: "button",
65
+ onClick: async () => {
66
+ R && (await V.mutateAsync(R), z("/teams"));
67
+ },
68
+ disabled: V.isPending,
69
+ 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",
70
+ children: [
71
+ V.isPending ? /* @__PURE__ */ E(b, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ E(g, { className: "h-4 w-4" }),
72
+ " ",
73
+ "Archive"
74
+ ]
75
+ })
76
+ ]
77
+ }),
78
+ children: [
79
+ /* @__PURE__ */ D(k, {
80
+ treatment: "insight",
81
+ className: "mb-8 p-6",
82
+ children: [
83
+ /* @__PURE__ */ D("div", {
84
+ className: "flex flex-wrap items-center gap-3",
85
+ children: [
86
+ /* @__PURE__ */ E(n, { status: X.status }),
87
+ X.ageGroup && /* @__PURE__ */ D("span", {
88
+ className: "text-sm text-text-secondary",
89
+ children: ["Age group: ", X.ageGroup]
90
+ }),
91
+ X.homeVenue && /* @__PURE__ */ D("span", {
92
+ className: "flex items-center gap-1 text-sm text-text-secondary",
93
+ children: [
94
+ /* @__PURE__ */ E(x, { className: "h-3.5 w-3.5" }),
95
+ " ",
96
+ X.homeVenue
97
+ ]
98
+ })
99
+ ]
100
+ }),
101
+ X.description && /* @__PURE__ */ E("p", {
102
+ className: "mt-4 text-sm text-text-secondary",
103
+ children: X.description
104
+ }),
105
+ X.tags.length > 0 && /* @__PURE__ */ E("div", {
106
+ className: "mt-4 flex flex-wrap gap-1.5",
107
+ children: X.tags.map((e) => /* @__PURE__ */ E("span", {
108
+ className: "inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary",
109
+ children: e
110
+ }, e))
111
+ })
112
+ ]
113
+ }),
114
+ /* @__PURE__ */ D("section", {
115
+ className: "mb-8",
116
+ children: [/* @__PURE__ */ D("div", {
117
+ className: "mb-4 flex items-center justify-between",
118
+ children: [/* @__PURE__ */ D("h2", {
119
+ className: "text-lg font-semibold text-text-primary",
120
+ children: [
121
+ "Roster (",
122
+ Z.length,
123
+ ")"
124
+ ]
125
+ }), /* @__PURE__ */ D("button", {
126
+ type: "button",
127
+ onClick: () => {
128
+ Y(null), G(!0);
129
+ },
130
+ 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",
131
+ children: [/* @__PURE__ */ E(w, { className: "h-4 w-4" }), " Add member"]
132
+ })]
133
+ }), Z.length === 0 ? /* @__PURE__ */ E(o, {
134
+ illustration: "empty-data",
135
+ icon: /* @__PURE__ */ E(w, { className: "h-10 w-10" }),
136
+ title: "No members yet",
137
+ description: "Add players, coaches and staff to build the roster."
138
+ }) : /* @__PURE__ */ E(O, { children: /* @__PURE__ */ E("div", {
139
+ className: "divide-y divide-border-seam",
140
+ children: Z.map((e) => /* @__PURE__ */ D("div", {
141
+ className: "flex items-center gap-4 py-3",
142
+ children: [
143
+ /* @__PURE__ */ E("div", {
144
+ 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",
145
+ children: e.jerseyNumber ?? e.displayName.charAt(0).toUpperCase()
146
+ }),
147
+ /* @__PURE__ */ D("div", {
148
+ className: "min-w-0 flex-1",
149
+ children: [/* @__PURE__ */ E("p", {
150
+ className: "truncate text-sm font-medium text-text-primary",
151
+ children: e.displayName
152
+ }), /* @__PURE__ */ D("p", {
153
+ className: "text-xs text-text-secondary",
154
+ children: [r[e.role], e.position ? ` · ${e.position}` : ""]
155
+ })]
156
+ }),
157
+ /* @__PURE__ */ E(n, { status: e.status }),
158
+ /* @__PURE__ */ E("button", {
159
+ type: "button",
160
+ onClick: () => void U.mutate(e.id),
161
+ disabled: U.isPending,
162
+ "aria-label": `Remove ${e.displayName}`,
163
+ className: "rounded-lg p-2 text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text disabled:opacity-60",
164
+ children: /* @__PURE__ */ E(C, { className: "h-4 w-4" })
165
+ })
166
+ ]
167
+ }, e.id))
168
+ }) })]
169
+ }),
170
+ /* @__PURE__ */ D("section", { children: [/* @__PURE__ */ D("div", {
171
+ className: "mb-4 flex items-center justify-between",
172
+ children: [/* @__PURE__ */ D("h2", {
173
+ className: "text-lg font-semibold text-text-primary",
174
+ children: [
175
+ "Fixtures (",
176
+ Q.length,
177
+ ")"
178
+ ]
179
+ }), /* @__PURE__ */ D("button", {
180
+ type: "button",
181
+ onClick: () => z(`/fixtures/new?homeTeamId=${X.id}`),
182
+ 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",
183
+ children: [/* @__PURE__ */ E(S, { className: "h-4 w-4" }), " Schedule"]
184
+ })]
185
+ }), Q.length === 0 ? /* @__PURE__ */ E(o, {
186
+ illustration: "empty-calendar",
187
+ icon: /* @__PURE__ */ E(v, { className: "h-10 w-10" }),
188
+ title: "No fixtures scheduled",
189
+ description: "Schedule a match for this team to start tracking results."
190
+ }) : /* @__PURE__ */ E("div", {
191
+ className: "grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3",
192
+ children: Q.map((e) => /* @__PURE__ */ E(a, {
193
+ fixture: e,
194
+ onClick: () => z(`/fixtures/${e.id}`)
195
+ }, e.id))
196
+ })] }),
197
+ /* @__PURE__ */ E(A, {
198
+ open: W,
199
+ onOpenChange: G,
200
+ children: /* @__PURE__ */ D(j, { children: [/* @__PURE__ */ E(N, { children: /* @__PURE__ */ E(P, { children: "Add member" }) }), /* @__PURE__ */ D("form", {
201
+ onSubmit: async (e) => {
202
+ if (e.preventDefault(), Y(null), !R) return;
203
+ if (!K.userId.trim() || !K.displayName.trim()) {
204
+ Y("User ID and display name are required.");
205
+ return;
206
+ }
207
+ let t = K.jerseyNumber.trim() ? Number.parseInt(K.jerseyNumber, 10) : void 0;
208
+ if (t !== void 0 && Number.isNaN(t)) {
209
+ Y("Jersey number must be a number.");
210
+ return;
211
+ }
212
+ try {
213
+ await H.mutateAsync({
214
+ teamId: R,
215
+ userId: K.userId.trim(),
216
+ displayName: K.displayName.trim(),
217
+ role: K.role,
218
+ status: K.status,
219
+ position: K.position.trim() || void 0,
220
+ jerseyNumber: t
221
+ }), q(L), G(!1);
222
+ } catch (e) {
223
+ Y(e instanceof Error ? e.message : "Failed to add member.");
224
+ }
225
+ },
226
+ className: "space-y-4 px-1",
227
+ children: [
228
+ /* @__PURE__ */ E(p, {
229
+ label: "User ID",
230
+ htmlFor: "userId",
231
+ required: !0,
232
+ hint: "The auth-svc user id.",
233
+ children: /* @__PURE__ */ E("input", {
234
+ id: "userId",
235
+ className: m,
236
+ value: K.userId,
237
+ onChange: (e) => q((t) => ({
238
+ ...t,
239
+ userId: e.target.value
240
+ })),
241
+ placeholder: "user-uuid"
242
+ })
243
+ }),
244
+ /* @__PURE__ */ E(p, {
245
+ label: "Display name",
246
+ htmlFor: "displayName",
247
+ required: !0,
248
+ children: /* @__PURE__ */ E("input", {
249
+ id: "displayName",
250
+ className: m,
251
+ value: K.displayName,
252
+ onChange: (e) => q((t) => ({
253
+ ...t,
254
+ displayName: e.target.value
255
+ })),
256
+ placeholder: "e.g. Alex Morgan"
257
+ })
258
+ }),
259
+ /* @__PURE__ */ D("div", {
260
+ className: "grid grid-cols-2 gap-4",
261
+ children: [/* @__PURE__ */ E(p, {
262
+ label: "Role",
263
+ htmlFor: "role",
264
+ children: /* @__PURE__ */ E("select", {
265
+ id: "role",
266
+ className: m,
267
+ value: K.role,
268
+ onChange: (e) => q((t) => ({
269
+ ...t,
270
+ role: e.target.value
271
+ })),
272
+ children: F.map((e) => /* @__PURE__ */ E("option", {
273
+ value: e,
274
+ children: r[e]
275
+ }, e))
276
+ })
277
+ }), /* @__PURE__ */ E(p, {
278
+ label: "Status",
279
+ htmlFor: "memberStatus",
280
+ children: /* @__PURE__ */ E("select", {
281
+ id: "memberStatus",
282
+ className: m,
283
+ value: K.status,
284
+ onChange: (e) => q((t) => ({
285
+ ...t,
286
+ status: e.target.value
287
+ })),
288
+ children: I.map((e) => /* @__PURE__ */ E("option", {
289
+ value: e,
290
+ children: e.charAt(0) + e.slice(1).toLowerCase()
291
+ }, e))
292
+ })
293
+ })]
294
+ }),
295
+ /* @__PURE__ */ D("div", {
296
+ className: "grid grid-cols-2 gap-4",
297
+ children: [/* @__PURE__ */ E(p, {
298
+ label: "Position",
299
+ htmlFor: "position",
300
+ children: /* @__PURE__ */ E("input", {
301
+ id: "position",
302
+ className: m,
303
+ value: K.position,
304
+ onChange: (e) => q((t) => ({
305
+ ...t,
306
+ position: e.target.value
307
+ })),
308
+ placeholder: "e.g. Striker"
309
+ })
310
+ }), /* @__PURE__ */ E(p, {
311
+ label: "Jersey #",
312
+ htmlFor: "jersey",
313
+ children: /* @__PURE__ */ E("input", {
314
+ id: "jersey",
315
+ className: m,
316
+ inputMode: "numeric",
317
+ value: K.jerseyNumber,
318
+ onChange: (e) => q((t) => ({
319
+ ...t,
320
+ jerseyNumber: e.target.value
321
+ })),
322
+ placeholder: "9"
323
+ })
324
+ })]
325
+ }),
326
+ J && /* @__PURE__ */ E("p", {
327
+ className: "text-sm text-status-error-text",
328
+ children: J
329
+ }),
330
+ /* @__PURE__ */ D(M, { children: [/* @__PURE__ */ E("button", {
331
+ type: "button",
332
+ onClick: () => G(!1),
333
+ className: "rounded-lg border border-border-seam px-4 py-2 text-sm font-medium text-text-primary transition-colors hover:bg-bg-sunken",
334
+ children: "Cancel"
335
+ }), /* @__PURE__ */ D("button", {
336
+ type: "submit",
337
+ disabled: H.isPending,
338
+ 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",
339
+ children: [H.isPending && /* @__PURE__ */ E(b, { className: "h-4 w-4 animate-spin" }), "Add member"]
340
+ })] })
341
+ ]
342
+ })] })
343
+ })
344
+ ]
345
+ });
346
+ }
347
+ //#endregion
348
+ export { R as TeamDetailPage };
349
+
350
+ //# sourceMappingURL=TeamDetailPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TeamDetailPage.js","names":[],"sources":["../../../../src/atheletebridge/pages/teams/TeamDetailPage.tsx"],"sourcesContent":["/**\n * Team Detail\n * @module atheletebridge/pages/teams\n *\n * Reads a single team (with members + fixtures) from `athTeam`, supports adding\n * and removing members (athAddMember / athRemoveMember), editing and archiving\n * the team (athUpdateTeam via the form / athArchiveTeam), and links into the\n * team's fixtures.\n */\n\nimport { useState } from 'react';\nimport { useParams } from 'react-router-dom';\nimport {\n ArrowLeft,\n CalendarDays,\n Edit,\n Archive,\n MapPin,\n Plus,\n Trash2,\n UserPlus,\n Loader2,\n} from 'lucide-react';\nimport {\n GlassCard,\n EmphasisPanel,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n ResponsiveDialogFooter,\n} from '@burdenoff/fe-libs/ui';\nimport { PageLayout } from '../../components/PageLayout';\nimport { StatusBadge } from '../../components/StatusBadge';\nimport { FixtureCard } from '../../components/FixtureCard';\nimport { EmptyState } from '../../components/EmptyState';\nimport { LoadingState, ErrorState } from '../../components/LoadingState';\nimport { FormField, fieldInputClass } from '../../components/form';\nimport { SPORT_LABELS, MEMBER_ROLE_LABELS } from '../../components/domain';\nimport { useAthleteBridge } from '../../context/AthleteBridgeContext';\nimport {\n useTeam,\n useArchiveTeam,\n useAddMember,\n useRemoveMember,\n} from '../../hooks/useAthleteBridgeApi';\nimport type { AthMemberRole, AthMemberStatus } from '../../types';\n\nconst ROLES = Object.keys(MEMBER_ROLE_LABELS) as AthMemberRole[];\nconst MEMBER_STATUSES: AthMemberStatus[] = [\n 'TRIAL',\n 'ACTIVE',\n 'INJURED',\n 'SUSPENDED',\n 'RELEASED',\n];\n\ninterface AddMemberForm {\n userId: string;\n displayName: string;\n role: AthMemberRole;\n status: AthMemberStatus;\n position: string;\n jerseyNumber: string;\n}\n\nconst EMPTY_MEMBER: AddMemberForm = {\n userId: '',\n displayName: '',\n role: 'PLAYER',\n status: 'ACTIVE',\n position: '',\n jerseyNumber: '',\n};\n\nexport function TeamDetailPage() {\n const { id } = useParams<{ id: string }>();\n const { navigateTo } = useAthleteBridge();\n\n const team = useTeam(id);\n const archiveTeam = useArchiveTeam();\n const addMember = useAddMember();\n const removeMember = useRemoveMember(id);\n\n const [addOpen, setAddOpen] = useState(false);\n const [memberForm, setMemberForm] = useState<AddMemberForm>(EMPTY_MEMBER);\n const [memberError, setMemberError] = useState<string | null>(null);\n\n if (team.isLoading) {\n return (\n <PageLayout title=\"Team\">\n <LoadingState label=\"Loading team…\" />\n </PageLayout>\n );\n }\n\n if (team.isError || !team.data) {\n return (\n <PageLayout title=\"Team\">\n <ErrorState\n title=\"Team not found\"\n message=\"This team does not exist or you do not have access to it.\"\n onRetry={() => navigateTo('/teams')}\n />\n </PageLayout>\n );\n }\n\n const t = team.data;\n const members = t.members ?? [];\n const fixtures = t.fixtures ?? [];\n\n const handleArchive = async () => {\n if (!id) return;\n await archiveTeam.mutateAsync(id);\n navigateTo('/teams');\n };\n\n const handleAddMember = async (e: React.FormEvent) => {\n e.preventDefault();\n setMemberError(null);\n if (!id) return;\n if (!memberForm.userId.trim() || !memberForm.displayName.trim()) {\n setMemberError('User ID and display name are required.');\n return;\n }\n const jersey = memberForm.jerseyNumber.trim()\n ? Number.parseInt(memberForm.jerseyNumber, 10)\n : undefined;\n if (jersey !== undefined && Number.isNaN(jersey)) {\n setMemberError('Jersey number must be a number.');\n return;\n }\n try {\n await addMember.mutateAsync({\n teamId: id,\n userId: memberForm.userId.trim(),\n displayName: memberForm.displayName.trim(),\n role: memberForm.role,\n status: memberForm.status,\n position: memberForm.position.trim() || undefined,\n jerseyNumber: jersey,\n });\n setMemberForm(EMPTY_MEMBER);\n setAddOpen(false);\n } catch (err) {\n setMemberError(err instanceof Error ? err.message : 'Failed to add member.');\n }\n };\n\n return (\n <PageLayout\n title={t.name}\n description={`${SPORT_LABELS[t.sport]}${t.season ? ` · ${t.season}` : ''}`}\n actions={\n <div className=\"flex flex-wrap items-center gap-2\">\n <button\n type=\"button\"\n onClick={() => navigateTo('/teams')}\n 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\"\n >\n <ArrowLeft className=\"h-4 w-4\" /> Back\n </button>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/teams/${t.id}/edit`)}\n 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\"\n >\n <Edit className=\"h-4 w-4\" /> Edit\n </button>\n {t.status !== 'ARCHIVED' && (\n <button\n type=\"button\"\n onClick={handleArchive}\n disabled={archiveTeam.isPending}\n 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\"\n >\n {archiveTeam.isPending ? (\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n ) : (\n <Archive className=\"h-4 w-4\" />\n )}{' '}\n Archive\n </button>\n )}\n </div>\n }\n >\n {/* Summary */}\n <GlassCard treatment=\"insight\" className=\"mb-8 p-6\">\n <div className=\"flex flex-wrap items-center gap-3\">\n <StatusBadge status={t.status} />\n {t.ageGroup && (\n <span className=\"text-sm text-text-secondary\">Age group: {t.ageGroup}</span>\n )}\n {t.homeVenue && (\n <span className=\"flex items-center gap-1 text-sm text-text-secondary\">\n <MapPin className=\"h-3.5 w-3.5\" /> {t.homeVenue}\n </span>\n )}\n </div>\n {t.description && <p className=\"mt-4 text-sm text-text-secondary\">{t.description}</p>}\n {t.tags.length > 0 && (\n <div className=\"mt-4 flex flex-wrap gap-1.5\">\n {t.tags.map((tag) => (\n <span\n key={tag}\n className=\"inline-flex items-center rounded-full bg-bg-sunken px-2 py-0.5 text-xs text-text-secondary\"\n >\n {tag}\n </span>\n ))}\n </div>\n )}\n </GlassCard>\n\n {/* Roster */}\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\">Roster ({members.length})</h2>\n <button\n type=\"button\"\n onClick={() => {\n setMemberError(null);\n setAddOpen(true);\n }}\n 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\"\n >\n <UserPlus className=\"h-4 w-4\" /> Add member\n </button>\n </div>\n\n {members.length === 0 ? (\n <EmptyState\n illustration=\"empty-data\"\n icon={<UserPlus className=\"h-10 w-10\" />}\n title=\"No members yet\"\n description=\"Add players, coaches and staff to build the roster.\"\n />\n ) : (\n <EmphasisPanel>\n <div className=\"divide-y divide-border-seam\">\n {members.map((m) => (\n <div key={m.id} className=\"flex items-center gap-4 py-3\">\n <div 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\">\n {m.jerseyNumber ?? m.displayName.charAt(0).toUpperCase()}\n </div>\n <div className=\"min-w-0 flex-1\">\n <p className=\"truncate text-sm font-medium text-text-primary\">\n {m.displayName}\n </p>\n <p className=\"text-xs text-text-secondary\">\n {MEMBER_ROLE_LABELS[m.role]}\n {m.position ? ` · ${m.position}` : ''}\n </p>\n </div>\n <StatusBadge status={m.status} />\n <button\n type=\"button\"\n onClick={() => void removeMember.mutate(m.id)}\n disabled={removeMember.isPending}\n aria-label={`Remove ${m.displayName}`}\n className=\"rounded-lg p-2 text-text-secondary transition-colors hover:bg-status-error-bg-subtle hover:text-status-error-text disabled:opacity-60\"\n >\n <Trash2 className=\"h-4 w-4\" />\n </button>\n </div>\n ))}\n </div>\n </EmphasisPanel>\n )}\n </section>\n\n {/* Fixtures */}\n <section>\n <div className=\"mb-4 flex items-center justify-between\">\n <h2 className=\"text-lg font-semibold text-text-primary\">Fixtures ({fixtures.length})</h2>\n <button\n type=\"button\"\n onClick={() => navigateTo(`/fixtures/new?homeTeamId=${t.id}`)}\n 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\"\n >\n <Plus className=\"h-4 w-4\" /> Schedule\n </button>\n </div>\n {fixtures.length === 0 ? (\n <EmptyState\n illustration=\"empty-calendar\"\n icon={<CalendarDays className=\"h-10 w-10\" />}\n title=\"No fixtures scheduled\"\n description=\"Schedule a match for this team to start tracking results.\"\n />\n ) : (\n <div className=\"grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3\">\n {fixtures.map((f) => (\n <FixtureCard\n key={f.id}\n fixture={f}\n onClick={() => navigateTo(`/fixtures/${f.id}`)}\n />\n ))}\n </div>\n )}\n </section>\n\n {/* Add member dialog */}\n <ResponsiveDialog open={addOpen} onOpenChange={setAddOpen}>\n <ResponsiveDialogContent>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>Add member</ResponsiveDialogTitle>\n </ResponsiveDialogHeader>\n <form onSubmit={handleAddMember} className=\"space-y-4 px-1\">\n <FormField label=\"User ID\" htmlFor=\"userId\" required hint=\"The auth-svc user id.\">\n <input\n id=\"userId\"\n className={fieldInputClass}\n value={memberForm.userId}\n onChange={(e) =>\n setMemberForm((p) => ({ ...p, userId: e.target.value }))\n }\n placeholder=\"user-uuid\"\n />\n </FormField>\n <FormField label=\"Display name\" htmlFor=\"displayName\" required>\n <input\n id=\"displayName\"\n className={fieldInputClass}\n value={memberForm.displayName}\n onChange={(e) =>\n setMemberForm((p) => ({ ...p, displayName: e.target.value }))\n }\n placeholder=\"e.g. Alex Morgan\"\n />\n </FormField>\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Role\" htmlFor=\"role\">\n <select\n id=\"role\"\n className={fieldInputClass}\n value={memberForm.role}\n onChange={(e) =>\n setMemberForm((p) => ({ ...p, role: e.target.value as AthMemberRole }))\n }\n >\n {ROLES.map((r) => (\n <option key={r} value={r}>\n {MEMBER_ROLE_LABELS[r]}\n </option>\n ))}\n </select>\n </FormField>\n <FormField label=\"Status\" htmlFor=\"memberStatus\">\n <select\n id=\"memberStatus\"\n className={fieldInputClass}\n value={memberForm.status}\n onChange={(e) =>\n setMemberForm((p) => ({ ...p, status: e.target.value as AthMemberStatus }))\n }\n >\n {MEMBER_STATUSES.map((s) => (\n <option key={s} value={s}>\n {s.charAt(0) + s.slice(1).toLowerCase()}\n </option>\n ))}\n </select>\n </FormField>\n </div>\n <div className=\"grid grid-cols-2 gap-4\">\n <FormField label=\"Position\" htmlFor=\"position\">\n <input\n id=\"position\"\n className={fieldInputClass}\n value={memberForm.position}\n onChange={(e) =>\n setMemberForm((p) => ({ ...p, position: e.target.value }))\n }\n placeholder=\"e.g. Striker\"\n />\n </FormField>\n <FormField label=\"Jersey #\" htmlFor=\"jersey\">\n <input\n id=\"jersey\"\n className={fieldInputClass}\n inputMode=\"numeric\"\n value={memberForm.jerseyNumber}\n onChange={(e) =>\n setMemberForm((p) => ({ ...p, jerseyNumber: e.target.value }))\n }\n placeholder=\"9\"\n />\n </FormField>\n </div>\n {memberError && <p className=\"text-sm text-status-error-text\">{memberError}</p>}\n <ResponsiveDialogFooter>\n <button\n type=\"button\"\n onClick={() => setAddOpen(false)}\n className=\"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 Cancel\n </button>\n <button\n type=\"submit\"\n disabled={addMember.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 {addMember.isPending && <Loader2 className=\"h-4 w-4 animate-spin\" />}\n Add member\n </button>\n </ResponsiveDialogFooter>\n </form>\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n </PageLayout>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;AAgDA,IAAM,IAAQ,OAAO,KAAK,EAAmB,EACvC,IAAqC;CACzC;CACA;CACA;CACA;CACA;CACD,EAWK,IAA8B;CAClC,QAAQ;CACR,aAAa;CACb,MAAM;CACN,QAAQ;CACR,UAAU;CACV,cAAc;CACf;AAED,SAAgB,IAAiB;CAC/B,IAAM,EAAE,UAAO,GAA2B,EACpC,EAAE,kBAAe,GAAkB,EAEnC,IAAO,EAAQ,EAAG,EAClB,IAAc,GAAgB,EAC9B,IAAY,GAAc,EAC1B,IAAe,EAAgB,EAAG,EAElC,CAAC,GAAS,KAAc,EAAS,GAAM,EACvC,CAAC,GAAY,KAAiB,EAAwB,EAAa,EACnE,CAAC,GAAa,KAAkB,EAAwB,KAAK;AAEnE,KAAI,EAAK,UACP,QACE,kBAAC,GAAD;EAAY,OAAM;YAChB,kBAAC,GAAD,EAAc,OAAM,iBAAkB,CAAA;EAC3B,CAAA;AAIjB,KAAI,EAAK,WAAW,CAAC,EAAK,KACxB,QACE,kBAAC,GAAD;EAAY,OAAM;YAChB,kBAAC,GAAD;GACE,OAAM;GACN,SAAQ;GACR,eAAe,EAAW,SAAS;GACnC,CAAA;EACS,CAAA;CAIjB,IAAM,IAAI,EAAK,MACT,IAAU,EAAE,WAAW,EAAE,EACzB,IAAW,EAAE,YAAY,EAAE;AAwCjC,QACE,kBAAC,GAAD;EACE,OAAO,EAAE;EACT,aAAa,GAAG,EAAa,EAAE,SAAS,EAAE,SAAS,MAAM,EAAE,WAAW;EACtE,SACE,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAW,SAAS;KACnC,WAAU;eAHZ,CAKE,kBAAC,GAAD,EAAW,WAAU,WAAY,CAAA,EAAA,QAC1B;;IACT,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAW,UAAU,EAAE,GAAG,OAAO;KAChD,WAAU;eAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,QACrB;;IACR,EAAE,WAAW,cACZ,kBAAC,UAAD;KACE,MAAK;KACL,SA7DU,YAAY;AAC3B,YACL,MAAM,EAAY,YAAY,EAAG,EACjC,EAAW,SAAS;;KA2DV,UAAU,EAAY;KACtB,WAAU;eAJZ;MAMG,EAAY,YACX,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,GAE5C,kBAAC,GAAD,EAAS,WAAU,WAAY,CAAA;MAC9B;MAAI;MAEA;;IAEP;;YAlCV;GAsCE,kBAAC,GAAD;IAAW,WAAU;IAAU,WAAU;cAAzC;KACE,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD,EAAa,QAAQ,EAAE,QAAU,CAAA;OAChC,EAAE,YACD,kBAAC,QAAD;QAAM,WAAU;kBAAhB,CAA8C,eAAY,EAAE,SAAgB;;OAE7E,EAAE,aACD,kBAAC,QAAD;QAAM,WAAU;kBAAhB;SACE,kBAAC,GAAD,EAAQ,WAAU,eAAgB,CAAA;;SAAE,EAAE;SACjC;;OAEL;;KACL,EAAE,eAAe,kBAAC,KAAD;MAAG,WAAU;gBAAoC,EAAE;MAAgB,CAAA;KACpF,EAAE,KAAK,SAAS,KACf,kBAAC,OAAD;MAAK,WAAU;gBACZ,EAAE,KAAK,KAAK,MACX,kBAAC,QAAD;OAEE,WAAU;iBAET;OACI,EAJA,EAIA,CACP;MACE,CAAA;KAEE;;GAGZ,kBAAC,WAAD;IAAS,WAAU;cAAnB,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAd;OAAwD;OAAS,EAAQ;OAAO;OAAM;SACtF,kBAAC,UAAD;MACE,MAAK;MACL,eAAe;AAEb,OADA,EAAe,KAAK,EACpB,EAAW,GAAK;;MAElB,WAAU;gBANZ,CAQE,kBAAC,GAAD,EAAU,WAAU,WAAY,CAAA,EAAA,cACzB;QACL;QAEL,EAAQ,WAAW,IAClB,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAU,WAAU,aAAc,CAAA;KACxC,OAAM;KACN,aAAY;KACZ,CAAA,GAEF,kBAAC,GAAD,EAAA,UACE,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAQ,KAAK,MACZ,kBAAC,OAAD;MAAgB,WAAU;gBAA1B;OACE,kBAAC,OAAD;QAAK,WAAU;kBACZ,EAAE,gBAAgB,EAAE,YAAY,OAAO,EAAE,CAAC,aAAa;QACpD,CAAA;OACN,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAE;SACD,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBAAb,CACG,EAAmB,EAAE,OACrB,EAAE,WAAW,MAAM,EAAE,aAAa,GACjC;WACA;;OACN,kBAAC,GAAD,EAAa,QAAQ,EAAE,QAAU,CAAA;OACjC,kBAAC,UAAD;QACE,MAAK;QACL,eAAe,KAAK,EAAa,OAAO,EAAE,GAAG;QAC7C,UAAU,EAAa;QACvB,cAAY,UAAU,EAAE;QACxB,WAAU;kBAEV,kBAAC,GAAD,EAAQ,WAAU,WAAY,CAAA;QACvB,CAAA;OACL;QAvBI,EAAE,GAuBN,CACN;KACE,CAAA,EACQ,CAAA,CAEV;;GAGV,kBAAC,WAAD,EAAA,UAAA,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,MAAD;KAAI,WAAU;eAAd;MAAwD;MAAW,EAAS;MAAO;MAAM;QACzF,kBAAC,UAAD;KACE,MAAK;KACL,eAAe,EAAW,4BAA4B,EAAE,KAAK;KAC7D,WAAU;eAHZ,CAKE,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA,EAAA,YACrB;OACL;OACL,EAAS,WAAW,IACnB,kBAAC,GAAD;IACE,cAAa;IACb,MAAM,kBAAC,GAAD,EAAc,WAAU,aAAc,CAAA;IAC5C,OAAM;IACN,aAAY;IACZ,CAAA,GAEF,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAS,KAAK,MACb,kBAAC,GAAD;KAEE,SAAS;KACT,eAAe,EAAW,aAAa,EAAE,KAAK;KAC9C,EAHK,EAAE,GAGP,CACF;IACE,CAAA,CAEA,EAAA,CAAA;GAGV,kBAAC,GAAD;IAAkB,MAAM;IAAS,cAAc;cAC7C,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,GAAD,EAAA,UACE,kBAAC,GAAD,EAAA,UAAuB,cAAkC,CAAA,EAClC,CAAA,EACzB,kBAAC,QAAD;KAAM,UAjMU,OAAO,MAAuB;AAGpD,UAFA,EAAE,gBAAgB,EAClB,EAAe,KAAK,EAChB,CAAC,EAAI;AACT,UAAI,CAAC,EAAW,OAAO,MAAM,IAAI,CAAC,EAAW,YAAY,MAAM,EAAE;AAC/D,SAAe,yCAAyC;AACxD;;MAEF,IAAM,IAAS,EAAW,aAAa,MAAM,GACzC,OAAO,SAAS,EAAW,cAAc,GAAG,GAC5C,KAAA;AACJ,UAAI,MAAW,KAAA,KAAa,OAAO,MAAM,EAAO,EAAE;AAChD,SAAe,kCAAkC;AACjD;;AAEF,UAAI;AAWF,OAVA,MAAM,EAAU,YAAY;QAC1B,QAAQ;QACR,QAAQ,EAAW,OAAO,MAAM;QAChC,aAAa,EAAW,YAAY,MAAM;QAC1C,MAAM,EAAW;QACjB,QAAQ,EAAW;QACnB,UAAU,EAAW,SAAS,MAAM,IAAI,KAAA;QACxC,cAAc;QACf,CAAC,EACF,EAAc,EAAa,EAC3B,EAAW,GAAM;eACV,GAAK;AACZ,SAAe,aAAe,QAAQ,EAAI,UAAU,wBAAwB;;;KAqKvC,WAAU;eAA3C;MACE,kBAAC,GAAD;OAAW,OAAM;OAAU,SAAQ;OAAS,UAAA;OAAS,MAAK;iBACxD,kBAAC,SAAD;QACE,IAAG;QACH,WAAW;QACX,OAAO,EAAW;QAClB,WAAW,MACT,GAAe,OAAO;SAAE,GAAG;SAAG,QAAQ,EAAE,OAAO;SAAO,EAAE;QAE1D,aAAY;QACZ,CAAA;OACQ,CAAA;MACZ,kBAAC,GAAD;OAAW,OAAM;OAAe,SAAQ;OAAc,UAAA;iBACpD,kBAAC,SAAD;QACE,IAAG;QACH,WAAW;QACX,OAAO,EAAW;QAClB,WAAW,MACT,GAAe,OAAO;SAAE,GAAG;SAAG,aAAa,EAAE,OAAO;SAAO,EAAE;QAE/D,aAAY;QACZ,CAAA;OACQ,CAAA;MACZ,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QAAW,OAAM;QAAO,SAAQ;kBAC9B,kBAAC,UAAD;SACE,IAAG;SACH,WAAW;SACX,OAAO,EAAW;SAClB,WAAW,MACT,GAAe,OAAO;UAAE,GAAG;UAAG,MAAM,EAAE,OAAO;UAAwB,EAAE;mBAGxE,EAAM,KAAK,MACV,kBAAC,UAAD;UAAgB,OAAO;oBACpB,EAAmB;UACb,EAFI,EAEJ,CACT;SACK,CAAA;QACC,CAAA,EACZ,kBAAC,GAAD;QAAW,OAAM;QAAS,SAAQ;kBAChC,kBAAC,UAAD;SACE,IAAG;SACH,WAAW;SACX,OAAO,EAAW;SAClB,WAAW,MACT,GAAe,OAAO;UAAE,GAAG;UAAG,QAAQ,EAAE,OAAO;UAA0B,EAAE;mBAG5E,EAAgB,KAAK,MACpB,kBAAC,UAAD;UAAgB,OAAO;oBACpB,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,aAAa;UAChC,EAFI,EAEJ,CACT;SACK,CAAA;QACC,CAAA,CACR;;MACN,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QAAW,OAAM;QAAW,SAAQ;kBAClC,kBAAC,SAAD;SACE,IAAG;SACH,WAAW;SACX,OAAO,EAAW;SAClB,WAAW,MACT,GAAe,OAAO;UAAE,GAAG;UAAG,UAAU,EAAE,OAAO;UAAO,EAAE;SAE5D,aAAY;SACZ,CAAA;QACQ,CAAA,EACZ,kBAAC,GAAD;QAAW,OAAM;QAAW,SAAQ;kBAClC,kBAAC,SAAD;SACE,IAAG;SACH,WAAW;SACX,WAAU;SACV,OAAO,EAAW;SAClB,WAAW,MACT,GAAe,OAAO;UAAE,GAAG;UAAG,cAAc,EAAE,OAAO;UAAO,EAAE;SAEhE,aAAY;SACZ,CAAA;QACQ,CAAA,CACR;;MACL,KAAe,kBAAC,KAAD;OAAG,WAAU;iBAAkC;OAAgB,CAAA;MAC/E,kBAAC,GAAD,EAAA,UAAA,CACE,kBAAC,UAAD;OACE,MAAK;OACL,eAAe,EAAW,GAAM;OAChC,WAAU;iBACX;OAEQ,CAAA,EACT,kBAAC,UAAD;OACE,MAAK;OACL,UAAU,EAAU;OACpB,WAAU;iBAHZ,CAKG,EAAU,aAAa,kBAAC,GAAD,EAAS,WAAU,wBAAyB,CAAA,EAAC,aAE9D;SACc,EAAA,CAAA;MACpB;OACiB,EAAA,CAAA;IACT,CAAA;GACR"}