@jmruthers/pace-core 0.6.1 → 0.6.3

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 (549) hide show
  1. package/CHANGELOG.md +88 -10
  2. package/cursor-rules/00-pace-core-compliance.mdc +46 -87
  3. package/cursor-rules/01-standards-compliance.mdc +16 -47
  4. package/cursor-rules/02-project-structure.mdc +4 -4
  5. package/cursor-rules/03-solid-principles.mdc +45 -164
  6. package/cursor-rules/04-testing-standards.mdc +22 -69
  7. package/cursor-rules/05-bug-reports-and-features.mdc +2 -2
  8. package/cursor-rules/06-code-quality.mdc +42 -125
  9. package/cursor-rules/07-tech-stack-compliance.mdc +33 -128
  10. package/cursor-rules/08-markup-quality.mdc +452 -0
  11. package/cursor-rules/CHANGELOG.md +18 -0
  12. package/cursor-rules/README.md +2 -1
  13. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-Cb34EQs3.d.ts} +63 -1
  14. package/dist/{DataTable-CH1U5Tpy.d.ts → DataTable-BMRU8a1j.d.ts} +33 -1
  15. package/dist/{DataTable-DQ7RSOHE.js → DataTable-THFPBKTP.js} +12 -10
  16. package/dist/{PublicPageProvider-ce4xlHYA.d.ts → PublicPageProvider-DEMpysFR.d.ts} +394 -171
  17. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CKvHP1MK.d.ts} +30 -8
  18. package/dist/{UnifiedAuthProvider-ATAP5UTR.js → UnifiedAuthProvider-KAGUYQ4J.js} +5 -4
  19. package/dist/{api-N774RPUA.js → api-IAGWF3ZG.js} +10 -10
  20. package/dist/{audit-B5P6FFIR.js → audit-V53FV5AG.js} +2 -2
  21. package/dist/{chunk-JBKQ3SAO.js → chunk-2T2IG7T7.js} +107 -57
  22. package/dist/chunk-2T2IG7T7.js.map +1 -0
  23. package/dist/{chunk-3QRJFVBR.js → chunk-6SOIHG6Z.js} +1 -1
  24. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  25. package/dist/{chunk-3XTALGJF.js → chunk-6Z7LTB3D.js} +69 -240
  26. package/dist/chunk-6Z7LTB3D.js.map +1 -0
  27. package/dist/{chunk-4ZC4GX36.js → chunk-CNCQDFLN.js} +199 -46
  28. package/dist/chunk-CNCQDFLN.js.map +1 -0
  29. package/dist/chunk-DGUM43GV.js +11 -0
  30. package/dist/{chunk-BYFSK72L.js → chunk-DWUBLJJM.js} +361 -187
  31. package/dist/chunk-DWUBLJJM.js.map +1 -0
  32. package/dist/{chunk-LXQLPRQ2.js → chunk-FFQEQTNW.js} +6 -8
  33. package/dist/chunk-FFQEQTNW.js.map +1 -0
  34. package/dist/chunk-FMUCXFII.js +76 -0
  35. package/dist/chunk-FMUCXFII.js.map +1 -0
  36. package/dist/{chunk-4N5C5XZU.js → chunk-HFZBI76P.js} +4 -4
  37. package/dist/chunk-HFZBI76P.js.map +1 -0
  38. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  39. package/dist/chunk-L4OXEN46.js.map +1 -0
  40. package/dist/{chunk-R77UEZ4E.js → chunk-M43Y4SSO.js} +1 -1
  41. package/dist/chunk-M43Y4SSO.js.map +1 -0
  42. package/dist/{chunk-I7PSE6JW.js → chunk-M7MPQISP.js} +3 -76
  43. package/dist/chunk-M7MPQISP.js.map +1 -0
  44. package/dist/chunk-PQBSKX33.js +7793 -0
  45. package/dist/chunk-PQBSKX33.js.map +1 -0
  46. package/dist/chunk-QRPVRXYT.js +226 -0
  47. package/dist/chunk-QRPVRXYT.js.map +1 -0
  48. package/dist/{chunk-KNC55RTG.js → chunk-RWEBCB47.js} +194 -416
  49. package/dist/chunk-RWEBCB47.js.map +1 -0
  50. package/dist/{chunk-XM25TVIE.js → chunk-YDQHOZNA.js} +843 -388
  51. package/dist/chunk-YDQHOZNA.js.map +1 -0
  52. package/dist/{chunk-GLK6VM3F.js → chunk-ZNIWI3UC.js} +739 -737
  53. package/dist/chunk-ZNIWI3UC.js.map +1 -0
  54. package/dist/components.d.ts +5 -5
  55. package/dist/components.js +18 -16
  56. package/dist/components.js.map +1 -1
  57. package/dist/contextValidator-3JNZKUTX.js +9 -0
  58. package/dist/contextValidator-3JNZKUTX.js.map +1 -0
  59. package/dist/eslint-rules/pace-core-compliance.cjs +106 -0
  60. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  61. package/dist/hooks.d.ts +55 -122
  62. package/dist/hooks.js +10 -13
  63. package/dist/hooks.js.map +1 -1
  64. package/dist/index.d.ts +60 -13
  65. package/dist/index.js +30 -25
  66. package/dist/index.js.map +1 -1
  67. package/dist/providers.d.ts +21 -3
  68. package/dist/providers.js +4 -3
  69. package/dist/rbac/index.d.ts +210 -139
  70. package/dist/rbac/index.js +17 -13
  71. package/dist/styles/index.js +1 -1
  72. package/dist/theming/runtime.d.ts +1 -13
  73. package/dist/theming/runtime.js +2 -2
  74. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  75. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  76. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  77. package/dist/types.d.ts +2 -2
  78. package/dist/types.js +1 -1
  79. package/dist/{usePublicRouteParams-BJAlWfuJ.d.ts → usePublicRouteParams-i3qtoBgg.d.ts} +38 -17
  80. package/dist/utils.d.ts +4 -5
  81. package/dist/utils.js +17 -19
  82. package/dist/utils.js.map +1 -1
  83. package/docs/api/README.md +21 -17
  84. package/docs/api/modules.md +4191 -2967
  85. package/docs/architecture/database-schema-requirements.md +161 -0
  86. package/docs/components/context-selector.md +126 -0
  87. package/docs/core-concepts/rbac-system.md +3 -3
  88. package/docs/documentation-index.md +2 -4
  89. package/docs/getting-started/cursor-rules.md +2 -1
  90. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  91. package/docs/migration/MIGRATION_GUIDE.md +2 -24
  92. package/docs/migration/RBAC_SCOPE_MIGRATION.md +385 -0
  93. package/docs/migration/README.md +52 -6
  94. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  95. package/docs/migration/database-changes-december-2025.md +3 -3
  96. package/docs/pace-mint-fix-auto-selection.md +218 -0
  97. package/docs/pace-mint-rbac-setup.md +391 -0
  98. package/docs/rbac/event-based-apps.md +1 -1
  99. package/docs/rbac/getting-started.md +1 -1
  100. package/docs/rbac/quick-start.md +1 -1
  101. package/docs/rbac/secure-client-protection.md +330 -0
  102. package/docs/standards/README.md +1 -0
  103. package/package.json +4 -3
  104. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  105. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  106. package/scripts/audit/core/checks/bundle.cjs +142 -0
  107. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +784 -685
  108. package/scripts/audit/core/checks/config.cjs +54 -0
  109. package/scripts/audit/core/checks/coverage.cjs +84 -0
  110. package/scripts/audit/core/checks/dependencies.cjs +985 -0
  111. package/scripts/audit/core/checks/documentation.cjs +268 -0
  112. package/scripts/audit/core/checks/environment.cjs +116 -0
  113. package/scripts/audit/core/checks/error-handling.cjs +340 -0
  114. package/scripts/audit/core/checks/forms.cjs +172 -0
  115. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  116. package/scripts/audit/core/checks/hooks.cjs +334 -0
  117. package/scripts/audit/core/checks/imports.cjs +244 -0
  118. package/scripts/audit/core/checks/performance.cjs +325 -0
  119. package/scripts/audit/core/checks/routes.cjs +117 -0
  120. package/scripts/audit/core/checks/state.cjs +130 -0
  121. package/scripts/audit/core/checks/structure.cjs +65 -0
  122. package/scripts/audit/core/checks/style.cjs +584 -0
  123. package/scripts/audit/core/checks/testing.cjs +122 -0
  124. package/scripts/audit/core/checks/typescript.cjs +61 -0
  125. package/scripts/audit/core/scanner.cjs +199 -0
  126. package/scripts/audit/core/utils.cjs +137 -0
  127. package/scripts/audit/index.cjs +223 -0
  128. package/scripts/audit/reporters/console.cjs +151 -0
  129. package/scripts/audit/reporters/json.cjs +54 -0
  130. package/scripts/audit/reporters/markdown.cjs +124 -0
  131. package/scripts/audit-consuming-app.cjs +61 -936
  132. package/scripts/build-docs/build-decision.js +240 -0
  133. package/scripts/build-docs/cache-utils.js +105 -0
  134. package/scripts/build-docs/content-normalization.js +150 -0
  135. package/scripts/build-docs/file-utils.js +105 -0
  136. package/scripts/build-docs/git-utils.js +86 -0
  137. package/scripts/build-docs/hash-utils.js +116 -0
  138. package/scripts/build-docs/typedoc-runner.js +220 -0
  139. package/scripts/build-docs-incremental.js +77 -913
  140. package/scripts/utils/command-runner.js +16 -11
  141. package/scripts/validate-formats.js +61 -56
  142. package/scripts/validate-master.js +74 -69
  143. package/scripts/validate-pre-publish.js +70 -65
  144. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  145. package/src/components/Alert/Alert.test.tsx +12 -18
  146. package/src/components/Alert/Alert.tsx +5 -7
  147. package/src/components/Avatar/Avatar.test.tsx +4 -4
  148. package/src/components/Badge/Badge.tsx +14 -0
  149. package/src/components/Button/Button.tsx +22 -0
  150. package/src/components/Calendar/Calendar.tsx +8 -2
  151. package/src/components/Card/Card.tsx +4 -0
  152. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  153. package/src/components/Checkbox/Checkbox.tsx +2 -2
  154. package/src/components/ContextSelector/ContextSelector.tsx +384 -0
  155. package/src/components/ContextSelector/index.ts +3 -0
  156. package/src/components/DataTable/DataTable.tsx +38 -4
  157. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  158. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +18 -4
  159. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  160. package/src/components/DataTable/components/AccessDeniedPage.tsx +16 -25
  161. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  162. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
  163. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  164. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  165. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  166. package/src/components/DataTable/components/DataTableCore.tsx +196 -554
  167. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  168. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  169. package/src/components/DataTable/components/DataTableModals.tsx +8 -0
  170. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  171. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  172. package/src/components/DataTable/components/EditFields.tsx +307 -0
  173. package/src/components/DataTable/components/EditableRow.tsx +8 -0
  174. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  175. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  176. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  177. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  178. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  179. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  180. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  181. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  182. package/src/components/DataTable/components/UnifiedTableBody.tsx +63 -851
  183. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  184. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  185. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  186. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  187. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  188. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  189. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  190. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  191. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  192. package/src/components/DataTable/hooks/useColumnReordering.ts +12 -0
  193. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  194. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  195. package/src/components/DataTable/hooks/useDataTablePermissions.ts +127 -33
  196. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  197. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  198. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  199. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  200. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  201. package/src/components/DataTable/styles.ts +6 -6
  202. package/src/components/DataTable/types.ts +6 -10
  203. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  204. package/src/components/DataTable/utils/debugTools.ts +18 -113
  205. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  206. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  207. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  208. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  209. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  210. package/src/components/Dialog/Dialog.tsx +31 -3
  211. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  212. package/src/components/ErrorBoundary/ErrorBoundary.tsx +45 -5
  213. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  214. package/src/components/ErrorBoundary/index.ts +27 -2
  215. package/src/components/FileDisplay/FileDisplay.tsx +74 -28
  216. package/src/components/FileUpload/FileUpload.tsx +22 -2
  217. package/src/components/Footer/Footer.test.tsx +16 -16
  218. package/src/components/Footer/Footer.tsx +14 -11
  219. package/src/components/Form/Form.tsx +1 -0
  220. package/src/components/Header/Header.test.tsx +43 -73
  221. package/src/components/Header/Header.tsx +59 -49
  222. package/src/components/Input/Input.test.tsx +2 -2
  223. package/src/components/Input/Input.tsx +8 -4
  224. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  225. package/src/components/LoginForm/LoginForm.tsx +4 -0
  226. package/src/components/NavigationMenu/NavigationMenu.tsx +14 -513
  227. package/src/components/NavigationMenu/types.ts +56 -0
  228. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  229. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +10 -19
  230. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +2 -2
  231. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +5 -5
  232. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +13 -11
  233. package/src/components/PaceAppLayout/PaceAppLayout.tsx +167 -44
  234. package/src/components/PaceAppLayout/README.md +14 -17
  235. package/src/components/PaceAppLayout/test-setup.tsx +3 -4
  236. package/src/components/PaceLoginPage/PaceLoginPage.tsx +3 -0
  237. package/src/components/PasswordChange/PasswordChangeForm.tsx +9 -0
  238. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  239. package/src/components/PublicLayout/PublicPageLayout.tsx +2 -5
  240. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  241. package/src/components/Select/Select.tsx +80 -434
  242. package/src/components/Select/context.ts +23 -0
  243. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  244. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  245. package/src/components/Select/hooks/useSelectState.ts +104 -0
  246. package/src/components/Select/index.ts +9 -1
  247. package/src/components/Select/types.ts +123 -0
  248. package/src/components/Select/utils/text.ts +26 -0
  249. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +4 -5
  250. package/src/components/Switch/Switch.tsx +4 -4
  251. package/src/components/Tabs/Tabs.tsx +1 -1
  252. package/src/components/Toast/Toast.tsx +4 -0
  253. package/src/components/Tooltip/Tooltip.tsx +2 -2
  254. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  255. package/src/components/UserMenu/UserMenu.tsx +21 -18
  256. package/src/components/index.ts +7 -7
  257. package/src/eslint-rules/pace-core-compliance.cjs +106 -0
  258. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  259. package/src/hooks/__tests__/useAppConfig.unit.test.ts +4 -98
  260. package/src/hooks/index.ts +1 -2
  261. package/src/hooks/public/usePublicEvent.ts +4 -0
  262. package/src/hooks/public/usePublicEventLogo.ts +4 -0
  263. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  264. package/src/hooks/public/usePublicRouteParams.ts +4 -0
  265. package/src/hooks/services/useAuth.ts +32 -0
  266. package/src/hooks/services/useCurrentEvent.ts +6 -0
  267. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  268. package/src/hooks/useAppConfig.ts +15 -30
  269. package/src/hooks/useDebounce.ts +9 -0
  270. package/src/hooks/useEventTheme.ts +6 -0
  271. package/src/hooks/useFileDisplay.ts +81 -50
  272. package/src/hooks/useFileReference.ts +25 -7
  273. package/src/hooks/useFileUrl.ts +11 -1
  274. package/src/hooks/useFocusManagement.ts +14 -0
  275. package/src/hooks/useFocusTrap.ts +3 -0
  276. package/src/hooks/useInactivityTracker.ts +3 -0
  277. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  278. package/src/hooks/useOrganisationPermissions.ts +4 -0
  279. package/src/hooks/useOrganisationSecurity.ts +4 -0
  280. package/src/hooks/usePerformanceMonitor.ts +4 -0
  281. package/src/hooks/usePermissionCache.ts +7 -0
  282. package/src/hooks/useQueryCache.ts +12 -1
  283. package/src/hooks/useSessionRestoration.ts +4 -0
  284. package/src/hooks/useStorage.ts +4 -0
  285. package/src/hooks/useToast.ts +1 -1
  286. package/src/index.ts +6 -6
  287. package/src/providers/__tests__/OrganisationProvider.test.tsx +92 -70
  288. package/src/providers/services/AuthServiceProvider.tsx +35 -7
  289. package/src/providers/services/EventServiceProvider.tsx +51 -5
  290. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  291. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  292. package/src/providers/services/UnifiedAuthProvider.tsx +126 -134
  293. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +29 -13
  294. package/src/rbac/README.md +1 -1
  295. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +1 -1
  296. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  297. package/src/rbac/adapters.tsx +12 -3
  298. package/src/rbac/api.test.ts +59 -51
  299. package/src/rbac/api.ts +246 -167
  300. package/src/rbac/components/NavigationProvider.tsx +4 -1
  301. package/src/rbac/components/PagePermissionGuard.tsx +185 -17
  302. package/src/rbac/components/RoleBasedRouter.tsx +5 -1
  303. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  304. package/src/rbac/components/SecureDataProvider.tsx +20 -5
  305. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  306. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  307. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  308. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  309. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  310. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  311. package/src/rbac/engine.ts +38 -14
  312. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +32 -21
  313. package/src/rbac/hooks/permissions/index.ts +7 -0
  314. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  315. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  316. package/src/rbac/hooks/permissions/useCan.ts +377 -0
  317. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  318. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  319. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  320. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  321. package/src/rbac/hooks/useCan.test.ts +64 -66
  322. package/src/rbac/hooks/usePermissions.ts +14 -995
  323. package/src/rbac/hooks/useRBAC.test.ts +1 -5
  324. package/src/rbac/hooks/useRBAC.ts +36 -37
  325. package/src/rbac/hooks/useResolvedScope.test.ts +120 -35
  326. package/src/rbac/hooks/useResolvedScope.ts +35 -40
  327. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  328. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  329. package/src/rbac/hooks/useSecureSupabase.ts +27 -7
  330. package/src/rbac/index.ts +7 -0
  331. package/src/rbac/permissions.ts +0 -30
  332. package/src/rbac/secureClient.test.ts +22 -18
  333. package/src/rbac/secureClient.ts +294 -68
  334. package/src/rbac/security.ts +0 -17
  335. package/src/rbac/types.ts +9 -0
  336. package/src/rbac/utils/__tests__/contextValidator.test.ts +64 -86
  337. package/src/rbac/utils/clientSecurity.ts +93 -0
  338. package/src/rbac/utils/contextValidator.ts +77 -168
  339. package/src/services/AuthService.ts +39 -7
  340. package/src/services/EventService.ts +186 -54
  341. package/src/services/OrganisationService.ts +81 -14
  342. package/src/services/__tests__/EventService.test.ts +1 -2
  343. package/src/services/base/BaseService.ts +3 -0
  344. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  345. package/src/theming/parseEventColours.ts +5 -19
  346. package/src/types/vitest-globals.d.ts +51 -26
  347. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  348. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  349. package/src/utils/__tests__/index.unit.test.ts +2 -2
  350. package/src/utils/audit/audit.ts +0 -3
  351. package/src/utils/core/cn.ts +1 -1
  352. package/src/utils/dynamic/dynamicUtils.ts +7 -4
  353. package/src/utils/file-reference/index.ts +53 -1
  354. package/src/utils/formatting/formatting.ts +8 -18
  355. package/src/utils/index.ts +0 -1
  356. package/dist/chunk-3QRJFVBR.js.map +0 -1
  357. package/dist/chunk-3XTALGJF.js.map +0 -1
  358. package/dist/chunk-4N5C5XZU.js.map +0 -1
  359. package/dist/chunk-4ZC4GX36.js.map +0 -1
  360. package/dist/chunk-7D4SUZUM.js +0 -38
  361. package/dist/chunk-BYFSK72L.js.map +0 -1
  362. package/dist/chunk-EXUD6RNJ.js +0 -451
  363. package/dist/chunk-EXUD6RNJ.js.map +0 -1
  364. package/dist/chunk-GLK6VM3F.js.map +0 -1
  365. package/dist/chunk-I7PSE6JW.js.map +0 -1
  366. package/dist/chunk-JBKQ3SAO.js.map +0 -1
  367. package/dist/chunk-KNC55RTG.js.map +0 -1
  368. package/dist/chunk-LXQLPRQ2.js.map +0 -1
  369. package/dist/chunk-R77UEZ4E.js.map +0 -1
  370. package/dist/chunk-SQGMNID3.js.map +0 -1
  371. package/dist/chunk-T33XF5ZC.js +0 -12922
  372. package/dist/chunk-T33XF5ZC.js.map +0 -1
  373. package/dist/chunk-XM25TVIE.js.map +0 -1
  374. package/docs/api/classes/ColumnFactory.md +0 -243
  375. package/docs/api/classes/ErrorBoundary.md +0 -144
  376. package/docs/api/classes/InvalidScopeError.md +0 -73
  377. package/docs/api/classes/Logger.md +0 -178
  378. package/docs/api/classes/MissingUserContextError.md +0 -66
  379. package/docs/api/classes/OrganisationContextRequiredError.md +0 -66
  380. package/docs/api/classes/PermissionDeniedError.md +0 -73
  381. package/docs/api/classes/RBACAuditManager.md +0 -297
  382. package/docs/api/classes/RBACCache.md +0 -322
  383. package/docs/api/classes/RBACEngine.md +0 -171
  384. package/docs/api/classes/RBACError.md +0 -76
  385. package/docs/api/classes/RBACNotInitializedError.md +0 -66
  386. package/docs/api/classes/SecureSupabaseClient.md +0 -160
  387. package/docs/api/classes/StorageUtils.md +0 -328
  388. package/docs/api/enums/FileCategory.md +0 -184
  389. package/docs/api/enums/LogLevel.md +0 -54
  390. package/docs/api/enums/RBACErrorCode.md +0 -228
  391. package/docs/api/enums/RPCFunction.md +0 -118
  392. package/docs/api/interfaces/AddressFieldProps.md +0 -241
  393. package/docs/api/interfaces/AddressFieldRef.md +0 -94
  394. package/docs/api/interfaces/AggregateConfig.md +0 -43
  395. package/docs/api/interfaces/AutocompleteOptions.md +0 -75
  396. package/docs/api/interfaces/AvatarProps.md +0 -128
  397. package/docs/api/interfaces/BadgeProps.md +0 -27
  398. package/docs/api/interfaces/ButtonProps.md +0 -53
  399. package/docs/api/interfaces/CalendarProps.md +0 -70
  400. package/docs/api/interfaces/CardProps.md +0 -66
  401. package/docs/api/interfaces/ColorPalette.md +0 -7
  402. package/docs/api/interfaces/ColorShade.md +0 -66
  403. package/docs/api/interfaces/ComplianceResult.md +0 -30
  404. package/docs/api/interfaces/DataAccessRecord.md +0 -96
  405. package/docs/api/interfaces/DataRecord.md +0 -11
  406. package/docs/api/interfaces/DataTableAction.md +0 -249
  407. package/docs/api/interfaces/DataTableColumn.md +0 -504
  408. package/docs/api/interfaces/DataTableProps.md +0 -625
  409. package/docs/api/interfaces/DataTableToolbarButton.md +0 -96
  410. package/docs/api/interfaces/DatabaseComplianceResult.md +0 -85
  411. package/docs/api/interfaces/DatabaseIssue.md +0 -41
  412. package/docs/api/interfaces/EmptyStateConfig.md +0 -61
  413. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +0 -235
  414. package/docs/api/interfaces/EventAppRoleData.md +0 -71
  415. package/docs/api/interfaces/ExportColumn.md +0 -90
  416. package/docs/api/interfaces/ExportOptions.md +0 -126
  417. package/docs/api/interfaces/FileDisplayProps.md +0 -249
  418. package/docs/api/interfaces/FileMetadata.md +0 -129
  419. package/docs/api/interfaces/FileReference.md +0 -118
  420. package/docs/api/interfaces/FileSizeLimits.md +0 -7
  421. package/docs/api/interfaces/FileUploadOptions.md +0 -139
  422. package/docs/api/interfaces/FileUploadProps.md +0 -293
  423. package/docs/api/interfaces/FooterProps.md +0 -105
  424. package/docs/api/interfaces/FormFieldProps.md +0 -166
  425. package/docs/api/interfaces/FormProps.md +0 -113
  426. package/docs/api/interfaces/GrantEventAppRoleParams.md +0 -122
  427. package/docs/api/interfaces/InactivityWarningModalProps.md +0 -115
  428. package/docs/api/interfaces/InputProps.md +0 -53
  429. package/docs/api/interfaces/LabelProps.md +0 -107
  430. package/docs/api/interfaces/LoggerConfig.md +0 -62
  431. package/docs/api/interfaces/LoginFormProps.md +0 -184
  432. package/docs/api/interfaces/NavigationAccessRecord.md +0 -107
  433. package/docs/api/interfaces/NavigationContextType.md +0 -164
  434. package/docs/api/interfaces/NavigationGuardProps.md +0 -139
  435. package/docs/api/interfaces/NavigationItem.md +0 -120
  436. package/docs/api/interfaces/NavigationMenuProps.md +0 -221
  437. package/docs/api/interfaces/NavigationProviderProps.md +0 -117
  438. package/docs/api/interfaces/Organisation.md +0 -140
  439. package/docs/api/interfaces/OrganisationContextType.md +0 -388
  440. package/docs/api/interfaces/OrganisationMembership.md +0 -140
  441. package/docs/api/interfaces/OrganisationProviderProps.md +0 -76
  442. package/docs/api/interfaces/OrganisationSecurityError.md +0 -62
  443. package/docs/api/interfaces/PaceAppLayoutProps.md +0 -406
  444. package/docs/api/interfaces/PaceLoginPageProps.md +0 -47
  445. package/docs/api/interfaces/PageAccessRecord.md +0 -85
  446. package/docs/api/interfaces/PagePermissionContextType.md +0 -140
  447. package/docs/api/interfaces/PagePermissionGuardProps.md +0 -153
  448. package/docs/api/interfaces/PagePermissionProviderProps.md +0 -119
  449. package/docs/api/interfaces/PaletteData.md +0 -41
  450. package/docs/api/interfaces/ParsedAddress.md +0 -120
  451. package/docs/api/interfaces/PermissionEnforcerProps.md +0 -153
  452. package/docs/api/interfaces/ProgressProps.md +0 -42
  453. package/docs/api/interfaces/ProtectedRouteProps.md +0 -97
  454. package/docs/api/interfaces/PublicPageFooterProps.md +0 -112
  455. package/docs/api/interfaces/PublicPageHeaderProps.md +0 -125
  456. package/docs/api/interfaces/PublicPageLayoutProps.md +0 -198
  457. package/docs/api/interfaces/QuickFix.md +0 -52
  458. package/docs/api/interfaces/RBACAccessValidateParams.md +0 -52
  459. package/docs/api/interfaces/RBACAccessValidateResult.md +0 -41
  460. package/docs/api/interfaces/RBACAuditLogParams.md +0 -85
  461. package/docs/api/interfaces/RBACAuditLogResult.md +0 -52
  462. package/docs/api/interfaces/RBACConfig.md +0 -133
  463. package/docs/api/interfaces/RBACContext.md +0 -52
  464. package/docs/api/interfaces/RBACLogger.md +0 -112
  465. package/docs/api/interfaces/RBACPageAccessCheckParams.md +0 -74
  466. package/docs/api/interfaces/RBACPerformanceMetrics.md +0 -138
  467. package/docs/api/interfaces/RBACPermissionCheckParams.md +0 -74
  468. package/docs/api/interfaces/RBACPermissionCheckResult.md +0 -52
  469. package/docs/api/interfaces/RBACPermissionsGetParams.md +0 -63
  470. package/docs/api/interfaces/RBACPermissionsGetResult.md +0 -63
  471. package/docs/api/interfaces/RBACResult.md +0 -58
  472. package/docs/api/interfaces/RBACRoleGrantParams.md +0 -63
  473. package/docs/api/interfaces/RBACRoleGrantResult.md +0 -52
  474. package/docs/api/interfaces/RBACRoleRevokeParams.md +0 -63
  475. package/docs/api/interfaces/RBACRoleRevokeResult.md +0 -52
  476. package/docs/api/interfaces/RBACRoleValidateParams.md +0 -52
  477. package/docs/api/interfaces/RBACRoleValidateResult.md +0 -63
  478. package/docs/api/interfaces/RBACRolesListParams.md +0 -52
  479. package/docs/api/interfaces/RBACRolesListResult.md +0 -74
  480. package/docs/api/interfaces/RBACSessionTrackParams.md +0 -74
  481. package/docs/api/interfaces/RBACSessionTrackResult.md +0 -52
  482. package/docs/api/interfaces/ResourcePermissions.md +0 -155
  483. package/docs/api/interfaces/RevokeEventAppRoleParams.md +0 -100
  484. package/docs/api/interfaces/RoleBasedRouterContextType.md +0 -151
  485. package/docs/api/interfaces/RoleBasedRouterProps.md +0 -156
  486. package/docs/api/interfaces/RoleManagementResult.md +0 -52
  487. package/docs/api/interfaces/RouteAccessRecord.md +0 -107
  488. package/docs/api/interfaces/RouteConfig.md +0 -134
  489. package/docs/api/interfaces/RuntimeComplianceResult.md +0 -55
  490. package/docs/api/interfaces/SecureDataContextType.md +0 -168
  491. package/docs/api/interfaces/SecureDataProviderProps.md +0 -132
  492. package/docs/api/interfaces/SessionRestorationLoaderProps.md +0 -34
  493. package/docs/api/interfaces/SetupIssue.md +0 -41
  494. package/docs/api/interfaces/StorageConfig.md +0 -41
  495. package/docs/api/interfaces/StorageFileInfo.md +0 -74
  496. package/docs/api/interfaces/StorageFileMetadata.md +0 -151
  497. package/docs/api/interfaces/StorageListOptions.md +0 -99
  498. package/docs/api/interfaces/StorageListResult.md +0 -41
  499. package/docs/api/interfaces/StorageUploadOptions.md +0 -101
  500. package/docs/api/interfaces/StorageUploadResult.md +0 -63
  501. package/docs/api/interfaces/StorageUrlOptions.md +0 -60
  502. package/docs/api/interfaces/StyleImport.md +0 -19
  503. package/docs/api/interfaces/SwitchProps.md +0 -34
  504. package/docs/api/interfaces/TabsContentProps.md +0 -9
  505. package/docs/api/interfaces/TabsListProps.md +0 -9
  506. package/docs/api/interfaces/TabsProps.md +0 -9
  507. package/docs/api/interfaces/TabsTriggerProps.md +0 -50
  508. package/docs/api/interfaces/TextareaProps.md +0 -53
  509. package/docs/api/interfaces/ToastActionElement.md +0 -9
  510. package/docs/api/interfaces/ToastProps.md +0 -9
  511. package/docs/api/interfaces/UnifiedAuthContextType.md +0 -820
  512. package/docs/api/interfaces/UnifiedAuthProviderProps.md +0 -171
  513. package/docs/api/interfaces/UseFormDialogOptions.md +0 -62
  514. package/docs/api/interfaces/UseFormDialogReturn.md +0 -117
  515. package/docs/api/interfaces/UseInactivityTrackerOptions.md +0 -136
  516. package/docs/api/interfaces/UseInactivityTrackerReturn.md +0 -123
  517. package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
  518. package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -81
  519. package/docs/api/interfaces/UsePublicEventOptions.md +0 -34
  520. package/docs/api/interfaces/UsePublicEventReturn.md +0 -68
  521. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +0 -47
  522. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +0 -120
  523. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +0 -94
  524. package/docs/api/interfaces/UseResolvedScopeOptions.md +0 -47
  525. package/docs/api/interfaces/UseResolvedScopeReturn.md +0 -47
  526. package/docs/api/interfaces/UseResourcePermissionsOptions.md +0 -34
  527. package/docs/api/interfaces/UserEventAccess.md +0 -118
  528. package/docs/api/interfaces/UserMenuProps.md +0 -86
  529. package/docs/api/interfaces/UserProfile.md +0 -63
  530. package/docs/migration/quick-migration-guide.md +0 -356
  531. package/docs/migration/service-architecture.md +0 -281
  532. package/src/components/EventSelector/EventSelector.test.tsx +0 -720
  533. package/src/components/EventSelector/EventSelector.tsx +0 -420
  534. package/src/components/EventSelector/index.ts +0 -3
  535. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +0 -784
  536. package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -324
  537. package/src/components/OrganisationSelector/index.ts +0 -9
  538. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  539. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  540. package/src/hooks/useSecureDataAccess.ts +0 -681
  541. /package/dist/{DataTable-DQ7RSOHE.js.map → DataTable-THFPBKTP.js.map} +0 -0
  542. /package/dist/{UnifiedAuthProvider-ATAP5UTR.js.map → UnifiedAuthProvider-KAGUYQ4J.js.map} +0 -0
  543. /package/dist/{api-N774RPUA.js.map → api-IAGWF3ZG.js.map} +0 -0
  544. /package/dist/{audit-B5P6FFIR.js.map → audit-V53FV5AG.js.map} +0 -0
  545. /package/dist/{chunk-7D4SUZUM.js.map → chunk-DGUM43GV.js.map} +0 -0
  546. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  547. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  548. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  549. /package/docs/migration/{REACT_19_MIGRATION.md → V0.6.0_REACT_19_MIGRATION.md} +0 -0
@@ -20,17 +20,19 @@ import {
20
20
  Input,
21
21
  Select,
22
22
  SelectContent,
23
+ SelectGroup,
23
24
  SelectItem,
24
25
  SelectLabel,
25
26
  SelectSeparator,
26
27
  SelectTrigger,
27
28
  SelectValue
28
- } from "./chunk-T33XF5ZC.js";
29
+ } from "./chunk-PQBSKX33.js";
29
30
  import {
30
31
  useCan,
31
32
  usePermissions,
32
- useRBAC
33
- } from "./chunk-XM25TVIE.js";
33
+ useRBAC,
34
+ useResolvedScope
35
+ } from "./chunk-YDQHOZNA.js";
34
36
  import {
35
37
  createFileReferenceService,
36
38
  generateFileUrlsBatch,
@@ -42,27 +44,26 @@ import {
42
44
  useFileDisplay,
43
45
  usePreventTabReload,
44
46
  usePublicFileDisplay
45
- } from "./chunk-JBKQ3SAO.js";
47
+ } from "./chunk-2T2IG7T7.js";
46
48
  import {
47
49
  useToast
48
- } from "./chunk-3QRJFVBR.js";
50
+ } from "./chunk-6SOIHG6Z.js";
49
51
  import {
50
52
  ErrorBoundary,
51
53
  PublicPageContext,
52
54
  useAppConfig,
53
55
  useEvents,
54
- useIsPublicPage,
55
- useResolvedScope
56
- } from "./chunk-3XTALGJF.js";
56
+ useIsPublicPage
57
+ } from "./chunk-6Z7LTB3D.js";
57
58
  import {
58
59
  EventServiceContext,
59
60
  useOrganisations,
60
61
  useSessionRestoration,
61
62
  useUnifiedAuth
62
- } from "./chunk-BYFSK72L.js";
63
+ } from "./chunk-DWUBLJJM.js";
63
64
  import {
64
65
  isSuperAdmin
65
- } from "./chunk-KNC55RTG.js";
66
+ } from "./chunk-RWEBCB47.js";
66
67
  import {
67
68
  assertAppId
68
69
  } from "./chunk-QXHPKYJV.js";
@@ -72,13 +73,13 @@ import {
72
73
  } from "./chunk-J36DSWQK.js";
73
74
  import {
74
75
  cn
75
- } from "./chunk-R77UEZ4E.js";
76
+ } from "./chunk-M43Y4SSO.js";
76
77
  import {
77
78
  getCurrentAppName
78
- } from "./chunk-I7PSE6JW.js";
79
+ } from "./chunk-M7MPQISP.js";
79
80
  import {
80
81
  clearPalette
81
- } from "./chunk-SQGMNID3.js";
82
+ } from "./chunk-L4OXEN46.js";
82
83
  import {
83
84
  createLogger,
84
85
  logger
@@ -404,7 +405,7 @@ function Textarea({ className, variant = "default", size = "md", error, ref, ...
404
405
  Textarea.displayName = "Textarea";
405
406
 
406
407
  // src/components/FileDisplay/FileDisplay.tsx
407
- import { useState as useState3, useEffect as useEffect3, useRef as useRef3, useContext, useMemo } from "react";
408
+ import React3, { useState as useState3, useEffect as useEffect3, useCallback as useCallback3, useRef as useRef3, useContext, useMemo } from "react";
408
409
  import { FileText, ExternalLink } from "lucide-react";
409
410
 
410
411
  // src/hooks/useFileUrl.ts
@@ -423,6 +424,12 @@ function useFileUrl(fileReference, options) {
423
424
  setError(null);
424
425
  return;
425
426
  }
427
+ if (!supabase) {
428
+ setUrl(null);
429
+ setIsLoading(false);
430
+ setError(new Error("Supabase client is required for URL generation"));
431
+ return;
432
+ }
426
433
  if (isLoading || url && fileReferenceIdRef.current === fileReference.id) {
427
434
  return;
428
435
  }
@@ -500,7 +507,7 @@ function defaultGenerateFallbackText(fileName) {
500
507
  if (words.length === 0) return "FL";
501
508
  return words.map((word) => word.charAt(0).toUpperCase()).join("").substring(0, 3);
502
509
  }
503
- function FileDisplayContent({
510
+ var FileDisplayContent = React3.memo(function FileDisplayContent2({
504
511
  isLoading,
505
512
  error,
506
513
  fileUrl,
@@ -531,6 +538,22 @@ function FileDisplayContent({
531
538
  const [internalFileUrls, setInternalFileUrls] = useState3(new Map(fileUrls));
532
539
  const [deleteDialogOpen, setDeleteDialogOpen] = useState3(false);
533
540
  const fileReferencesRef = useRef3([]);
541
+ const imgRef = useRef3(null);
542
+ const currentSrcRef = useRef3(null);
543
+ const isImageLoadingRef = useRef3(false);
544
+ const stableFileUrl = useMemo(() => fileUrl, [fileUrl]);
545
+ const handleImageLoadStart = useCallback3(() => {
546
+ isImageLoadingRef.current = true;
547
+ if (stableFileUrl) {
548
+ currentSrcRef.current = stableFileUrl;
549
+ }
550
+ }, [stableFileUrl]);
551
+ const handleImageLoad = useCallback3(() => {
552
+ isImageLoadingRef.current = false;
553
+ if (stableFileUrl) {
554
+ currentSrcRef.current = stableFileUrl;
555
+ }
556
+ }, [stableFileUrl]);
534
557
  const computedFallbackText = useMemo(() => {
535
558
  if (fallbackText) return fallbackText;
536
559
  const sourceText = fallbackSourceText ?? fileReference?.file_metadata?.fileName;
@@ -554,10 +577,14 @@ function FileDisplayContent({
554
577
  };
555
578
  const handleDeleteConfirm = async () => {
556
579
  setDeleteDialogOpen(false);
557
- if (onDelete) {
558
- await onDelete();
580
+ try {
581
+ if (onDelete) {
582
+ await onDelete();
583
+ }
584
+ setImageError(false);
585
+ } catch (error2) {
586
+ setImageError(false);
559
587
  }
560
- setImageError(false);
561
588
  };
562
589
  const handleImageError = () => {
563
590
  setImageError(true);
@@ -632,27 +659,32 @@ function FileDisplayContent({
632
659
  if (imageError && showFallback) {
633
660
  return /* @__PURE__ */ jsx4("figure", { className, title: fileReference.file_metadata.fileName || "File", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: computedFallbackText }) });
634
661
  }
635
- if (!fileUrl) {
662
+ if (!stableFileUrl) {
636
663
  return /* @__PURE__ */ jsx4("figure", { className: className || "max-w-full h-48", title: "Loading", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: /* @__PURE__ */ jsx4(LoadingSpinner, {}) }) });
637
664
  }
638
665
  return /* @__PURE__ */ jsx4("figure", { className: className || "", children: /* @__PURE__ */ jsx4(
639
666
  "img",
640
667
  {
641
- src: fileUrl,
668
+ ref: imgRef,
669
+ src: stableFileUrl || void 0,
642
670
  alt: fileReference.file_metadata.fileName || "File",
643
671
  className: imgClassName || "object-cover size-full",
644
- onError: handleImageError
645
- }
672
+ onError: handleImageError,
673
+ onLoadStart: handleImageLoadStart,
674
+ onLoad: handleImageLoad,
675
+ loading: "lazy"
676
+ },
677
+ fileReference.id
646
678
  ) });
647
679
  }
648
- if (displayOnly && !isImage && fileUrl && fileReference && !showDelete) {
680
+ if (displayOnly && !isImage && stableFileUrl && fileReference && !showDelete) {
649
681
  const fileName = fileReference.file_metadata?.fileName || "Document";
650
682
  const ariaLabel = `Open ${fileName} in new tab`;
651
683
  return /* @__PURE__ */ jsxs3("figure", { className, children: [
652
684
  /* @__PURE__ */ jsxs3(
653
685
  "a",
654
686
  {
655
- href: fileUrl,
687
+ href: stableFileUrl || void 0,
656
688
  target: "_blank",
657
689
  rel: "noopener noreferrer",
658
690
  "aria-label": ariaLabel,
@@ -674,18 +706,20 @@ function FileDisplayContent({
674
706
  ] })
675
707
  ] });
676
708
  }
677
- if (displayOnly && showFallback && (!fileUrl || imageError || !isImage)) {
709
+ if (displayOnly && showFallback && (!stableFileUrl || imageError || !isImage)) {
678
710
  return /* @__PURE__ */ jsx4("figure", { className, title: fileReference.file_metadata.fileName || "File", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: computedFallbackText }) });
679
711
  }
680
- return /* @__PURE__ */ jsx4("figure", { className: `relative ${className}`, children: isImage && fileUrl && !imageError ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
712
+ return /* @__PURE__ */ jsx4("figure", { className: `relative ${className}`, children: isImage && stableFileUrl && !imageError ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
681
713
  /* @__PURE__ */ jsx4(
682
714
  "img",
683
715
  {
684
- src: fileUrl,
716
+ src: stableFileUrl,
685
717
  alt: fileReference.file_metadata.fileName || "File",
686
718
  className: imgClassName || "object-cover size-full",
687
- onError: handleImageError
688
- }
719
+ onError: handleImageError,
720
+ loading: "lazy"
721
+ },
722
+ fileReference.id
689
723
  ),
690
724
  showDelete && /* @__PURE__ */ jsxs3(Fragment3, { children: [
691
725
  /* @__PURE__ */ jsx4(
@@ -778,11 +812,13 @@ function FileDisplayContent({
778
812
  isImage && fileUrl2 ? /* @__PURE__ */ jsx4(
779
813
  "img",
780
814
  {
781
- src: fileUrl2,
815
+ src: fileUrl2 || void 0,
782
816
  alt: fileRef.file_metadata.fileName || "File",
783
817
  className: imgClassName || "object-cover size-full",
784
- onError: handleImageError
785
- }
818
+ onError: handleImageError,
819
+ loading: "lazy"
820
+ },
821
+ fileRef.id
786
822
  ) : /* @__PURE__ */ jsx4("span", { className: "text-2xl", children: getFileIcon(fileRef.file_metadata.fileType || "") }),
787
823
  showMetadata && /* @__PURE__ */ jsxs3("figcaption", { className: "flex-1 min-w-0", children: [
788
824
  /* @__PURE__ */ jsx4("p", { className: "font-medium text-sec-900 truncate", children: fileRef.file_metadata.fileName || "Unknown file" }),
@@ -821,7 +857,7 @@ function FileDisplayContent({
821
857
  }),
822
858
  children
823
859
  ] });
824
- }
860
+ });
825
861
  function FileDisplayPublic({
826
862
  table_name,
827
863
  record_id,
@@ -971,9 +1007,7 @@ function FileDisplayAuthenticated({
971
1007
  showMetadata
972
1008
  }) {
973
1009
  const { supabase } = useUnifiedAuth();
974
- if (!supabase) {
975
- return /* @__PURE__ */ jsx4("figure", { className, title: "Error", children: /* @__PURE__ */ jsx4("p", { className: getFallbackClasses(fallbackSize || "md"), children: "Supabase client not available in authenticated context" }) });
976
- }
1010
+ const [displayOnlyFileReference, setDisplayOnlyFileReference] = useState3(null);
977
1011
  const {
978
1012
  fileUrl,
979
1013
  fileReference,
@@ -988,16 +1022,15 @@ function FileDisplayAuthenticated({
988
1022
  record_id,
989
1023
  organisation_id,
990
1024
  category,
991
- { supabase }
1025
+ { supabase: supabase || null }
992
1026
  );
993
- const [displayOnlyFileReference, setDisplayOnlyFileReference] = useState3(null);
994
1027
  const displayOnlyFileUrlFromMap = displayOnlyFileReference ? fileUrls.get(displayOnlyFileReference.id) : null;
995
1028
  const displayOnlyFileUrlHook = useFileUrl(
996
1029
  displayOnlyFileReference && !displayOnlyFileUrlFromMap ? displayOnlyFileReference : null,
997
1030
  {
998
- supabase,
1031
+ supabase: supabase || null,
999
1032
  organisation_id,
1000
- autoLoad: !displayOnlyFileUrlFromMap && !!displayOnlyFileReference
1033
+ autoLoad: !displayOnlyFileUrlFromMap && !!displayOnlyFileReference && !!supabase
1001
1034
  }
1002
1035
  );
1003
1036
  const displayOnlyFileUrl = displayOnlyFileUrlFromMap || displayOnlyFileUrlHook.url;
@@ -1012,6 +1045,9 @@ function FileDisplayAuthenticated({
1012
1045
  setDisplayOnlyFileReference(null);
1013
1046
  }
1014
1047
  }, [displayOnly, category, fileReferences, fileUrls]);
1048
+ if (!supabase) {
1049
+ return /* @__PURE__ */ jsx4("figure", { className, title: "Error", children: /* @__PURE__ */ jsx4("p", { className: getFallbackClasses(fallbackSize || "md"), children: "Supabase client not available in authenticated context" }) });
1050
+ }
1015
1051
  const handleDelete = async () => {
1016
1052
  };
1017
1053
  let finalFileReference = fileReference;
@@ -1428,13 +1464,17 @@ function useFileReferenceById(supabase, fileReferenceId, organisationId) {
1428
1464
  return;
1429
1465
  }
1430
1466
  const loadUrl = async () => {
1431
- const service = createFileReferenceService(supabase);
1432
- const url = await service.getFileUrl(
1433
- fileReference.table_name,
1434
- fileReference.record_id,
1435
- organisationId
1436
- );
1437
- setFileUrl(url);
1467
+ try {
1468
+ const service = createFileReferenceService(supabase);
1469
+ const url = await service.getFileUrl(
1470
+ fileReference.table_name,
1471
+ fileReference.record_id,
1472
+ organisationId
1473
+ );
1474
+ setFileUrl(url);
1475
+ } catch (error2) {
1476
+ setFileUrl(null);
1477
+ }
1438
1478
  };
1439
1479
  loadUrl();
1440
1480
  }, [fileReference, fileReferenceId, organisationId, supabase]);
@@ -1982,7 +2022,7 @@ var Calendar = React7.forwardRef(
1982
2022
  ] })
1983
2023
  );
1984
2024
  }
1985
- return child;
2025
+ return React7.isValidElement(child) ? React7.cloneElement(child, { key: child.key ?? `calendar-child-${index}` }) : child;
1986
2026
  }) });
1987
2027
  });
1988
2028
  CustomMonth.displayName = "CustomMonth";
@@ -2236,6 +2276,7 @@ function FormField({
2236
2276
  type,
2237
2277
  placeholder,
2238
2278
  "data-testid": testId,
2279
+ "aria-label": label || placeholder || name,
2239
2280
  className: cn(
2240
2281
  "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
2241
2282
  fieldError && "border-destructive focus-visible:ring-destructive"
@@ -2356,297 +2397,98 @@ var LoginForm = React9.memo(({
2356
2397
  ] }) });
2357
2398
  });
2358
2399
 
2359
- // src/components/EventSelector/EventSelector.tsx
2360
- import { RefreshCw, AlertCircle, Lock, Calendar as Calendar2, Star } from "lucide-react";
2361
- import { useEffect as useEffect6, useMemo as useMemo5, useRef as useRef6 } from "react";
2362
- import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
2363
- function EventSelector({
2364
- placeholder = "Select an event",
2400
+ // src/components/ContextSelector/ContextSelector.tsx
2401
+ import { useMemo as useMemo5 } from "react";
2402
+ import { RefreshCw, AlertCircle, Building2, Calendar as Calendar2 } from "lucide-react";
2403
+ import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
2404
+ function ContextSelector({
2405
+ placeholder = "Select organisation or event",
2365
2406
  className,
2366
- onEventChange,
2367
- showNoEventsMessage = true,
2407
+ onOrganisationSelect,
2408
+ onEventSelect,
2409
+ showNoItemsMessage = true,
2368
2410
  showRetryButton = true,
2369
- showEventDetails = true,
2370
- showNextEventIndicator = true
2411
+ compact = false,
2412
+ disabled = false,
2413
+ showOrganisations = true,
2414
+ showEvents = true
2371
2415
  }) {
2416
+ const {
2417
+ organisations,
2418
+ selectedOrganisation,
2419
+ isLoading: orgLoading,
2420
+ error: orgError,
2421
+ refreshOrganisations
2422
+ } = useOrganisations();
2372
2423
  const {
2373
2424
  events,
2374
2425
  selectedEvent,
2375
- isLoading,
2376
- error,
2377
- setSelectedEvent,
2426
+ isLoading: eventLoading,
2427
+ error: eventError,
2378
2428
  refreshEvents
2379
2429
  } = useEvents();
2380
- const handleValueChange = (eventId) => {
2381
- const event = events.find((e) => (e.event_id || e.id) === eventId);
2382
- if (event) {
2383
- setSelectedEvent(event);
2384
- if (onEventChange) {
2385
- onEventChange(event);
2386
- }
2430
+ const { isSuperAdmin: isSuperAdmin2 } = useRBAC();
2431
+ const isLoading = showOrganisations && orgLoading || showEvents && eventLoading;
2432
+ const hasError = showOrganisations && orgError || showEvents && eventError;
2433
+ const hasItems = showOrganisations && (organisations?.length || 0) > 0 || showEvents && (events?.length || 0) > 0;
2434
+ const currentValue = useMemo5(() => {
2435
+ if (showEvents && selectedEvent) {
2436
+ return `event:${selectedEvent.event_id || selectedEvent.id}`;
2387
2437
  }
2388
- };
2389
- const handleRetry = () => {
2390
- refreshEvents();
2391
- };
2392
- const isNextEvent = (event) => {
2393
- if (!event.event_date) return false;
2394
- const now = /* @__PURE__ */ new Date();
2395
- const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
2396
- const eventDate = new Date(event.event_date);
2397
- return eventDate >= today;
2398
- };
2399
- const formatEventDate = (dateString) => {
2400
- const date = new Date(dateString);
2401
- const today = /* @__PURE__ */ new Date();
2402
- const tomorrow = new Date(today);
2403
- tomorrow.setDate(tomorrow.getDate() + 1);
2404
- const normalizeDate = (d) => {
2405
- const normalized = new Date(d);
2406
- normalized.setHours(0, 0, 0, 0);
2407
- return normalized;
2408
- };
2409
- const normalizedDate = normalizeDate(date);
2410
- const normalizedToday = normalizeDate(today);
2411
- const normalizedTomorrow = normalizeDate(tomorrow);
2412
- if (normalizedDate.getTime() === normalizedToday.getTime()) {
2413
- return "Today";
2414
- } else if (normalizedDate.getTime() === normalizedTomorrow.getTime()) {
2415
- return "Tomorrow";
2416
- } else {
2417
- return date.toLocaleDateString();
2438
+ if (showOrganisations && selectedOrganisation) {
2439
+ return `org:${selectedOrganisation.id}`;
2418
2440
  }
2419
- };
2420
- const sortedEvents = useMemo5(() => {
2421
- const getTime = (e) => e.event_date ? new Date(e.event_date).getTime() : Number.NEGATIVE_INFINITY;
2422
- return [...events].sort((a, b) => getTime(b) - getTime(a));
2423
- }, [events]);
2424
- const prevEventsLengthRef = useRef6(events.length);
2425
- const prevSelectedEventIdRef = useRef6(selectedEvent?.event_id);
2426
- const hasAutoSelectedRef = useRef6(false);
2427
- useEffect6(() => {
2428
- const eventsLengthChanged = events.length !== prevEventsLengthRef.current;
2429
- const selectedEventChanged = selectedEvent?.event_id !== prevSelectedEventIdRef.current;
2430
- if (eventsLengthChanged) {
2431
- prevEventsLengthRef.current = events.length;
2432
- if (events.length > 0) {
2433
- hasAutoSelectedRef.current = false;
2441
+ return "";
2442
+ }, [showOrganisations, showEvents, selectedOrganisation?.id, selectedEvent]);
2443
+ const handleValueChange = (value) => {
2444
+ if (disabled || isLoading) return;
2445
+ if (value.startsWith("org:") && showOrganisations) {
2446
+ const orgId = value.replace("org:", "");
2447
+ const org = organisations?.find((o) => o.id === orgId);
2448
+ if (org && onOrganisationSelect) {
2449
+ onOrganisationSelect(org);
2434
2450
  }
2435
- }
2436
- if (selectedEventChanged) {
2437
- prevSelectedEventIdRef.current = selectedEvent?.event_id;
2438
- if (selectedEvent) {
2439
- hasAutoSelectedRef.current = false;
2451
+ } else if (value.startsWith("event:") && showEvents) {
2452
+ const eventId = value.replace("event:", "");
2453
+ const event = events?.find((e) => (e.event_id || e.id) === eventId);
2454
+ if (event && onEventSelect) {
2455
+ onEventSelect(event);
2440
2456
  }
2441
2457
  }
2442
- if (!selectedEvent && events.length > 0 && !isLoading && eventsLengthChanged && !hasAutoSelectedRef.current) {
2443
- hasAutoSelectedRef.current = true;
2444
- autoSelectEvent();
2445
- }
2446
- function autoSelectEvent() {
2447
- const today = /* @__PURE__ */ new Date();
2448
- const startOfToday = new Date(today.getFullYear(), today.getMonth(), today.getDate()).getTime();
2449
- const next = [...events].filter((e) => e.event_date && new Date(e.event_date).getTime() >= startOfToday).sort((a, b) => new Date(a.event_date).getTime() - new Date(b.event_date).getTime())[0];
2450
- if (next) {
2451
- setSelectedEvent(next);
2452
- if (onEventChange) onEventChange(next);
2453
- } else {
2454
- const mostRecentPast = [...events].filter((e) => {
2455
- if (!e.event_date) return false;
2456
- const eventDate = new Date(e.event_date);
2457
- const startOfEventDate = new Date(eventDate.getFullYear(), eventDate.getMonth(), eventDate.getDate()).getTime();
2458
- return startOfEventDate < startOfToday;
2459
- }).sort((a, b) => new Date(b.event_date).getTime() - new Date(a.event_date).getTime())[0];
2460
- if (mostRecentPast) {
2461
- setSelectedEvent(mostRecentPast);
2462
- if (onEventChange) onEventChange(mostRecentPast);
2463
- }
2458
+ };
2459
+ const handleRetry = async () => {
2460
+ try {
2461
+ if (showOrganisations && orgError) {
2462
+ await refreshOrganisations();
2463
+ }
2464
+ if (showEvents && eventError) {
2465
+ await refreshEvents();
2464
2466
  }
2467
+ } catch (error) {
2468
+ logger.error("ContextSelector", "Failed to refresh:", error);
2465
2469
  }
2466
- }, [events.length, selectedEvent?.event_id, isLoading, setSelectedEvent, onEventChange]);
2467
- if (isLoading) {
2470
+ };
2471
+ if (isLoading && !hasItems) {
2472
+ const loadingText = compact ? "Loading..." : showOrganisations && showEvents ? "Loading organisations and events..." : showOrganisations ? "Loading organisations..." : "Loading events...";
2468
2473
  return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-2 ${className}`, children: [
2469
2474
  /* @__PURE__ */ jsx13(LoadingSpinner, { size: "sm" }),
2470
- /* @__PURE__ */ jsx13("span", { className: "text-sm text-muted-foreground", children: "Loading events..." })
2475
+ /* @__PURE__ */ jsx13("span", { className: "text-sm text-muted-foreground", children: loadingText })
2471
2476
  ] });
2472
2477
  }
2473
- if (error) {
2474
- return /* @__PURE__ */ jsx13("div", { className, children: /* @__PURE__ */ jsxs8(Alert, { variant: "destructive", children: [
2475
- /* @__PURE__ */ jsx13(Lock, { className: "size-4" }),
2476
- /* @__PURE__ */ jsxs8(AlertDescription, { className: "flex items-center justify-between", children: [
2477
- /* @__PURE__ */ jsx13("span", { children: error.message }),
2478
- showRetryButton && /* @__PURE__ */ jsxs8(
2479
- Button,
2480
- {
2481
- variant: "outline",
2482
- size: "sm",
2483
- onClick: handleRetry,
2484
- className: "ml-2",
2485
- children: [
2486
- /* @__PURE__ */ jsx13(RefreshCw, { className: "size-3 mr-1" }),
2487
- "Retry"
2488
- ]
2489
- }
2490
- )
2491
- ] })
2492
- ] }) });
2493
- }
2494
- if (events.length === 0) {
2495
- if (showNoEventsMessage) {
2496
- return /* @__PURE__ */ jsx13("div", { className, children: /* @__PURE__ */ jsxs8(Alert, { variant: "inline", children: [
2497
- /* @__PURE__ */ jsx13(AlertCircle, { className: "size-4 text-acc-700" }),
2498
- /* @__PURE__ */ jsxs8(AlertDescription, { className: "flex items-center justify-between", children: [
2499
- /* @__PURE__ */ jsx13("span", { children: "No events available." }),
2500
- showRetryButton && /* @__PURE__ */ jsxs8(
2501
- Button,
2502
- {
2503
- variant: "outline",
2504
- size: "sm",
2505
- onClick: handleRetry,
2506
- className: "ml-2",
2507
- children: [
2508
- /* @__PURE__ */ jsx13(RefreshCw, { className: "size-3 mr-1" }),
2509
- "Refresh"
2510
- ]
2511
- }
2512
- )
2513
- ] })
2514
- ] }) });
2515
- }
2516
- return null;
2517
- }
2518
- return /* @__PURE__ */ jsxs8(
2519
- Select,
2520
- {
2521
- value: selectedEvent ? selectedEvent.event_id || selectedEvent.id : "",
2522
- onValueChange: handleValueChange,
2523
- className,
2524
- children: [
2525
- /* @__PURE__ */ jsx13(SelectTrigger, { className: "text-left", variant: "outline", children: /* @__PURE__ */ jsx13(SelectValue, { placeholder, children: selectedEvent && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
2526
- /* @__PURE__ */ jsx13(Calendar2, { className: "size-4 flex-shrink-0" }),
2527
- /* @__PURE__ */ jsx13("span", { className: "truncate", children: selectedEvent.event_name }),
2528
- selectedEvent.event_date && /* @__PURE__ */ jsxs8("span", { className: "text-xs text-muted-foreground flex-shrink-0", children: [
2529
- "(",
2530
- formatEventDate(selectedEvent.event_date),
2531
- ")"
2532
- ] })
2533
- ] }) }) }),
2534
- /* @__PURE__ */ jsx13(SelectContent, { children: sortedEvents.map((event) => {
2535
- const isNext = isNextEvent(event);
2536
- const isSelected = selectedEvent && (selectedEvent.event_id === event.event_id || selectedEvent.id === event.id);
2537
- return /* @__PURE__ */ jsx13(
2538
- SelectItem,
2539
- {
2540
- value: event.event_id || event.id,
2541
- className: "flex items-center justify-between",
2542
- children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 w-full", children: [
2543
- showNextEventIndicator && isNext && /* @__PURE__ */ jsx13(Star, { className: "size-3 text-acc-500" }),
2544
- /* @__PURE__ */ jsxs8("div", { className: "flex-1", children: [
2545
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
2546
- /* @__PURE__ */ jsx13("span", { className: isSelected ? "font-semibold" : "", children: event.event_name }),
2547
- isSelected && /* @__PURE__ */ jsx13("span", { className: "text-xs bg-primary text-primary-foreground px-1 rounded", children: "Current" })
2548
- ] }),
2549
- showEventDetails && event.event_date && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
2550
- /* @__PURE__ */ jsx13(Calendar2, { className: "size-3" }),
2551
- /* @__PURE__ */ jsx13("span", { children: formatEventDate(event.event_date) }),
2552
- showNextEventIndicator && isNext && /* @__PURE__ */ jsx13("span", { className: "text-acc-600 font-medium", children: "(Next)" })
2553
- ] }),
2554
- showEventDetails && event.event_venue && /* @__PURE__ */ jsxs8("div", { className: "text-xs text-muted-foreground", children: [
2555
- "\u{1F4CD} ",
2556
- event.event_venue
2557
- ] })
2558
- ] })
2559
- ] })
2560
- },
2561
- event.event_id || event.id
2562
- );
2563
- }) })
2564
- ]
2478
+ if (hasError) {
2479
+ const errorMessages = [];
2480
+ if (showOrganisations && orgError) {
2481
+ errorMessages.push(`Failed to load organisations: ${orgError.message}`);
2565
2482
  }
2566
- );
2567
- }
2568
-
2569
- // src/components/OrganisationSelector/OrganisationSelector.tsx
2570
- import { useState as useState8, useCallback as useCallback8, useMemo as useMemo6 } from "react";
2571
- import { RefreshCw as RefreshCw2, AlertCircle as AlertCircle2, Building2, Shield } from "lucide-react";
2572
- import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
2573
- function OrganisationSelector({
2574
- placeholder = "Select organisation",
2575
- className,
2576
- onOrganisationChange,
2577
- showNoOrganisationsMessage = true,
2578
- showRetryButton = true,
2579
- showRole = false,
2580
- compact = false,
2581
- disabled = false
2582
- }) {
2583
- const [isLoading, setIsLoading] = useState8(false);
2584
- const [switchError, setSwitchError] = useState8(null);
2585
- const {
2586
- organisations,
2587
- selectedOrganisation,
2588
- isLoading: orgLoading,
2589
- error: orgError,
2590
- switchOrganisation,
2591
- getUserRole,
2592
- validateOrganisationAccess,
2593
- refreshOrganisations
2594
- } = useOrganisations();
2595
- const handleOrganisationChange = useCallback8(async (orgId) => {
2596
- if (disabled || isLoading) return;
2597
- setSwitchError(null);
2598
- setIsLoading(true);
2599
- try {
2600
- if (!validateOrganisationAccess(orgId)) {
2601
- throw new Error("You do not have access to this organisation");
2602
- }
2603
- await switchOrganisation(orgId);
2604
- const newOrganisation = organisations.find((org) => org.id === orgId);
2605
- if (newOrganisation && onOrganisationChange) {
2606
- onOrganisationChange(newOrganisation);
2607
- }
2608
- } catch (error) {
2609
- logger.error("OrganisationSelector", "Failed to switch organisation:", error);
2610
- setSwitchError(error instanceof Error ? error.message : "Failed to switch organisation");
2611
- } finally {
2612
- setIsLoading(false);
2613
- }
2614
- }, [
2615
- disabled,
2616
- isLoading,
2617
- validateOrganisationAccess,
2618
- switchOrganisation,
2619
- organisations,
2620
- onOrganisationChange
2621
- ]);
2622
- const handleRetry = useCallback8(async () => {
2623
- setIsLoading(true);
2624
- setSwitchError(null);
2625
- try {
2626
- await refreshOrganisations();
2627
- } catch (error) {
2628
- logger.error("OrganisationSelector", "Failed to refresh organisations:", error);
2629
- setSwitchError("Failed to refresh organisations");
2630
- } finally {
2631
- setIsLoading(false);
2483
+ if (showEvents && eventError) {
2484
+ errorMessages.push(`Failed to load events: ${eventError.message}`);
2632
2485
  }
2633
- }, [refreshOrganisations]);
2634
- if (orgLoading) {
2635
- return /* @__PURE__ */ jsxs9("div", { className: `flex items-center gap-2 ${className}`, children: [
2636
- /* @__PURE__ */ jsx14(LoadingSpinner, { size: "sm" }),
2637
- /* @__PURE__ */ jsx14("span", { className: "text-sm text-muted-foreground", children: compact ? "Loading..." : "Loading organisations..." })
2638
- ] });
2639
- }
2640
- if (orgError) {
2641
- return /* @__PURE__ */ jsxs9("div", { className: `space-y-2 ${className}`, children: [
2642
- /* @__PURE__ */ jsxs9(Alert, { variant: "destructive", children: [
2643
- /* @__PURE__ */ jsx14(AlertCircle2, { className: "size-4" }),
2644
- /* @__PURE__ */ jsxs9(AlertDescription, { children: [
2645
- "Failed to load organisations: ",
2646
- orgError.message
2647
- ] })
2486
+ return /* @__PURE__ */ jsxs8("div", { className: `space-y-2 ${className}`, children: [
2487
+ /* @__PURE__ */ jsxs8(Alert, { variant: "destructive", children: [
2488
+ /* @__PURE__ */ jsx13(AlertCircle, { className: "size-4" }),
2489
+ /* @__PURE__ */ jsx13(AlertDescription, { children: errorMessages.join(" ") })
2648
2490
  ] }),
2649
- showRetryButton && /* @__PURE__ */ jsxs9(
2491
+ showRetryButton && /* @__PURE__ */ jsxs8(
2650
2492
  Button,
2651
2493
  {
2652
2494
  variant: "outline",
@@ -2655,21 +2497,22 @@ function OrganisationSelector({
2655
2497
  disabled: isLoading,
2656
2498
  className: "w-full",
2657
2499
  children: [
2658
- /* @__PURE__ */ jsx14(RefreshCw2, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
2500
+ /* @__PURE__ */ jsx13(RefreshCw, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
2659
2501
  "Retry"
2660
2502
  ]
2661
2503
  }
2662
2504
  )
2663
2505
  ] });
2664
2506
  }
2665
- if (organisations.length === 0) {
2666
- if (showNoOrganisationsMessage) {
2667
- return /* @__PURE__ */ jsxs9("div", { className: `space-y-2 ${className}`, children: [
2668
- /* @__PURE__ */ jsxs9(Alert, { children: [
2669
- /* @__PURE__ */ jsx14(Building2, { className: "size-4" }),
2670
- /* @__PURE__ */ jsx14(AlertDescription, { children: "No organisations available. Please contact your administrator to be added to an organisation." })
2507
+ if (!hasItems) {
2508
+ if (showNoItemsMessage) {
2509
+ const noItemsText = showOrganisations && showEvents ? "No organisations or events available. Please contact your administrator." : showOrganisations ? "No organisations available. Please contact your administrator." : "No events available. Please contact your administrator.";
2510
+ return /* @__PURE__ */ jsxs8("div", { className: `space-y-2 ${className}`, children: [
2511
+ /* @__PURE__ */ jsxs8(Alert, { children: [
2512
+ /* @__PURE__ */ jsx13(AlertCircle, { className: "size-4" }),
2513
+ /* @__PURE__ */ jsx13(AlertDescription, { children: noItemsText })
2671
2514
  ] }),
2672
- showRetryButton && /* @__PURE__ */ jsxs9(
2515
+ showRetryButton && /* @__PURE__ */ jsxs8(
2673
2516
  Button,
2674
2517
  {
2675
2518
  variant: "outline",
@@ -2678,7 +2521,7 @@ function OrganisationSelector({
2678
2521
  disabled: isLoading,
2679
2522
  className: "w-full",
2680
2523
  children: [
2681
- /* @__PURE__ */ jsx14(RefreshCw2, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
2524
+ /* @__PURE__ */ jsx13(RefreshCw, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
2682
2525
  "Check Again"
2683
2526
  ]
2684
2527
  }
@@ -2687,74 +2530,103 @@ function OrganisationSelector({
2687
2530
  }
2688
2531
  return null;
2689
2532
  }
2690
- const switchErrorDisplay = switchError && /* @__PURE__ */ jsxs9(Alert, { variant: "destructive", className: "mt-2", children: [
2691
- /* @__PURE__ */ jsx14(AlertCircle2, { className: "size-4" }),
2692
- /* @__PURE__ */ jsx14(AlertDescription, { children: switchError })
2693
- ] });
2694
- const isSelectDisabled = disabled || isLoading;
2695
- const selectValue = useMemo6(() => {
2696
- return selectedOrganisation?.id || "";
2697
- }, [selectedOrganisation?.id]);
2698
- return /* @__PURE__ */ jsxs9("div", { className, children: [
2699
- /* @__PURE__ */ jsxs9(
2700
- Select,
2701
- {
2702
- value: selectValue,
2703
- onValueChange: handleOrganisationChange,
2704
- disabled: isSelectDisabled,
2705
- children: [
2706
- /* @__PURE__ */ jsx14(
2707
- SelectTrigger,
2708
- {
2709
- className: "text-left",
2710
- variant: "outline",
2711
- children: /* @__PURE__ */ jsx14(SelectValue, { placeholder, children: selectedOrganisation && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
2712
- isLoading ? /* @__PURE__ */ jsx14(LoadingSpinner, { size: "sm" }) : /* @__PURE__ */ jsx14(Building2, { className: "size-4 flex-shrink-0" }),
2713
- /* @__PURE__ */ jsx14("span", { className: "truncate", children: selectedOrganisation.display_name })
2714
- ] }) })
2715
- }
2716
- ),
2717
- /* @__PURE__ */ jsx14(SelectContent, { children: organisations.map((org) => {
2718
- const userRole = getUserRole(org.id);
2719
- const hasAccess = validateOrganisationAccess(org.id);
2720
- return /* @__PURE__ */ jsx14(
2533
+ const displayValue = useMemo5(() => {
2534
+ if (showEvents && selectedEvent) {
2535
+ return /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
2536
+ /* @__PURE__ */ jsx13(Calendar2, { className: "size-4 flex-shrink-0" }),
2537
+ /* @__PURE__ */ jsx13("span", { className: "truncate", children: selectedEvent.event_name })
2538
+ ] });
2539
+ }
2540
+ if (showOrganisations && selectedOrganisation) {
2541
+ return /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
2542
+ /* @__PURE__ */ jsx13(Building2, { className: "size-4 flex-shrink-0" }),
2543
+ /* @__PURE__ */ jsx13("span", { className: "truncate", children: selectedOrganisation.display_name })
2544
+ ] });
2545
+ }
2546
+ return null;
2547
+ }, [showOrganisations, showEvents, selectedOrganisation, selectedEvent]);
2548
+ const effectivePlaceholder = useMemo5(() => {
2549
+ if (placeholder !== "Select organisation or event") {
2550
+ return placeholder;
2551
+ }
2552
+ if (showOrganisations && showEvents) {
2553
+ return "Select organisation or event";
2554
+ }
2555
+ if (showOrganisations) {
2556
+ return "Select organisation";
2557
+ }
2558
+ if (showEvents) {
2559
+ return "Select event";
2560
+ }
2561
+ return placeholder;
2562
+ }, [placeholder, showOrganisations, showEvents]);
2563
+ return /* @__PURE__ */ jsx13("div", { className, "data-testid": "context-selector", children: /* @__PURE__ */ jsxs8(
2564
+ Select,
2565
+ {
2566
+ value: currentValue,
2567
+ onValueChange: handleValueChange,
2568
+ disabled: disabled || isLoading,
2569
+ children: [
2570
+ /* @__PURE__ */ jsx13(
2571
+ SelectTrigger,
2572
+ {
2573
+ className: "text-left",
2574
+ variant: "outline",
2575
+ children: /* @__PURE__ */ jsx13(SelectValue, { placeholder: effectivePlaceholder, children: displayValue })
2576
+ }
2577
+ ),
2578
+ /* @__PURE__ */ jsxs8(SelectContent, { children: [
2579
+ showOrganisations && organisations && organisations.length > 0 && /* @__PURE__ */ jsxs8(Fragment6, { children: [
2580
+ /* @__PURE__ */ jsxs8(SelectGroup, { children: [
2581
+ /* @__PURE__ */ jsx13(SelectLabel, { children: "Organisations" }),
2582
+ organisations.map((org) => /* @__PURE__ */ jsx13(
2583
+ SelectItem,
2584
+ {
2585
+ value: `org:${org.id}`,
2586
+ children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
2587
+ /* @__PURE__ */ jsx13(Building2, { className: "size-4" }),
2588
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
2589
+ /* @__PURE__ */ jsx13("span", { className: "font-medium", children: org.display_name }),
2590
+ !compact && org.description && /* @__PURE__ */ jsx13("span", { className: "text-xs text-muted-foreground truncate max-w-40", children: org.description })
2591
+ ] })
2592
+ ] })
2593
+ },
2594
+ org.id
2595
+ ))
2596
+ ] }),
2597
+ showEvents && events && events.length > 0 && /* @__PURE__ */ jsx13(SelectSeparator, {})
2598
+ ] }),
2599
+ showEvents && events && events.length > 0 && /* @__PURE__ */ jsxs8(SelectGroup, { children: [
2600
+ /* @__PURE__ */ jsx13(SelectLabel, { children: "Events" }),
2601
+ events.map((event) => /* @__PURE__ */ jsx13(
2721
2602
  SelectItem,
2722
2603
  {
2723
- value: org.id,
2724
- disabled: !hasAccess,
2725
- className: !hasAccess ? "opacity-50" : "",
2726
- children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between w-full", children: [
2727
- /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
2728
- /* @__PURE__ */ jsx14(Building2, { className: "size-4" }),
2729
- /* @__PURE__ */ jsxs9("div", { className: "flex flex-col", children: [
2730
- /* @__PURE__ */ jsx14("span", { className: "font-medium", children: org.display_name }),
2731
- !compact && org.description && /* @__PURE__ */ jsx14("span", { className: "text-xs text-muted-foreground truncate max-w-40", children: org.description })
2732
- ] })
2733
- ] }),
2734
- showRole && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1 ml-4", children: [
2735
- /* @__PURE__ */ jsx14(Shield, { className: "size-3 text-muted-foreground" }),
2736
- /* @__PURE__ */ jsx14("span", { className: "text-xs text-muted-foreground capitalize", children: userRole?.replace("_", " ") || "No Role" })
2604
+ value: `event:${event.event_id || event.id}`,
2605
+ children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
2606
+ /* @__PURE__ */ jsx13(Calendar2, { className: "size-4" }),
2607
+ /* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
2608
+ /* @__PURE__ */ jsx13("span", { className: "font-medium", children: event.event_name }),
2609
+ !compact && event.event_date && /* @__PURE__ */ jsx13("span", { className: "text-xs text-muted-foreground", children: new Date(event.event_date).toLocaleDateString() })
2737
2610
  ] })
2738
2611
  ] })
2739
2612
  },
2740
- org.id
2741
- );
2742
- }) })
2743
- ]
2744
- }
2745
- ),
2746
- switchErrorDisplay && /* @__PURE__ */ jsx14("div", { className: "mt-2", children: switchErrorDisplay })
2747
- ] });
2613
+ event.event_id || event.id
2614
+ ))
2615
+ ] })
2616
+ ] })
2617
+ ]
2618
+ }
2619
+ ) });
2748
2620
  }
2749
2621
 
2750
2622
  // src/components/PasswordChange/PasswordChangeForm.tsx
2751
- import { useState as useState9 } from "react";
2752
- import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
2623
+ import { useState as useState8 } from "react";
2624
+ import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
2753
2625
  function PasswordChangeForm({ onSubmit, className }) {
2754
- const [newPassword, setNewPassword] = useState9("");
2755
- const [confirmPassword, setConfirmPassword] = useState9("");
2756
- const [error, setError] = useState9(null);
2757
- const [isSubmitting, setIsSubmitting] = useState9(false);
2626
+ const [newPassword, setNewPassword] = useState8("");
2627
+ const [confirmPassword, setConfirmPassword] = useState8("");
2628
+ const [error, setError] = useState8(null);
2629
+ const [isSubmitting, setIsSubmitting] = useState8(false);
2758
2630
  const handleSubmit = async (e) => {
2759
2631
  e.preventDefault();
2760
2632
  setError(null);
@@ -2779,11 +2651,11 @@ function PasswordChangeForm({ onSubmit, className }) {
2779
2651
  setIsSubmitting(false);
2780
2652
  }
2781
2653
  };
2782
- return /* @__PURE__ */ jsxs10("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: [
2783
- error && /* @__PURE__ */ jsx15("div", { role: "alert", children: error }),
2784
- /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
2785
- /* @__PURE__ */ jsx15(Label, { htmlFor: "new-password", children: "New Password" }),
2786
- /* @__PURE__ */ jsx15(
2654
+ return /* @__PURE__ */ jsxs9("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: [
2655
+ error && /* @__PURE__ */ jsx14("div", { role: "alert", children: error }),
2656
+ /* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
2657
+ /* @__PURE__ */ jsx14(Label, { htmlFor: "new-password", children: "New Password" }),
2658
+ /* @__PURE__ */ jsx14(
2787
2659
  Input,
2788
2660
  {
2789
2661
  id: "new-password",
@@ -2795,9 +2667,9 @@ function PasswordChangeForm({ onSubmit, className }) {
2795
2667
  }
2796
2668
  )
2797
2669
  ] }),
2798
- /* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
2799
- /* @__PURE__ */ jsx15(Label, { htmlFor: "confirm-password", children: "Confirm Password" }),
2800
- /* @__PURE__ */ jsx15(
2670
+ /* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
2671
+ /* @__PURE__ */ jsx14(Label, { htmlFor: "confirm-password", children: "Confirm Password" }),
2672
+ /* @__PURE__ */ jsx14(
2801
2673
  Input,
2802
2674
  {
2803
2675
  id: "confirm-password",
@@ -2809,7 +2681,7 @@ function PasswordChangeForm({ onSubmit, className }) {
2809
2681
  }
2810
2682
  )
2811
2683
  ] }),
2812
- /* @__PURE__ */ jsx15(
2684
+ /* @__PURE__ */ jsx14(
2813
2685
  Button,
2814
2686
  {
2815
2687
  type: "submit",
@@ -2822,9 +2694,9 @@ function PasswordChangeForm({ onSubmit, className }) {
2822
2694
  }
2823
2695
 
2824
2696
  // src/components/UserMenu/UserMenu.tsx
2825
- import React12, { useCallback as useCallback9, useMemo as useMemo7, useState as useState10 } from "react";
2697
+ import React12, { useCallback as useCallback8, useMemo as useMemo6, useState as useState9 } from "react";
2826
2698
  import { ChevronDown, LogOut, KeyRound } from "lucide-react";
2827
- import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
2699
+ import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
2828
2700
  var UserMenu = React12.memo(function UserMenu2({
2829
2701
  user,
2830
2702
  onSignOut,
@@ -2832,8 +2704,8 @@ var UserMenu = React12.memo(function UserMenu2({
2832
2704
  className,
2833
2705
  showAvatar = true
2834
2706
  }) {
2835
- const [isPasswordDialogOpen, setPasswordDialogOpen] = useState10(false);
2836
- const userInfo = useMemo7(() => {
2707
+ const [isPasswordDialogOpen, setPasswordDialogOpen] = useState9(false);
2708
+ const userInfo = useMemo6(() => {
2837
2709
  if (!user) return null;
2838
2710
  return {
2839
2711
  email: user.email,
@@ -2842,16 +2714,16 @@ var UserMenu = React12.memo(function UserMenu2({
2842
2714
  initial: (user.user_metadata?.display_name || user.user_metadata?.full_name || user.email || "U").charAt(0).toUpperCase()
2843
2715
  };
2844
2716
  }, [user]);
2845
- const handleSignOut = useCallback9(async () => {
2717
+ const handleSignOut = useCallback8(async () => {
2846
2718
  if (onSignOut) await onSignOut();
2847
2719
  }, [onSignOut]);
2848
2720
  if (!user || !userInfo) {
2849
2721
  return null;
2850
2722
  }
2851
- return /* @__PURE__ */ jsxs11(Dialog, { open: isPasswordDialogOpen, onOpenChange: setPasswordDialogOpen, children: [
2852
- /* @__PURE__ */ jsxs11(Select, { className, children: [
2853
- /* @__PURE__ */ jsx16(SelectTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(Button, { variant: "outline", className: "flex items-center gap-2", "aria-label": userInfo.displayName, children: [
2854
- showAvatar && /* @__PURE__ */ jsx16(
2723
+ return /* @__PURE__ */ jsxs10(Dialog, { open: isPasswordDialogOpen, onOpenChange: setPasswordDialogOpen, children: [
2724
+ /* @__PURE__ */ jsxs10(Select, { className, children: [
2725
+ /* @__PURE__ */ jsx15(SelectTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(Button, { variant: "outline", className: "flex items-center gap-2", "aria-label": userInfo.displayName, children: [
2726
+ showAvatar && /* @__PURE__ */ jsx15(
2855
2727
  Avatar,
2856
2728
  {
2857
2729
  src: userInfo.avatarUrl,
@@ -2860,29 +2732,30 @@ var UserMenu = React12.memo(function UserMenu2({
2860
2732
  className: "size-7"
2861
2733
  }
2862
2734
  ),
2863
- /* @__PURE__ */ jsx16("span", { children: userInfo.displayName }),
2864
- /* @__PURE__ */ jsx16(ChevronDown, { className: "size-4" })
2735
+ /* @__PURE__ */ jsx15("span", { children: userInfo.displayName }),
2736
+ /* @__PURE__ */ jsx15(ChevronDown, { className: "size-4" })
2865
2737
  ] }) }),
2866
- /* @__PURE__ */ jsxs11(SelectContent, { children: [
2867
- /* @__PURE__ */ jsx16(SelectLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col space-y-1", children: [
2868
- /* @__PURE__ */ jsx16("p", { className: "font-medium", children: userInfo.displayName }),
2869
- /* @__PURE__ */ jsx16("p", { className: "text-muted-foreground", children: userInfo.email })
2738
+ /* @__PURE__ */ jsxs10(SelectContent, { children: [
2739
+ /* @__PURE__ */ jsx15(SelectLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs10("li", { className: "pt-2", children: [
2740
+ userInfo.displayName,
2741
+ /* @__PURE__ */ jsx15("br", {}),
2742
+ /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: userInfo.email })
2870
2743
  ] }) }),
2871
- /* @__PURE__ */ jsx16(SelectSeparator, {}),
2872
- /* @__PURE__ */ jsx16(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(SelectItem, { value: "change-password", children: [
2873
- /* @__PURE__ */ jsx16(KeyRound, { className: "mr-2 size-4" }),
2874
- /* @__PURE__ */ jsx16("span", { children: "Change Password" })
2744
+ /* @__PURE__ */ jsx15(SelectSeparator, {}),
2745
+ /* @__PURE__ */ jsx15(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(SelectItem, { value: "change-password", children: [
2746
+ /* @__PURE__ */ jsx15(KeyRound, { className: "mr-2 size-4" }),
2747
+ /* @__PURE__ */ jsx15("span", { children: "Change Password" })
2875
2748
  ] }) }),
2876
- /* @__PURE__ */ jsxs11(SelectItem, { value: "sign-out", onClick: handleSignOut, children: [
2877
- /* @__PURE__ */ jsx16(LogOut, { className: "mr-2 size-4" }),
2878
- /* @__PURE__ */ jsx16("span", { children: "Sign out" })
2749
+ /* @__PURE__ */ jsxs10(SelectItem, { value: "sign-out", onClick: handleSignOut, children: [
2750
+ /* @__PURE__ */ jsx15(LogOut, { className: "mr-2 size-4" }),
2751
+ /* @__PURE__ */ jsx15("span", { children: "Sign out" })
2879
2752
  ] })
2880
2753
  ] })
2881
2754
  ] }),
2882
- /* @__PURE__ */ jsx16(DialogOverlay, {}),
2883
- /* @__PURE__ */ jsxs11(DialogContent, { className, children: [
2884
- /* @__PURE__ */ jsx16(DialogHeader, { children: /* @__PURE__ */ jsx16(DialogTitle, { children: "Change Password" }) }),
2885
- /* @__PURE__ */ jsx16(
2755
+ /* @__PURE__ */ jsx15(DialogOverlay, {}),
2756
+ /* @__PURE__ */ jsxs10(DialogContent, { className, children: [
2757
+ /* @__PURE__ */ jsx15(DialogHeader, { children: /* @__PURE__ */ jsx15(DialogTitle, { children: "Change Password" }) }),
2758
+ /* @__PURE__ */ jsx15(
2886
2759
  PasswordChangeForm,
2887
2760
  {
2888
2761
  onSubmit: async ({ newPassword, confirmPassword }) => {
@@ -2901,60 +2774,54 @@ var UserMenu = React12.memo(function UserMenu2({
2901
2774
  ] });
2902
2775
  });
2903
2776
  var UserMenuLoading = React12.memo(function UserMenuLoading2() {
2904
- return /* @__PURE__ */ jsxs11("div", { className: "relative inline-block text-left", children: [
2905
- /* @__PURE__ */ jsxs11(
2906
- "button",
2907
- {
2908
- type: "button",
2909
- disabled: true,
2910
- className: "flex items-center space-x-2 px-3 py-2 text-sm font-medium text-muted-foreground bg-muted border border-input rounded-md",
2911
- children: [
2912
- /* @__PURE__ */ jsx16("div", { className: "w-6 h-6 rounded-full bg-muted animate-pulse" }),
2913
- /* @__PURE__ */ jsx16("span", { className: "truncate max-w-[150px]", children: "Loading..." }),
2914
- /* @__PURE__ */ jsx16(ChevronDown, { className: "w-4 h-4 text-muted-foreground" })
2915
- ]
2916
- }
2917
- ),
2918
- /* @__PURE__ */ jsx16("div", { role: "status", "aria-label": "Loading user menu", "aria-live": "polite", className: "w-6 h-6 rounded-full bg-muted animate-pulse" })
2919
- ] });
2777
+ return /* @__PURE__ */ jsxs10(
2778
+ Button,
2779
+ {
2780
+ type: "button",
2781
+ disabled: true,
2782
+ variant: "outline",
2783
+ className: "flex items-center space-x-2",
2784
+ "aria-label": "Loading user menu",
2785
+ children: [
2786
+ /* @__PURE__ */ jsx15(LoadingSpinner, { size: "sm", className: "inline-block mr-2" }),
2787
+ /* @__PURE__ */ jsx15("span", { className: "truncate max-w-[150px]", children: "Loading..." }),
2788
+ /* @__PURE__ */ jsx15(ChevronDown, { className: "w-4 h-4 text-muted-foreground" })
2789
+ ]
2790
+ }
2791
+ );
2920
2792
  });
2921
2793
  UserMenu.Loading = UserMenuLoading;
2922
2794
 
2923
2795
  // src/components/NavigationMenu/NavigationMenu.tsx
2924
- import * as React13 from "react";
2796
+ import * as React14 from "react";
2925
2797
  import { ChevronDown as ChevronDown2 } from "lucide-react";
2926
- import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
2927
- var NavigationMenu = React13.forwardRef(({
2798
+
2799
+ // src/components/NavigationMenu/useNavigationFiltering.ts
2800
+ import * as React13 from "react";
2801
+ function useNavigationFiltering({
2928
2802
  items,
2929
- mode = "dropdown",
2930
- currentPath,
2931
- onNavigate,
2932
- className,
2933
- disabled = false,
2934
- buttonText = "Menu",
2935
- showIcons = true,
2936
- navigationLabel = "Main navigation",
2937
- // NEW: Phase 2 - Enhanced Security Features
2938
- strictMode = true,
2939
- auditLog = true,
2940
- onNavigationAccessDenied,
2941
- onStrictModeViolation,
2942
2803
  itemsPreFiltered = false,
2943
- ...props
2944
- }, ref) => {
2945
- const [expandedItems, setExpandedItems] = React13.useState(/* @__PURE__ */ new Set());
2946
- const buttonRef = React13.useRef(null);
2804
+ auditLog = true
2805
+ }) {
2806
+ const [resolvedAppId, setResolvedAppId] = React13.useState(void 0);
2807
+ const previousFilteredItemsRef = React13.useRef([]);
2947
2808
  let authContext = null;
2948
2809
  try {
2949
2810
  authContext = useUnifiedAuth();
2950
2811
  } catch (error) {
2951
- logger.warn("NavigationMenu", "useUnifiedAuth not available, running in unauthenticated mode");
2812
+ logger.warn(
2813
+ "NavigationMenu",
2814
+ "useUnifiedAuth not available, running in unauthenticated mode"
2815
+ );
2952
2816
  }
2953
2817
  let rbacContext = null;
2954
2818
  try {
2955
2819
  rbacContext = useRBAC();
2956
2820
  } catch (error) {
2957
- logger.warn("NavigationMenu", "useRBAC not available, permission filtering disabled");
2821
+ logger.warn(
2822
+ "NavigationMenu",
2823
+ "useRBAC not available, permission filtering disabled"
2824
+ );
2958
2825
  }
2959
2826
  const eventLoadingRaw = authContext?.eventLoading;
2960
2827
  const eventLoading = eventLoadingRaw ?? false;
@@ -2964,11 +2831,9 @@ var NavigationMenu = React13.forwardRef(({
2964
2831
  const { selectedOrganisation } = authContext || {};
2965
2832
  const { resolvedScope, isLoading: scopeLoading, error: scopeError } = useResolvedScope({
2966
2833
  supabase: itemsPreFiltered ? null : supabase || null,
2967
- // Skip expensive resolution if pre-filtered
2968
2834
  selectedOrganisationId: itemsPreFiltered ? null : selectedOrganisation?.id || null,
2969
2835
  selectedEventId: itemsPreFiltered ? null : selectedEvent?.event_id || null
2970
2836
  });
2971
- const [resolvedAppId, setResolvedAppId] = React13.useState(void 0);
2972
2837
  React13.useEffect(() => {
2973
2838
  if (!scopeLoading && !resolvedScope?.appId && selectedOrganisation?.id && authContext?.appName && authContext?.user?.id && !resolvedAppId) {
2974
2839
  if (!authContext.user || !authContext.appName) {
@@ -2976,7 +2841,7 @@ var NavigationMenu = React13.forwardRef(({
2976
2841
  }
2977
2842
  const userId2 = authContext.user.id;
2978
2843
  const appName = authContext.appName;
2979
- import("./api-N774RPUA.js").then(({ resolveAppContext }) => {
2844
+ import("./api-IAGWF3ZG.js").then(({ resolveAppContext }) => {
2980
2845
  resolveAppContext({
2981
2846
  userId: userId2,
2982
2847
  appName
@@ -2984,11 +2849,19 @@ var NavigationMenu = React13.forwardRef(({
2984
2849
  if (result?.appId) {
2985
2850
  setResolvedAppId(result.appId);
2986
2851
  }
2987
- }).catch((error) => {
2852
+ }).catch(() => {
2988
2853
  });
2854
+ }).catch(() => {
2989
2855
  });
2990
2856
  }
2991
- }, [scopeLoading, resolvedScope?.appId, selectedOrganisation?.id, authContext?.appName, authContext?.user?.id, resolvedAppId]);
2857
+ }, [
2858
+ scopeLoading,
2859
+ resolvedScope?.appId,
2860
+ selectedOrganisation?.id,
2861
+ authContext?.appName,
2862
+ authContext?.user?.id,
2863
+ resolvedAppId
2864
+ ]);
2992
2865
  const effectiveScope = React13.useMemo(() => {
2993
2866
  if (resolvedScope?.organisationId) {
2994
2867
  return resolvedScope;
@@ -3019,17 +2892,17 @@ var NavigationMenu = React13.forwardRef(({
3019
2892
  };
3020
2893
  }, [scopeKey, effectiveScope]);
3021
2894
  const userId = authContext?.user?.id || "";
3022
- const { permissions: permissionMap, hasAnyPermission, isLoading: permissionsLoading, error: permissionsError } = usePermissions(
2895
+ const {
2896
+ permissions: permissionMap,
2897
+ hasAnyPermission,
2898
+ isLoading: permissionsLoading,
2899
+ error: permissionsError
2900
+ } = usePermissions(
3023
2901
  itemsPreFiltered ? null : userId,
3024
- // Pass null to trigger early return (empty string would wait 3s)
3025
2902
  itemsPreFiltered ? void 0 : stableScope.organisationId,
3026
- // Pass undefined to skip timeout
3027
2903
  itemsPreFiltered ? void 0 : stableScope.eventId,
3028
- // Skip if pre-filtered
3029
2904
  itemsPreFiltered ? void 0 : stableScope.appId
3030
- // Skip if pre-filtered
3031
2905
  );
3032
- const previousFilteredItemsRef = React13.useRef([]);
3033
2906
  const filteredItems = React13.useMemo(() => {
3034
2907
  if (itemsPreFiltered && items && items.length > 0) {
3035
2908
  const visibleItems = (items || []).filter((item) => !item.meta?.hidden);
@@ -3059,9 +2932,13 @@ var NavigationMenu = React13.forwardRef(({
3059
2932
  return [];
3060
2933
  }
3061
2934
  if (permissionsError) {
3062
- logger.warn("NavigationMenu", "Permission check error - showing no items for security", {
3063
- permissionsError: permissionsError?.message
3064
- });
2935
+ logger.warn(
2936
+ "NavigationMenu",
2937
+ "Permission check error - showing no items for security",
2938
+ {
2939
+ permissionsError: permissionsError?.message
2940
+ }
2941
+ );
3065
2942
  return [];
3066
2943
  }
3067
2944
  if (!permissionMap || Object.keys(permissionMap).length === 0) {
@@ -3087,7 +2964,7 @@ var NavigationMenu = React13.forwardRef(({
3087
2964
  if (item.permissions && item.permissions.length > 0 && !item.href) {
3088
2965
  const permissions = item.permissions.filter((p) => typeof p === "string").map((p) => p);
3089
2966
  if (permissions.length > 0) {
3090
- const hasPermission = hasAnyPermission(permissions);
2967
+ const hasPermission = hasAnyPermission?.(permissions);
3091
2968
  if (!hasPermission) {
3092
2969
  return false;
3093
2970
  }
@@ -3119,13 +2996,12 @@ var NavigationMenu = React13.forwardRef(({
3119
2996
  if (typeof item.accessLevel === "string") {
3120
2997
  const accessLevel = item.accessLevel.toLowerCase();
3121
2998
  const userEventRole = rbacContext.eventAppRole;
3122
- if (rbacContext.isSuperAdmin) {
3123
- } else {
2999
+ if (!rbacContext.isSuperAdmin) {
3124
3000
  const roleToAccessLevel = {
3125
- "viewer": "viewer",
3126
- "participant": "participant",
3127
- "planner": "planner",
3128
- "event_admin": "admin"
3001
+ viewer: "viewer",
3002
+ participant: "participant",
3003
+ planner: "planner",
3004
+ event_admin: "admin"
3129
3005
  };
3130
3006
  const userAccessLevel = userEventRole ? roleToAccessLevel[userEventRole] || "viewer" : null;
3131
3007
  const levelHierarchy = {
@@ -3178,7 +3054,6 @@ var NavigationMenu = React13.forwardRef(({
3178
3054
  }, [
3179
3055
  items,
3180
3056
  itemsPreFiltered,
3181
- // Add itemsPreFiltered to dependencies
3182
3057
  authContext,
3183
3058
  rbacContext,
3184
3059
  permissionMap,
@@ -3189,13 +3064,48 @@ var NavigationMenu = React13.forwardRef(({
3189
3064
  resolvedScope,
3190
3065
  effectiveScope,
3191
3066
  auditLog,
3192
- // Add event context state to dependencies so we re-check permissions when event context becomes available
3193
3067
  eventLoadingRaw,
3194
3068
  eventLoading,
3195
3069
  selectedEvent,
3196
3070
  orgContextReady,
3197
- selectedOrganisation?.id
3071
+ selectedOrganisation?.id,
3072
+ permissionsError,
3073
+ stableScope.organisationId,
3074
+ stableScope.eventId,
3075
+ stableScope.appId
3198
3076
  ]);
3077
+ return {
3078
+ authContext,
3079
+ rbacContext,
3080
+ filteredItems,
3081
+ permissionMap,
3082
+ hasAnyPermission: hasAnyPermission || null
3083
+ };
3084
+ }
3085
+
3086
+ // src/components/NavigationMenu/NavigationMenu.tsx
3087
+ import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
3088
+ var NavigationMenu = React14.forwardRef(({
3089
+ items,
3090
+ mode = "dropdown",
3091
+ currentPath,
3092
+ onNavigate,
3093
+ className,
3094
+ disabled = false,
3095
+ buttonText = "Menu",
3096
+ showIcons = true,
3097
+ navigationLabel = "Main navigation",
3098
+ // NEW: Phase 2 - Enhanced Security Features
3099
+ strictMode = true,
3100
+ auditLog = true,
3101
+ onNavigationAccessDenied,
3102
+ onStrictModeViolation,
3103
+ itemsPreFiltered = false,
3104
+ ...props
3105
+ }, ref) => {
3106
+ const [expandedItems, setExpandedItems] = React14.useState(/* @__PURE__ */ new Set());
3107
+ const buttonRef = React14.useRef(null);
3108
+ const { authContext, rbacContext, filteredItems, permissionMap, hasAnyPermission } = useNavigationFiltering({ items, itemsPreFiltered, auditLog });
3199
3109
  const handleHierarchicalKeyDown = (event, item) => {
3200
3110
  switch (event.key) {
3201
3111
  case "Enter":
@@ -3317,8 +3227,8 @@ var NavigationMenu = React13.forwardRef(({
3317
3227
  const hasChildren = item.children && item.children.length > 0;
3318
3228
  const isExpanded = expandedItems.has(item.id);
3319
3229
  const itemIsActive = isActiveItem(item);
3320
- return /* @__PURE__ */ jsx17("li", { role: "none", children: hasChildren ? /* @__PURE__ */ jsxs12("div", { children: [
3321
- /* @__PURE__ */ jsxs12(
3230
+ return /* @__PURE__ */ jsx16("li", { role: "none", children: hasChildren ? /* @__PURE__ */ jsxs11("div", { children: [
3231
+ /* @__PURE__ */ jsxs11(
3322
3232
  "button",
3323
3233
  {
3324
3234
  onClick: () => toggleExpanded(item.id),
@@ -3327,21 +3237,21 @@ var NavigationMenu = React13.forwardRef(({
3327
3237
  "aria-controls": `submenu-${item.id}`,
3328
3238
  "aria-current": itemIsActive ? "page" : void 0,
3329
3239
  children: [
3330
- /* @__PURE__ */ jsx17("span", { children: item.label }),
3331
- /* @__PURE__ */ jsx17(ChevronDown2, { "aria-hidden": "true" })
3240
+ /* @__PURE__ */ jsx16("span", { children: item.label }),
3241
+ /* @__PURE__ */ jsx16(ChevronDown2, { "aria-hidden": "true" })
3332
3242
  ]
3333
3243
  }
3334
3244
  ),
3335
- isExpanded && item.children && /* @__PURE__ */ jsx17(
3245
+ isExpanded && item.children && /* @__PURE__ */ jsx16(
3336
3246
  "ul",
3337
3247
  {
3338
3248
  id: `submenu-${item.id}`,
3339
3249
  role: "menu",
3340
3250
  "aria-label": `${item.label} submenu`,
3341
- children: item.children.map((child) => /* @__PURE__ */ jsx17(React13.Fragment, { children: renderHierarchicalItem(child, level + 1) }, child.id))
3251
+ children: item.children.map((child) => /* @__PURE__ */ jsx16(React14.Fragment, { children: renderHierarchicalItem(child, level + 1) }, child.id))
3342
3252
  }
3343
3253
  )
3344
- ] }) : /* @__PURE__ */ jsx17(
3254
+ ] }) : /* @__PURE__ */ jsx16(
3345
3255
  "a",
3346
3256
  {
3347
3257
  href: item.href || "#",
@@ -3359,26 +3269,26 @@ var NavigationMenu = React13.forwardRef(({
3359
3269
  ) });
3360
3270
  };
3361
3271
  if (mode === "dropdown") {
3362
- return /* @__PURE__ */ jsxs12(
3272
+ return /* @__PURE__ */ jsxs11(
3363
3273
  Select,
3364
3274
  {
3365
3275
  onValueChange: handleNavigationSelect,
3366
3276
  className,
3367
3277
  "data-testid": "navigation-menu-root",
3368
3278
  children: [
3369
- /* @__PURE__ */ jsx17(
3279
+ /* @__PURE__ */ jsx16(
3370
3280
  SelectTrigger,
3371
3281
  {
3372
3282
  ref: buttonRef,
3373
3283
  disabled,
3374
3284
  "aria-label": buttonText,
3375
3285
  "data-testid": "navigation-menu-trigger",
3376
- children: /* @__PURE__ */ jsx17(SelectValue, { placeholder: buttonText })
3286
+ children: /* @__PURE__ */ jsx16(SelectValue, { placeholder: buttonText })
3377
3287
  }
3378
3288
  ),
3379
- /* @__PURE__ */ jsx17(SelectContent, { children: filteredItems.map((item) => {
3289
+ /* @__PURE__ */ jsx16(SelectContent, { children: filteredItems.map((item) => {
3380
3290
  const isActive = isActiveItem(item);
3381
- return /* @__PURE__ */ jsx17(
3291
+ return /* @__PURE__ */ jsx16(
3382
3292
  SelectItem,
3383
3293
  {
3384
3294
  value: item.id,
@@ -3393,14 +3303,14 @@ var NavigationMenu = React13.forwardRef(({
3393
3303
  }
3394
3304
  );
3395
3305
  }
3396
- return /* @__PURE__ */ jsx17(
3306
+ return /* @__PURE__ */ jsx16(
3397
3307
  "nav",
3398
3308
  {
3399
3309
  ref,
3400
3310
  className,
3401
3311
  "aria-label": navigationLabel,
3402
3312
  ...props,
3403
- children: /* @__PURE__ */ jsx17("ul", { role: "menubar", children: filteredItems.map((item) => /* @__PURE__ */ jsx17(React13.Fragment, { children: renderHierarchicalItem(item, 0) }, item.id)) })
3313
+ children: /* @__PURE__ */ jsx16("ul", { role: "menubar", children: filteredItems.map((item) => /* @__PURE__ */ jsx16(React14.Fragment, { children: renderHierarchicalItem(item, 0) }, item.id)) })
3404
3314
  }
3405
3315
  );
3406
3316
  });
@@ -3408,7 +3318,7 @@ NavigationMenu.displayName = "NavigationMenu";
3408
3318
 
3409
3319
  // src/components/Header/Header.tsx
3410
3320
  import { Link } from "react-router-dom";
3411
- import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
3321
+ import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
3412
3322
  function Header({
3413
3323
  logoUrl,
3414
3324
  logoAlt = "Logo",
@@ -3420,54 +3330,43 @@ function Header({
3420
3330
  actions,
3421
3331
  userMenu,
3422
3332
  className,
3423
- showEventSelector = true,
3424
- showOrgSelector = false,
3333
+ showContextSelector = true,
3334
+ showOrganisations = true,
3335
+ showEvents = true,
3425
3336
  showUserMenu = true,
3426
3337
  currentPath,
3427
3338
  onNavigate,
3428
3339
  logoHref
3429
3340
  }) {
3430
- const OrganisationSelectorConditional = () => {
3431
- const { organisations, isContextReady } = useOrganisations();
3432
- if (!isContextReady || !organisations || organisations.length === 0) {
3433
- return null;
3434
- }
3435
- return /* @__PURE__ */ jsx18(
3436
- OrganisationSelector,
3437
- {
3438
- placeholder: "Select organisation",
3439
- className: "w-64",
3440
- "data-testid": "org-selector",
3441
- compact: true
3442
- }
3443
- );
3444
- };
3445
- return /* @__PURE__ */ jsx18("header", { className: cn(
3341
+ const shouldShowContextSelector = showContextSelector !== false;
3342
+ const { switchOrganisation } = useOrganisations();
3343
+ const { events, setSelectedEvent } = useEvents();
3344
+ return /* @__PURE__ */ jsx17("header", { className: cn(
3446
3345
  "w-full border-b border-main-200 h-16 shadow-sm bg-main-100 ",
3447
3346
  className
3448
- ), role: "banner", children: /* @__PURE__ */ jsxs13("nav", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto flex items-center gap-4 h-full", children: [
3449
- logo ? logoHref ? /* @__PURE__ */ jsx18(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: logo }) : logo : logoUrl ? logoHref ? /* @__PURE__ */ jsx18(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx18(
3347
+ ), role: "banner", children: /* @__PURE__ */ jsxs12("nav", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto grid grid-cols-[auto_1fr_auto_auto_auto_auto] items-center gap-4 h-full", children: [
3348
+ logo ? logoHref ? /* @__PURE__ */ jsx17(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: logo }) : logo : logoUrl ? logoHref ? /* @__PURE__ */ jsx17(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx17(
3450
3349
  "img",
3451
3350
  {
3452
3351
  src: logoUrl,
3453
3352
  alt: logoAlt || "Logo",
3454
3353
  className: "h-[2.15rem] w-auto max-w-[200px] object-contain rounded-md shadow-md bg-transparent"
3455
3354
  }
3456
- ) }) : /* @__PURE__ */ jsx18(
3355
+ ) }) : /* @__PURE__ */ jsx17(
3457
3356
  "img",
3458
3357
  {
3459
3358
  src: logoUrl,
3460
3359
  alt: logoAlt || "Logo",
3461
3360
  className: "h-[2.15rem] w-auto max-w-[200px] object-contain rounded-md shadow-md bg-transparent"
3462
3361
  }
3463
- ) : logoHref ? /* @__PURE__ */ jsx18(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx18(
3362
+ ) : logoHref ? /* @__PURE__ */ jsx17(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx17(
3464
3363
  "img",
3465
3364
  {
3466
3365
  src: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23000'/%3E%3Ctext x='16' y='20' text-anchor='middle' fill='white' font-family='Arial' font-size='14' font-weight='bold'%3EL%3C/text%3E%3C/svg%3E",
3467
3366
  alt: logoAlt || "Logo",
3468
3367
  className: "size-8 shadow-md"
3469
3368
  }
3470
- ) }) : /* @__PURE__ */ jsx18(
3369
+ ) }) : /* @__PURE__ */ jsx17(
3471
3370
  "img",
3472
3371
  {
3473
3372
  src: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23000'/%3E%3Ctext x='16' y='20' text-anchor='middle' fill='white' font-family='Arial' font-size='14' font-weight='bold'%3EL%3C/text%3E%3C/svg%3E",
@@ -3475,7 +3374,7 @@ function Header({
3475
3374
  className: "size-8 shadow-md"
3476
3375
  }
3477
3376
  ),
3478
- navItems && navItems.length > 0 && /* @__PURE__ */ jsx18(
3377
+ navItems && navItems.length > 0 && /* @__PURE__ */ jsx17(
3479
3378
  NavigationMenu,
3480
3379
  {
3481
3380
  items: navItems,
@@ -3486,33 +3385,44 @@ function Header({
3486
3385
  itemsPreFiltered: true
3487
3386
  }
3488
3387
  ),
3489
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-4 ml-auto", children: [
3490
- showOrgSelector ? /* @__PURE__ */ jsx18(OrganisationSelectorConditional, {}) : null,
3491
- showEventSelector ? /* @__PURE__ */ jsx18(
3492
- EventSelector,
3493
- {
3494
- placeholder: "Select event",
3495
- className: "w-96",
3496
- "data-testid": "event-selector"
3497
- }
3498
- ) : null,
3499
- actions,
3500
- showUserMenu && (userMenu ? userMenu : /* @__PURE__ */ jsx18(
3501
- UserMenu,
3502
- {
3503
- user: user || null,
3504
- onSignOut,
3505
- onChangePassword,
3506
- className: "w-70"
3507
- }
3508
- ))
3509
- ] })
3388
+ shouldShowContextSelector ? /* @__PURE__ */ jsx17(
3389
+ ContextSelector,
3390
+ {
3391
+ placeholder: "Select organisation or event",
3392
+ className: cn(
3393
+ "w-96",
3394
+ // Adjust width based on whether actions exist
3395
+ actions ? "col-span-1" : "col-span-2"
3396
+ ),
3397
+ showOrganisations,
3398
+ showEvents,
3399
+ onOrganisationSelect: async (org) => {
3400
+ setSelectedEvent(null);
3401
+ await switchOrganisation(org.id);
3402
+ },
3403
+ onEventSelect: (event) => {
3404
+ const fullEvent = events.find((e) => (e.event_id || e.id) === (event.event_id || event.id));
3405
+ setSelectedEvent(fullEvent || event);
3406
+ },
3407
+ compact: true
3408
+ }
3409
+ ) : null,
3410
+ actions,
3411
+ showUserMenu && (userMenu ? userMenu : /* @__PURE__ */ jsx17(
3412
+ UserMenu,
3413
+ {
3414
+ user: user || null,
3415
+ onSignOut,
3416
+ onChangePassword,
3417
+ className: "w-70"
3418
+ }
3419
+ ))
3510
3420
  ] }) });
3511
3421
  }
3512
3422
 
3513
3423
  // src/components/Footer/Footer.tsx
3514
- import React14 from "react";
3515
- import { Fragment as Fragment7, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
3424
+ import React15 from "react";
3425
+ import { Fragment as Fragment8, jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
3516
3426
  var FooterComponent = ({
3517
3427
  companyName = "Solvera Solutions Pty Ltd",
3518
3428
  year = (/* @__PURE__ */ new Date()).getFullYear(),
@@ -3523,28 +3433,29 @@ var FooterComponent = ({
3523
3433
  children
3524
3434
  }) => {
3525
3435
  const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
3526
- return /* @__PURE__ */ jsx19("footer", { className: cn("mt-8 py-6 flex justify-center border-t border-border bg-main-100", className), children: /* @__PURE__ */ jsxs14("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
3527
- logo && /* @__PURE__ */ jsx19("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
3528
- children && /* @__PURE__ */ jsx19(Fragment7, { children }),
3529
- /* @__PURE__ */ jsx19("span", { className: "text-muted-foreground", children: copyrightText }),
3530
- links && links.length > 0 && /* @__PURE__ */ jsx19("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx19("li", { children: /* @__PURE__ */ jsx19("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
3436
+ return /* @__PURE__ */ jsx18("footer", { className: cn("mt-8 py-6 flex justify-center border-t border-border bg-main-100", className), children: /* @__PURE__ */ jsxs13("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
3437
+ logo && /* @__PURE__ */ jsx18("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
3438
+ children && /* @__PURE__ */ jsx18(Fragment8, { children }),
3439
+ /* @__PURE__ */ jsx18("span", { className: "text-muted-foreground", children: copyrightText }),
3440
+ links && links.length > 0 && /* @__PURE__ */ jsx18("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsx18("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
3531
3441
  ] }) });
3532
3442
  };
3533
3443
  FooterComponent.displayName = "Footer";
3534
- var Footer = React14.memo(FooterComponent);
3444
+ var Footer = React15.memo(FooterComponent);
3535
3445
  Footer.displayName = "Footer";
3536
3446
 
3537
3447
  // src/components/PaceAppLayout/PaceAppLayout.tsx
3538
- import { useState as useState12, useEffect as useEffect8, useMemo as useMemo9 } from "react";
3448
+ import { useState as useState12, useEffect as useEffect7, useMemo as useMemo8 } from "react";
3539
3449
  import { Outlet, useNavigate, useLocation } from "react-router-dom";
3540
- import { Fragment as Fragment8, jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
3450
+ import { Fragment as Fragment9, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
3541
3451
  var EMPTY_PAGE_ID_MAPPING = {};
3542
3452
  var EMPTY_ROUTE_PERMISSIONS = {};
3543
3453
  function PaceAppLayout({
3544
3454
  appName,
3545
3455
  navItems,
3546
- showEventSelector,
3547
- showOrgSelector,
3456
+ showContextSelector = true,
3457
+ showOrganisations = true,
3458
+ showEvents = true,
3548
3459
  headerActions,
3549
3460
  customLogo,
3550
3461
  logoHref = "/dashboard",
@@ -3581,7 +3492,7 @@ function PaceAppLayout({
3581
3492
  const { isSuperAdmin: isSuperAdminFromRBAC, isLoading: rbacLoading } = useRBAC();
3582
3493
  const [isSuperAdminDirect, setIsSuperAdminDirect] = useState12(false);
3583
3494
  const [isCheckingSuperAdminDirect, setIsCheckingSuperAdminDirect] = useState12(false);
3584
- useEffect8(() => {
3495
+ useEffect7(() => {
3585
3496
  const checkSuperAdminDirect = async () => {
3586
3497
  if (!user?.id) {
3587
3498
  setIsSuperAdminDirect(false);
@@ -3594,8 +3505,8 @@ function PaceAppLayout({
3594
3505
  }
3595
3506
  setIsCheckingSuperAdminDirect(true);
3596
3507
  try {
3597
- const superAdminStatus = await isSuperAdmin(user.id);
3598
- setIsSuperAdminDirect(superAdminStatus);
3508
+ const superAdminStatus2 = await isSuperAdmin(user.id);
3509
+ setIsSuperAdminDirect(superAdminStatus2);
3599
3510
  } catch (error) {
3600
3511
  logger.error("PaceAppLayout", "Error checking super admin status directly", { userId: user?.id, error });
3601
3512
  setIsSuperAdminDirect(false);
@@ -3624,7 +3535,7 @@ function PaceAppLayout({
3624
3535
  const scopeOrgId = resolvedScope?.organisationId || selectedOrganisation?.id || "";
3625
3536
  const scopeEventId = resolvedScope?.eventId || selectedEvent?.event_id || void 0;
3626
3537
  const scopeAppId = resolvedScope?.appId || resolvedAppId || void 0;
3627
- const scope = useMemo9(() => {
3538
+ const scope = useMemo8(() => {
3628
3539
  const newScope = {};
3629
3540
  if (scopeOrgId) {
3630
3541
  newScope.organisationId = scopeOrgId;
@@ -3637,19 +3548,19 @@ function PaceAppLayout({
3637
3548
  }
3638
3549
  return newScope;
3639
3550
  }, [scopeOrgId, scopeEventId, scopeAppId]);
3640
- const defaultNavItems = useMemo9(() => [
3551
+ const defaultNavItems = useMemo8(() => [
3641
3552
  { id: "home", label: "Home", href: "/", icon: "Home" },
3642
3553
  { id: "dashboard", label: "Dashboard", href: "/dashboard", icon: "LayoutDashboard" },
3643
3554
  { id: "settings", label: "Settings", href: "/settings", icon: "Settings" },
3644
3555
  { id: "ui-showcase", label: "UI Showcase", href: "/ui-showcase", icon: "Component" },
3645
3556
  { id: "data-table-showcase", label: "DataTable Showcase", href: "/data-table-showcase", icon: "Table" }
3646
3557
  ], []);
3647
- const baseMenuItems = useMemo9(() => navItems || defaultNavItems, [navItems]);
3648
- const currentRoutePermission = useMemo9(() => {
3558
+ const baseMenuItems = useMemo8(() => navItems || defaultNavItems, [navItems]);
3559
+ const currentRoutePermission = useMemo8(() => {
3649
3560
  const currentPath = location.pathname;
3650
3561
  return routePermissions[currentPath] || defaultPermission;
3651
3562
  }, [location.pathname, routePermissions, defaultPermission]);
3652
- const currentPageId = useMemo9(() => {
3563
+ const currentPageId = useMemo8(() => {
3653
3564
  const currentPath = location.pathname;
3654
3565
  if (pageIdMapping[currentPath]) {
3655
3566
  return pageIdMapping[currentPath];
@@ -3657,7 +3568,7 @@ function PaceAppLayout({
3657
3568
  const pathSegments = currentPath.slice(1).split("/").filter(Boolean);
3658
3569
  return pathSegments[0] || "";
3659
3570
  }, [location.pathname, pageIdMapping]);
3660
- const currentPermission = useMemo9(() => {
3571
+ const currentPermission = useMemo8(() => {
3661
3572
  if (!enforcePermissions || !currentPageId) {
3662
3573
  return "";
3663
3574
  }
@@ -3665,6 +3576,7 @@ function PaceAppLayout({
3665
3576
  return permissionString;
3666
3577
  }, [enforcePermissions, currentRoutePermission, currentPageId]);
3667
3578
  const shouldCheckPermission = enforcePermissions && !!currentPermission && !!currentPageId;
3579
+ const superAdminStatus = isSuperAdminFromRBAC ? true : isCheckingSuperAdminDirect ? null : isSuperAdminDirect;
3668
3580
  const { can: canFromHook, isLoading: isCheckingPermission, error: permissionError } = useCan(
3669
3581
  user?.id || "",
3670
3582
  scope,
@@ -3672,12 +3584,14 @@ function PaceAppLayout({
3672
3584
  shouldCheckPermission ? currentPageId : "",
3673
3585
  true,
3674
3586
  // useCache
3587
+ superAdminStatus,
3588
+ // Pass super admin status to avoid duplicate check
3675
3589
  appName
3676
3590
  // Pass appName for PORTAL/ADMIN special case
3677
3591
  );
3678
3592
  const can = isSuperAdmin2 ? true : canFromHook;
3679
3593
  const hasPermission = enforcePermissions ? can : true;
3680
- useEffect8(() => {
3594
+ useEffect7(() => {
3681
3595
  if (!enforcePermissions) {
3682
3596
  return;
3683
3597
  }
@@ -3701,7 +3615,7 @@ function PaceAppLayout({
3701
3615
  }
3702
3616
  }, [enforcePermissions, can, isCheckingPermission, isSuperAdmin2, currentPageId, currentRoutePermission, user?.id, strictMode, auditLog, onPageAccessDenied, onStrictModeViolation]);
3703
3617
  const [filteredMenuItems, setFilteredMenuItems] = useState12(baseMenuItems);
3704
- useEffect8(() => {
3618
+ useEffect7(() => {
3705
3619
  let isMounted = true;
3706
3620
  const filterItems = async () => {
3707
3621
  if (!user?.id) {
@@ -3727,7 +3641,7 @@ function PaceAppLayout({
3727
3641
  return;
3728
3642
  }
3729
3643
  try {
3730
- const { isSuperAdmin: checkSuperAdminDynamic } = await import("./api-N774RPUA.js");
3644
+ const { isSuperAdmin: checkSuperAdminDynamic } = await import("./api-IAGWF3ZG.js");
3731
3645
  const isSuper = await checkSuperAdminDynamic(user.id);
3732
3646
  if (isSuper) {
3733
3647
  if (isMounted) {
@@ -3742,7 +3656,7 @@ function PaceAppLayout({
3742
3656
  }
3743
3657
  }
3744
3658
  try {
3745
- const { getPermissionMap } = await import("./api-N774RPUA.js");
3659
+ const { getPermissionMap } = await import("./api-IAGWF3ZG.js");
3746
3660
  const permissionScope = {
3747
3661
  organisationId: currentScope.organisationId,
3748
3662
  eventId: currentScope.eventId,
@@ -3753,16 +3667,80 @@ function PaceAppLayout({
3753
3667
  userId: user.id,
3754
3668
  scope: permissionScope
3755
3669
  });
3756
- const filtered = baseMenuItems.map((item) => {
3757
- if (!item.href) return { item, hasAccess: true };
3758
- const pageId = pageIdMapping[item.href] || (item.href === "/" ? "dashboard" : item.href.slice(1)) || "dashboard";
3759
- const permission = routePermissions[item.href] || defaultPermission;
3760
- const fullPermission = permission.includes(":") ? permission : pageId ? `${permission}:page.${pageId}` : permission;
3761
- const hasAccess = permissionMap["*"] === true || permissionMap[fullPermission] === true;
3762
- return { item, hasAccess };
3763
- });
3670
+ const { getPageScopeType } = await import("./api-IAGWF3ZG.js");
3671
+ const effectiveAppId = currentScope.appId || resolvedAppId;
3672
+ const effectiveAppName = appName;
3673
+ const hasEventContext = !!currentScope.eventId;
3674
+ const hasOrgContext = !!currentScope.organisationId;
3675
+ const filtered = await Promise.all(
3676
+ baseMenuItems.map(async (item) => {
3677
+ if (!item.href) return { item, hasAccess: true, matchesScope: true, scopeCheckError: false };
3678
+ const pageId = pageIdMapping[item.href] || (item.href === "/" ? "dashboard" : item.href.slice(1)) || "dashboard";
3679
+ const permission = routePermissions[item.href] || defaultPermission;
3680
+ const fullPermission = permission.includes(":") ? permission : pageId ? `${permission}:page.${pageId}` : permission;
3681
+ const hasAccess = permissionMap["*"] === true || permissionMap[fullPermission] === true;
3682
+ let matchesScope = true;
3683
+ let scopeCheckError = false;
3684
+ if (effectiveAppId || effectiveAppName) {
3685
+ try {
3686
+ const pageScopeType = await getPageScopeType(
3687
+ pageId,
3688
+ effectiveAppId,
3689
+ effectiveAppName
3690
+ );
3691
+ if (hasEventContext) {
3692
+ matchesScope = pageScopeType === "event" || pageScopeType === "both";
3693
+ } else if (hasOrgContext) {
3694
+ matchesScope = pageScopeType === "organisation" || pageScopeType === "both";
3695
+ } else {
3696
+ matchesScope = true;
3697
+ }
3698
+ } catch (error) {
3699
+ scopeCheckError = true;
3700
+ logger.warn("PaceAppLayout", "Failed to get page scope type for navigation filtering", {
3701
+ pageId,
3702
+ href: item.href,
3703
+ contextType: hasEventContext ? "event" : hasOrgContext ? "organisation" : "none",
3704
+ error: error instanceof Error ? error.message : String(error),
3705
+ note: "Allowing page to prevent navigation from disappearing - this may indicate missing scope_type in database"
3706
+ });
3707
+ matchesScope = true;
3708
+ }
3709
+ } else {
3710
+ matchesScope = true;
3711
+ }
3712
+ return { item, hasAccess, matchesScope, scopeCheckError };
3713
+ })
3714
+ );
3764
3715
  if (!isMounted) return;
3765
- const accessibleItems = filtered.filter(({ hasAccess }) => hasAccess).map(({ item }) => item);
3716
+ const accessibleItems = filtered.filter(({ hasAccess, matchesScope }) => hasAccess && matchesScope).map(({ item }) => item);
3717
+ if (accessibleItems.length === 0 && filtered.length > 0) {
3718
+ const itemsWithPermissions = filtered.filter(({ hasAccess }) => hasAccess);
3719
+ const itemsFilteredByScope = filtered.filter(({ hasAccess, matchesScope }) => hasAccess && !matchesScope);
3720
+ const itemsWithScopeErrors = filtered.filter(({ hasAccess, scopeCheckError }) => hasAccess && scopeCheckError);
3721
+ if (itemsWithPermissions.length > 0 && itemsWithScopeErrors.length === itemsWithPermissions.length) {
3722
+ logger.warn("PaceAppLayout", "Scope checking failed for all items - falling back to permission-only filtering", {
3723
+ contextType: hasEventContext ? "event" : hasOrgContext ? "organisation" : "none",
3724
+ totalItems: baseMenuItems.length,
3725
+ itemsWithPermissions: itemsWithPermissions.length,
3726
+ scopeCheckErrorCount: itemsWithScopeErrors.length,
3727
+ note: "Showing items based on permissions only - scope filtering disabled due to errors. This may indicate database issues or missing scope_type values."
3728
+ });
3729
+ const fallbackItems = filtered.filter(({ hasAccess }) => hasAccess).map(({ item }) => item);
3730
+ if (isMounted && fallbackItems.length > 0) {
3731
+ setFilteredMenuItems(fallbackItems);
3732
+ return;
3733
+ }
3734
+ } else if (itemsWithPermissions.length > 0 && itemsFilteredByScope.length === itemsWithPermissions.length) {
3735
+ logger.info("PaceAppLayout", "All navigation items filtered out by scope type", {
3736
+ contextType: hasEventContext ? "event" : hasOrgContext ? "organisation" : "none",
3737
+ totalItems: baseMenuItems.length,
3738
+ itemsWithPermissions: itemsWithPermissions.length,
3739
+ itemsFilteredByScope: itemsFilteredByScope.length,
3740
+ note: "All pages appear to be scoped for a different context type - this is expected behavior. Navigation will be empty until user selects the appropriate context."
3741
+ });
3742
+ }
3743
+ }
3766
3744
  setFilteredMenuItems(accessibleItems);
3767
3745
  } catch (error) {
3768
3746
  logger.error("PaceAppLayout", "Failed to load permission map for navigation filtering", { userId: user?.id, error });
@@ -3775,8 +3753,8 @@ function PaceAppLayout({
3775
3753
  return () => {
3776
3754
  isMounted = false;
3777
3755
  };
3778
- }, [baseMenuItems, pageIdMapping, routePermissions, defaultPermission, can, user?.id, scope, scopeLoading, contextAppId, resolvedScope?.appId, selectedOrganisation?.id]);
3779
- useEffect8(() => {
3756
+ }, [baseMenuItems, pageIdMapping, routePermissions, defaultPermission, can, user?.id, scope, scopeLoading, contextAppId, resolvedScope?.appId, selectedOrganisation?.id, selectedEvent?.event_id, appName]);
3757
+ useEffect7(() => {
3780
3758
  if (!roleBasedRouting || routeConfig.length === 0) return;
3781
3759
  let isMounted = true;
3782
3760
  const checkRouteAccess = async () => {
@@ -3798,7 +3776,7 @@ function PaceAppLayout({
3798
3776
  let hasAccess = true;
3799
3777
  if (currentRoute.pageId && currentRoute.permissions && currentRoute.permissions.length > 0) {
3800
3778
  try {
3801
- const { isPermittedCached } = await import("./api-N774RPUA.js");
3779
+ const { isPermittedCached } = await import("./api-IAGWF3ZG.js");
3802
3780
  const hasPagePermission = await isPermittedCached({
3803
3781
  userId: user?.id || "",
3804
3782
  scope,
@@ -3814,7 +3792,7 @@ function PaceAppLayout({
3814
3792
  }
3815
3793
  }
3816
3794
  if (hasAccess && currentRoute.roles && currentRoute.roles.length > 0 && user?.id) {
3817
- const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-ATAP5UTR.js");
3795
+ const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-KAGUYQ4J.js");
3818
3796
  hasAccess = true;
3819
3797
  }
3820
3798
  if (!isMounted) return;
@@ -3845,53 +3823,67 @@ function PaceAppLayout({
3845
3823
  };
3846
3824
  }, [roleBasedRouting, routeConfig, location.pathname, strictMode, user?.id, fallbackRoute, scope, navigate, auditLog, onRouteAccessDenied, onRouteStrictModeViolation]);
3847
3825
  const handleSignOut = async () => {
3848
- await signOut();
3826
+ try {
3827
+ await signOut();
3828
+ } catch (error) {
3829
+ logger.error("PaceAppLayout", "Failed to sign out", { error: error instanceof Error ? error.message : String(error) });
3830
+ }
3849
3831
  };
3850
3832
  const handleChangePassword = async (newPassword, confirmPassword) => {
3851
- const result = await updatePassword(newPassword);
3852
- if (result?.error) {
3853
- logger.error("PaceAppLayout", "Failed to change password", { error: result.error.message });
3833
+ try {
3834
+ const result = await updatePassword(newPassword);
3835
+ if (result?.error) {
3836
+ logger.error("PaceAppLayout", "Failed to change password", { error: result.error.message });
3837
+ return {
3838
+ error: {
3839
+ message: result.error.message,
3840
+ code: result.error.name || "PASSWORD_UPDATE_ERROR"
3841
+ }
3842
+ };
3843
+ }
3844
+ return {};
3845
+ } catch (error) {
3846
+ logger.error("PaceAppLayout", "Failed to change password", { error: error instanceof Error ? error.message : String(error) });
3854
3847
  return {
3855
3848
  error: {
3856
- message: result.error.message,
3857
- code: result.error.name || "PASSWORD_UPDATE_ERROR"
3849
+ message: error instanceof Error ? error.message : "An unexpected error occurred",
3850
+ code: "PASSWORD_UPDATE_ERROR"
3858
3851
  }
3859
3852
  };
3860
3853
  }
3861
- return {};
3862
3854
  };
3863
3855
  if (user?.id && organisationLoading && !isSuperAdmin2 && !isCheckingSuperAdminDirect && !rbacLoading && !selectedOrganisationId) {
3864
- return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
3865
- /* @__PURE__ */ jsx20("div", { className: "animate-spin rounded-full size-8 border-b-2 border-sec-900 mx-auto mb-4" }),
3866
- /* @__PURE__ */ jsx20("p", { className: "text-sec-600", children: "Loading organisation context..." })
3856
+ return /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs14("div", { className: "text-center", children: [
3857
+ /* @__PURE__ */ jsx19("div", { className: "animate-spin rounded-full size-8 border-b-2 border-sec-900 mx-auto mb-4" }),
3858
+ /* @__PURE__ */ jsx19("p", { className: "text-sec-600", children: "Loading organisation context..." })
3867
3859
  ] }) });
3868
3860
  }
3869
3861
  if (enforcePermissions && isCheckingPermission) {
3870
- return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
3871
- /* @__PURE__ */ jsx20("div", { className: "animate-spin rounded-full size-8 border-b-2 border-sec-900 mx-auto mb-4" }),
3872
- /* @__PURE__ */ jsx20("p", { className: "text-sec-600", children: "Checking permissions..." })
3862
+ return /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs14("div", { className: "text-center", children: [
3863
+ /* @__PURE__ */ jsx19("div", { className: "animate-spin rounded-full size-8 border-b-2 border-sec-900 mx-auto mb-4" }),
3864
+ /* @__PURE__ */ jsx19("p", { className: "text-sec-600", children: "Checking permissions..." })
3873
3865
  ] }) });
3874
3866
  }
3875
3867
  if (enforcePermissions && permissionError && !isSuperAdmin2) {
3876
- return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
3877
- /* @__PURE__ */ jsx20("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Permission Error" }),
3878
- /* @__PURE__ */ jsx20("p", { className: "text-sec-600 mb-4", children: permissionError.message }),
3879
- /* @__PURE__ */ jsx20(Button, { onClick: () => navigate("/"), children: "Go Home" })
3868
+ return /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs14("div", { className: "text-center", children: [
3869
+ /* @__PURE__ */ jsx19("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Permission Error" }),
3870
+ /* @__PURE__ */ jsx19("p", { className: "text-sec-600 mb-4", children: permissionError.message }),
3871
+ /* @__PURE__ */ jsx19(Button, { onClick: () => navigate("/"), children: "Go Home" })
3880
3872
  ] }) });
3881
3873
  }
3882
3874
  if (enforcePermissions && hasPermission === false && !isCheckingSuperAdminDirect && !isSuperAdmin2) {
3883
3875
  if (enforcePagePermissions && pagePermissionFallback) {
3884
- return /* @__PURE__ */ jsx20(Fragment8, { children: pagePermissionFallback });
3876
+ return /* @__PURE__ */ jsx19(Fragment9, { children: pagePermissionFallback });
3885
3877
  }
3886
3878
  if (permissionFallback) {
3887
- return /* @__PURE__ */ jsx20(Fragment8, { children: permissionFallback });
3879
+ return /* @__PURE__ */ jsx19(Fragment9, { children: permissionFallback });
3888
3880
  }
3889
- return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
3890
- /* @__PURE__ */ jsx20("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Access Denied" }),
3891
- /* @__PURE__ */ jsx20("p", { className: "text-sec-600 mb-4", children: "You don't have permission to access this page." }),
3892
- /* @__PURE__ */ jsxs15("div", { className: "flex gap-2 justify-center", children: [
3893
- /* @__PURE__ */ jsx20(Button, { onClick: () => navigate("/"), children: "Go Home" }),
3894
- /* @__PURE__ */ jsx20(
3881
+ return /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs14("div", { className: "text-center", children: [
3882
+ /* @__PURE__ */ jsx19("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Access Denied" }),
3883
+ /* @__PURE__ */ jsx19("p", { className: "text-sec-600 mb-4", children: "You don't have permission to access this page." }),
3884
+ /* @__PURE__ */ jsxs14("div", { className: "flex gap-2 justify-center", children: [
3885
+ /* @__PURE__ */ jsx19(Button, { onClick: () => navigate("/"), children: "Go Home" }),
3886
+ /* @__PURE__ */ jsx19(
3895
3887
  Button,
3896
3888
  {
3897
3889
  variant: "outline",
@@ -3905,8 +3897,8 @@ function PaceAppLayout({
3905
3897
  ] })
3906
3898
  ] }) });
3907
3899
  }
3908
- return /* @__PURE__ */ jsxs15(Fragment8, { children: [
3909
- /* @__PURE__ */ jsx20(
3900
+ return /* @__PURE__ */ jsxs14(Fragment9, { children: [
3901
+ /* @__PURE__ */ jsx19(
3910
3902
  Header,
3911
3903
  {
3912
3904
  logo: customLogo || void 0,
@@ -3925,21 +3917,22 @@ function PaceAppLayout({
3925
3917
  navigate(item.href);
3926
3918
  }
3927
3919
  },
3928
- showEventSelector,
3929
- showOrgSelector,
3920
+ showContextSelector,
3921
+ showOrganisations,
3922
+ showEvents,
3930
3923
  showUserMenu,
3931
3924
  className: headerClassName || "sticky top-0 z-[40] w-full"
3932
3925
  }
3933
3926
  ),
3934
- /* @__PURE__ */ jsx20("main", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: /* @__PURE__ */ jsx20(Outlet, {}) }),
3935
- /* @__PURE__ */ jsx20(Footer, {})
3927
+ /* @__PURE__ */ jsx19("main", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: /* @__PURE__ */ jsx19(Outlet, {}) }),
3928
+ /* @__PURE__ */ jsx19(Footer, {})
3936
3929
  ] });
3937
3930
  }
3938
3931
 
3939
3932
  // src/components/PaceLoginPage/PaceLoginPage.tsx
3940
- import { useEffect as useEffect9, useState as useState13, useContext as useContext2 } from "react";
3933
+ import { useEffect as useEffect8, useState as useState13, useContext as useContext2 } from "react";
3941
3934
  import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
3942
- import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
3935
+ import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
3943
3936
  var PaceLoginPage = ({
3944
3937
  appName = "Pace",
3945
3938
  onSuccessRedirectPath = "/",
@@ -3953,16 +3946,16 @@ var PaceLoginPage = ({
3953
3946
  const [isCheckingAccess, setIsCheckingAccess] = useState13(false);
3954
3947
  const eventServiceContext = useContext2(EventServiceContext);
3955
3948
  const eventService = eventServiceContext?.eventService || null;
3956
- useEffect9(() => {
3949
+ useEffect8(() => {
3957
3950
  clearPalette();
3958
3951
  }, []);
3959
- useEffect9(() => {
3952
+ useEffect8(() => {
3960
3953
  const isOnLoginPage = location.pathname === "/login" || location.pathname.startsWith("/login");
3961
3954
  if (isOnLoginPage) {
3962
3955
  clearPalette();
3963
3956
  }
3964
3957
  }, [location.pathname]);
3965
- useEffect9(() => {
3958
+ useEffect8(() => {
3966
3959
  const restoreEvent = async () => {
3967
3960
  try {
3968
3961
  const isOnLoginPage = window.location.pathname === "/login" || window.location.pathname.startsWith("/login");
@@ -3977,7 +3970,7 @@ var PaceLoginPage = ({
3977
3970
  }, 100);
3978
3971
  return () => clearTimeout(timeoutId);
3979
3972
  }, [eventService]);
3980
- useEffect9(() => {
3973
+ useEffect8(() => {
3981
3974
  if (!requireAppAccess || !isAuthenticated || isLoading || !user || !supabase) {
3982
3975
  return;
3983
3976
  }
@@ -4065,8 +4058,8 @@ var PaceLoginPage = ({
4065
4058
  setIsSigningIn(false);
4066
4059
  }
4067
4060
  };
4068
- return /* @__PURE__ */ jsxs16("main", { className: "min-h-screen grid mx-auto w-fit content-center justify-items-center gap-y-8", "aria-label": `${appName} Login Page`, children: [
4069
- /* @__PURE__ */ jsx21(
4061
+ return /* @__PURE__ */ jsxs15("main", { className: "min-h-screen grid mx-auto w-fit content-center justify-items-center gap-y-8", "aria-label": `${appName} Login Page`, children: [
4062
+ /* @__PURE__ */ jsx20(
4070
4063
  "img",
4071
4064
  {
4072
4065
  src: `/${appName.toLowerCase()}_logo_square.svg`,
@@ -4074,7 +4067,7 @@ var PaceLoginPage = ({
4074
4067
  className: "h-48"
4075
4068
  }
4076
4069
  ),
4077
- /* @__PURE__ */ jsx21(
4070
+ /* @__PURE__ */ jsx20(
4078
4071
  LoginForm,
4079
4072
  {
4080
4073
  className: "w-md",
@@ -4088,21 +4081,21 @@ var PaceLoginPage = ({
4088
4081
  ),
4089
4082
  (() => {
4090
4083
  const benign = !!(authError && (authError.name === "AuthSessionMissingError" || /Auth session missing/i.test(authError.message)));
4091
- return authError && !benign ? /* @__PURE__ */ jsx21("em", { className: "mt-4 text-destructive text-center", children: authError.message }) : null;
4084
+ return authError && !benign ? /* @__PURE__ */ jsx20("em", { className: "mt-4 text-destructive text-center", children: authError.message }) : null;
4092
4085
  })(),
4093
- accessError && /* @__PURE__ */ jsx21("em", { className: "mt-4 text-destructive text-center", children: accessError }),
4094
- isCheckingAccess && /* @__PURE__ */ jsx21("em", { className: "mt-4 text-muted-foreground text-center", children: "Checking permissions..." })
4086
+ accessError && /* @__PURE__ */ jsx20("em", { className: "mt-4 text-destructive text-center", children: accessError }),
4087
+ isCheckingAccess && /* @__PURE__ */ jsx20("em", { className: "mt-4 text-muted-foreground text-center", children: "Checking permissions..." })
4095
4088
  ] });
4096
4089
  };
4097
4090
 
4098
4091
  // src/components/SessionRestorationLoader/SessionRestorationLoader.tsx
4099
- import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
4092
+ import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
4100
4093
  var SessionRestorationLoader = ({
4101
4094
  message = "Restoring session...",
4102
4095
  className
4103
4096
  }) => {
4104
- return /* @__PURE__ */ jsxs17(
4105
- "div",
4097
+ return /* @__PURE__ */ jsxs16(
4098
+ Alert,
4106
4099
  {
4107
4100
  className: cn(
4108
4101
  "flex flex-col items-center justify-center h-screen w-full gap-4 text-center p-4 bg-background",
@@ -4112,20 +4105,19 @@ var SessionRestorationLoader = ({
4112
4105
  "aria-live": "polite",
4113
4106
  "aria-label": message,
4114
4107
  children: [
4115
- /* @__PURE__ */ jsx22(LoadingSpinner, { size: "lg" }),
4116
- /* @__PURE__ */ jsx22("div", { className: "text-sm text-sec-600", children: message })
4108
+ /* @__PURE__ */ jsx21(LoadingSpinner, { size: "lg" }),
4109
+ /* @__PURE__ */ jsx21("span", { className: "text-sm text-sec-600", children: message })
4117
4110
  ]
4118
4111
  }
4119
4112
  );
4120
4113
  };
4121
4114
 
4122
4115
  // src/components/ProtectedRoute/ProtectedRoute.tsx
4123
- import { useMemo as useMemo10, useEffect as useEffect10, useRef as useRef8, useState as useState14 } from "react";
4116
+ import { useMemo as useMemo9, useEffect as useEffect9, useRef as useRef8, useState as useState14 } from "react";
4124
4117
  import { Navigate, Outlet as Outlet2 } from "react-router-dom";
4125
- import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
4118
+ import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
4126
4119
  function ProtectedRoute({
4127
4120
  requireEvent = false,
4128
- allowSuperAdminBypass = false,
4129
4121
  noEventsFallback,
4130
4122
  loadingFallback,
4131
4123
  loginPath = "/login"
@@ -4140,14 +4132,14 @@ function ProtectedRoute({
4140
4132
  const wasAuthenticatedRef = useRef8(false);
4141
4133
  const [shouldRedirect, setShouldRedirect] = useState14(false);
4142
4134
  const tabJustBecameVisibleRef = useRef8(false);
4143
- useEffect10(() => {
4135
+ useEffect9(() => {
4144
4136
  if (isAuthenticated) {
4145
4137
  wasAuthenticatedRef.current = true;
4146
4138
  setShouldRedirect(false);
4147
4139
  tabJustBecameVisibleRef.current = false;
4148
4140
  }
4149
4141
  }, [isAuthenticated]);
4150
- useEffect10(() => {
4142
+ useEffect9(() => {
4151
4143
  if (typeof document === "undefined") return;
4152
4144
  let timeoutId = null;
4153
4145
  let wasHidden = document.hidden;
@@ -4191,13 +4183,13 @@ function ProtectedRoute({
4191
4183
  }
4192
4184
  };
4193
4185
  }, [isAuthenticated]);
4194
- useEffect10(() => {
4186
+ useEffect9(() => {
4195
4187
  if (isAuthenticated) {
4196
4188
  setShouldRedirect(false);
4197
4189
  tabJustBecameVisibleRef.current = false;
4198
4190
  }
4199
4191
  }, [isAuthenticated]);
4200
- const isRestoringSession = useMemo10(() => {
4192
+ const isRestoringSession = useMemo9(() => {
4201
4193
  return sessionRestoration.isRestoring && !sessionRestoration.restorationComplete && !sessionRestoration.restorationError && !sessionRestoration.hasTimedOut;
4202
4194
  }, [
4203
4195
  sessionRestoration.isRestoring,
@@ -4206,13 +4198,13 @@ function ProtectedRoute({
4206
4198
  sessionRestoration.hasTimedOut
4207
4199
  ]);
4208
4200
  if (isRestoringSession) {
4209
- return /* @__PURE__ */ jsx23(SessionRestorationLoader, {});
4201
+ return /* @__PURE__ */ jsx22(SessionRestorationLoader, {});
4210
4202
  }
4211
4203
  if (requireEvent && eventLoading) {
4212
- return /* @__PURE__ */ jsx23(Outlet2, {});
4204
+ return /* @__PURE__ */ jsx22(Outlet2, {});
4213
4205
  }
4214
4206
  if (isLoading && !sessionRestoration.hasTimedOut) {
4215
- return loadingFallback || /* @__PURE__ */ jsx23("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx23(LoadingSpinner, {}) });
4207
+ return loadingFallback || /* @__PURE__ */ jsx22("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx22(LoadingSpinner, {}) });
4216
4208
  }
4217
4209
  if (!isAuthenticated) {
4218
4210
  if (sessionRestoration.hasTimedOut || sessionRestoration.restorationError) {
@@ -4220,41 +4212,41 @@ function ProtectedRoute({
4220
4212
  timedOut: sessionRestoration.hasTimedOut,
4221
4213
  error: sessionRestoration.restorationError?.message
4222
4214
  });
4223
- return /* @__PURE__ */ jsx23(Navigate, { to: loginPath, replace: true });
4215
+ return /* @__PURE__ */ jsx22(Navigate, { to: loginPath, replace: true });
4224
4216
  }
4225
4217
  if (!wasAuthenticatedRef.current) {
4226
- return /* @__PURE__ */ jsx23(Navigate, { to: loginPath, replace: true });
4218
+ return /* @__PURE__ */ jsx22(Navigate, { to: loginPath, replace: true });
4227
4219
  }
4228
4220
  const isTabVisible = typeof document !== "undefined" && !document.hidden;
4229
4221
  if (tabJustBecameVisibleRef.current || isTabVisible && wasAuthenticatedRef.current && isLoading) {
4230
- return loadingFallback || /* @__PURE__ */ jsx23("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx23(LoadingSpinner, {}) });
4222
+ return loadingFallback || /* @__PURE__ */ jsx22("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx22(LoadingSpinner, {}) });
4231
4223
  }
4232
4224
  if (shouldRedirect) {
4233
- return /* @__PURE__ */ jsx23(Navigate, { to: loginPath, replace: true });
4225
+ return /* @__PURE__ */ jsx22(Navigate, { to: loginPath, replace: true });
4234
4226
  }
4235
4227
  if (isLoading) {
4236
- return loadingFallback || /* @__PURE__ */ jsx23("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx23(LoadingSpinner, {}) });
4228
+ return loadingFallback || /* @__PURE__ */ jsx22("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx22(LoadingSpinner, {}) });
4237
4229
  }
4238
- return /* @__PURE__ */ jsx23(Navigate, { to: loginPath, replace: true });
4230
+ return /* @__PURE__ */ jsx22(Navigate, { to: loginPath, replace: true });
4239
4231
  }
4240
4232
  if (!requireEvent) {
4241
- return /* @__PURE__ */ jsx23(Outlet2, {});
4233
+ return /* @__PURE__ */ jsx22(Outlet2, {});
4242
4234
  }
4243
4235
  if (!events || events.length === 0) {
4244
- return noEventsFallback || /* @__PURE__ */ jsx23("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "100vh", padding: "2rem" }, children: /* @__PURE__ */ jsxs18(Alert, { variant: "destructive", className: "max-w-md", children: [
4245
- /* @__PURE__ */ jsx23(AlertTitle, { children: "No Events Available" }),
4246
- /* @__PURE__ */ jsx23(AlertDescription, { children: "You don't have access to any events. Please contact your administrator if you believe this is an error." })
4236
+ return noEventsFallback || /* @__PURE__ */ jsx22("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "100vh", padding: "2rem" }, children: /* @__PURE__ */ jsxs17(Alert, { variant: "destructive", className: "max-w-md", children: [
4237
+ /* @__PURE__ */ jsx22(AlertTitle, { children: "No Events Available" }),
4238
+ /* @__PURE__ */ jsx22(AlertDescription, { children: "You don't have access to any events. Please contact your administrator if you believe this is an error." })
4247
4239
  ] }) });
4248
4240
  }
4249
4241
  if (!selectedEvent) {
4250
- return /* @__PURE__ */ jsx23(Outlet2, {});
4242
+ return /* @__PURE__ */ jsx22(Outlet2, {});
4251
4243
  }
4252
- return /* @__PURE__ */ jsx23(Outlet2, {});
4244
+ return /* @__PURE__ */ jsx22(Outlet2, {});
4253
4245
  }
4254
4246
 
4255
4247
  // src/components/FileUpload/FileUpload.tsx
4256
- import { useState as useState15, useCallback as useCallback11, useRef as useRef9, useEffect as useEffect11, useMemo as useMemo11 } from "react";
4257
- import { Fragment as Fragment9, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
4248
+ import { useState as useState15, useCallback as useCallback10, useRef as useRef9, useEffect as useEffect10, useMemo as useMemo10 } from "react";
4249
+ import { Fragment as Fragment10, jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
4258
4250
  function FileUpload({
4259
4251
  supabase,
4260
4252
  table_name,
@@ -4280,6 +4272,13 @@ function FileUpload({
4280
4272
  onProgress,
4281
4273
  children
4282
4274
  }) {
4275
+ if (!pageContext) {
4276
+ const errorMsg = "pageContext is required for FileUpload component. This is used for permission checks.";
4277
+ if (import.meta.env.MODE === "development") {
4278
+ console.error("[FileUpload]", errorMsg);
4279
+ }
4280
+ throw new Error(errorMsg);
4281
+ }
4283
4282
  const [isDragging, setIsDragging] = useState15(false);
4284
4283
  const [uploadStates, setUploadStates] = useState15(/* @__PURE__ */ new Map());
4285
4284
  const [resolvedAppId, setResolvedAppId] = useState15(app_id || null);
@@ -4287,7 +4286,7 @@ function FileUpload({
4287
4286
  const [appIdError, setAppIdError] = useState15(null);
4288
4287
  const fileInputRef = useRef9(null);
4289
4288
  const { uploadFile, isLoading, error } = useFileReference(supabase);
4290
- useEffect11(() => {
4289
+ useEffect10(() => {
4291
4290
  if (app_id) {
4292
4291
  setResolvedAppId(app_id);
4293
4292
  setIsResolvingAppId(false);
@@ -4322,15 +4321,15 @@ function FileUpload({
4322
4321
  };
4323
4322
  resolveAppId();
4324
4323
  }, [app_id, supabase]);
4325
- const isUploading = useMemo11(() => {
4324
+ const isUploading = useMemo10(() => {
4326
4325
  return uploadStates.size > 0 && Array.from(uploadStates.values()).some(
4327
4326
  (state) => state.progress.status === "uploading" || state.progress.status === "processing"
4328
4327
  );
4329
4328
  }, [uploadStates]);
4330
- const isDisabled = useMemo11(() => {
4329
+ const isDisabled = useMemo10(() => {
4331
4330
  return disabled || isUploading || isResolvingAppId || !resolvedAppId;
4332
4331
  }, [disabled, isUploading, isResolvingAppId, resolvedAppId]);
4333
- const generatePreview = useCallback11((file) => {
4332
+ const generatePreview = useCallback10((file) => {
4334
4333
  return new Promise((resolve) => {
4335
4334
  if (!file.type.startsWith("image/")) {
4336
4335
  resolve(null);
@@ -4344,7 +4343,7 @@ function FileUpload({
4344
4343
  reader.readAsDataURL(file);
4345
4344
  });
4346
4345
  }, []);
4347
- const validateFile = useCallback11((file) => {
4346
+ const validateFile = useCallback10((file) => {
4348
4347
  if (file.size > maxSize) {
4349
4348
  return `File "${file.name}" exceeds maximum size of ${Math.round(maxSize / 1024 / 1024)}MB`;
4350
4349
  }
@@ -4368,7 +4367,7 @@ function FileUpload({
4368
4367
  }
4369
4368
  return null;
4370
4369
  }, [accept, maxSize]);
4371
- const handleFileSelect = useCallback11(async (files) => {
4370
+ const handleFileSelect = useCallback10(async (files) => {
4372
4371
  if (!files || files.length === 0) return;
4373
4372
  const fileArray = Array.from(files);
4374
4373
  const validationErrors = [];
@@ -4447,6 +4446,10 @@ function FileUpload({
4447
4446
  const errorMsg = appIdError || "App ID not available. Please provide app_id prop or set app name.";
4448
4447
  throw new Error(errorMsg);
4449
4448
  }
4449
+ if (!pageContext) {
4450
+ const errorMsg = "pageContext is required for file upload. This is used for permission checks.";
4451
+ throw new Error(errorMsg);
4452
+ }
4450
4453
  const result = await uploadFile({
4451
4454
  table_name,
4452
4455
  record_id,
@@ -4544,20 +4547,20 @@ function FileUpload({
4544
4547
  onUploadError?.(errorMessage, file);
4545
4548
  }
4546
4549
  }
4547
- }, [uploadFile, table_name, record_id, organisation_id, resolvedAppId, category, folder, isPublic, maxSize, onUploadSuccess, onUploadError, onProgress, validateFile, generatePreview, showPreview, appIdError]);
4548
- const handleDragOver = useCallback11((e) => {
4550
+ }, [uploadFile, table_name, record_id, organisation_id, resolvedAppId, category, folder, isPublic, maxSize, onUploadSuccess, onUploadError, onProgress, validateFile, generatePreview, showPreview, appIdError, pageContext]);
4551
+ const handleDragOver = useCallback10((e) => {
4549
4552
  e.preventDefault();
4550
4553
  e.stopPropagation();
4551
4554
  if (!isDisabled) {
4552
4555
  setIsDragging(true);
4553
4556
  }
4554
4557
  }, [isDisabled]);
4555
- const handleDragLeave = useCallback11((e) => {
4558
+ const handleDragLeave = useCallback10((e) => {
4556
4559
  e.preventDefault();
4557
4560
  e.stopPropagation();
4558
4561
  setIsDragging(false);
4559
4562
  }, []);
4560
- const handleDrop = useCallback11((e) => {
4563
+ const handleDrop = useCallback10((e) => {
4561
4564
  e.preventDefault();
4562
4565
  e.stopPropagation();
4563
4566
  setIsDragging(false);
@@ -4565,13 +4568,13 @@ function FileUpload({
4565
4568
  const files = e.dataTransfer.files;
4566
4569
  handleFileSelect(files);
4567
4570
  }, [isDisabled, handleFileSelect]);
4568
- const handleFileInputChange = useCallback11((e) => {
4571
+ const handleFileInputChange = useCallback10((e) => {
4569
4572
  handleFileSelect(e.target.files);
4570
4573
  if (e.target) {
4571
4574
  e.target.value = "";
4572
4575
  }
4573
4576
  }, [handleFileSelect]);
4574
- const handleClick = useCallback11(() => {
4577
+ const handleClick = useCallback10(() => {
4575
4578
  if (!isDisabled && fileInputRef.current) {
4576
4579
  fileInputRef.current.click();
4577
4580
  }
@@ -4585,8 +4588,8 @@ function FileUpload({
4585
4588
  };
4586
4589
  const dragClasses = isDragging ? "border-main-500 bg-main-50" : "border-sec-300 hover:border-sec-400";
4587
4590
  const disabledClasses = isDisabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-sec-50";
4588
- return /* @__PURE__ */ jsxs19("div", { className: `space-y-4 ${className}`, children: [
4589
- /* @__PURE__ */ jsxs19(
4591
+ return /* @__PURE__ */ jsxs18("div", { className: `space-y-4 ${className}`, children: [
4592
+ /* @__PURE__ */ jsxs18(
4590
4593
  "div",
4591
4594
  {
4592
4595
  role: "button",
@@ -4605,8 +4608,8 @@ function FileUpload({
4605
4608
  }
4606
4609
  } : void 0,
4607
4610
  children: [
4608
- children || /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
4609
- /* @__PURE__ */ jsx24(
4611
+ children || /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
4612
+ /* @__PURE__ */ jsx23(
4610
4613
  "input",
4611
4614
  {
4612
4615
  ref: fileInputRef,
@@ -4616,67 +4619,68 @@ function FileUpload({
4616
4619
  onChange: handleFileInputChange,
4617
4620
  className: "hidden",
4618
4621
  disabled: isDisabled,
4619
- "data-testid": "file-input"
4622
+ "data-testid": "file-input",
4623
+ "aria-label": accept ? `Upload file${multiple ? "s" : ""} (${accept})` : `Upload file${multiple ? "s" : ""}`
4620
4624
  }
4621
4625
  ),
4622
- /* @__PURE__ */ jsx24("div", { className: "text-sec-600", children: isResolvingAppId ? "Resolving app configuration..." : isDragging ? "Drop files here..." : /* @__PURE__ */ jsxs19(Fragment9, { children: [
4623
- /* @__PURE__ */ jsx24("span", { className: "font-medium", children: "Click to upload" }),
4626
+ /* @__PURE__ */ jsx23("div", { className: "text-sec-600", children: isResolvingAppId ? "Resolving app configuration..." : isDragging ? "Drop files here..." : /* @__PURE__ */ jsxs18(Fragment10, { children: [
4627
+ /* @__PURE__ */ jsx23("span", { className: "font-medium", children: "Click to upload" }),
4624
4628
  " ",
4625
4629
  "or drag and drop"
4626
4630
  ] }) }),
4627
- /* @__PURE__ */ jsxs19("div", { className: "text-sm text-sec-500", children: [
4631
+ /* @__PURE__ */ jsxs18("div", { className: "text-sm text-sec-500", children: [
4628
4632
  !isResolvingAppId && accept !== "*/*" && `Accepted formats: ${accept}`,
4629
4633
  !isResolvingAppId && maxSize && ` \u2022 Max size: ${Math.round(maxSize / 1024 / 1024)}MB`,
4630
4634
  !isResolvingAppId && multiple && " \u2022 Multiple files allowed"
4631
4635
  ] })
4632
4636
  ] }),
4633
- isUploading && !showProgress && /* @__PURE__ */ jsx24(
4637
+ isUploading && !showProgress && /* @__PURE__ */ jsx23(
4634
4638
  "div",
4635
4639
  {
4636
4640
  className: "absolute inset-0 bg-white bg-opacity-75 flex items-center justify-center",
4637
4641
  role: "status",
4638
4642
  "aria-live": "polite",
4639
4643
  "aria-label": "Uploading file",
4640
- children: /* @__PURE__ */ jsx24("div", { className: "animate-spin rounded-full size-8 border-b-2 border-main-500", "aria-hidden": "true" })
4644
+ children: /* @__PURE__ */ jsx23("div", { className: "animate-spin rounded-full size-8 border-b-2 border-main-500", "aria-hidden": "true" })
4641
4645
  }
4642
4646
  )
4643
4647
  ]
4644
4648
  }
4645
4649
  ),
4646
- showProgress && uploadStates.size > 0 && /* @__PURE__ */ jsx24("div", { className: "space-y-2", children: Array.from(uploadStates.entries()).map(([fileId, uploadState]) => {
4650
+ showProgress && uploadStates.size > 0 && /* @__PURE__ */ jsx23("div", { className: "space-y-2", children: Array.from(uploadStates.entries()).map(([fileId, uploadState]) => {
4647
4651
  const { file, progress, preview, result } = uploadState;
4648
4652
  const isError = progress.status === "error";
4649
4653
  const isCompleted = progress.status === "completed";
4650
4654
  const isUploading2 = progress.status === "uploading" || progress.status === "processing";
4651
- return /* @__PURE__ */ jsxs19(
4655
+ return /* @__PURE__ */ jsxs18(
4652
4656
  "div",
4653
4657
  {
4654
4658
  className: `flex items-center space-x-3 p-3 rounded-lg border ${isError ? "bg-acc-50 border-acc-200" : isCompleted ? "bg-success-50 border-success-200" : "bg-sec-50 border-sec-200"}`,
4655
4659
  children: [
4656
- /* @__PURE__ */ jsx24("div", { className: "flex-shrink-0", children: preview ? /* @__PURE__ */ jsx24(
4660
+ /* @__PURE__ */ jsx23("div", { className: "flex-shrink-0", children: preview ? /* @__PURE__ */ jsx23(
4657
4661
  "img",
4658
4662
  {
4659
4663
  src: preview,
4660
4664
  alt: file.name,
4661
4665
  className: "w-12 h-12 object-cover rounded"
4662
4666
  }
4663
- ) : /* @__PURE__ */ jsx24("div", { className: "w-12 h-12 flex items-center justify-center bg-sec-200 rounded", children: /* @__PURE__ */ jsx24("span", { className: "text-2xl", children: "\u{1F4C4}" }) }) }),
4664
- /* @__PURE__ */ jsxs19("div", { className: "flex-1 min-w-0", children: [
4665
- /* @__PURE__ */ jsx24("div", { className: "font-medium text-sec-900 truncate", children: file.name }),
4666
- /* @__PURE__ */ jsxs19("div", { className: "text-sm text-sec-500", children: [
4667
+ ) : /* @__PURE__ */ jsx23("div", { className: "w-12 h-12 flex items-center justify-center bg-sec-200 rounded", children: /* @__PURE__ */ jsx23("span", { className: "text-2xl", children: "\u{1F4C4}" }) }) }),
4668
+ /* @__PURE__ */ jsxs18("div", { className: "flex-1 min-w-0", children: [
4669
+ /* @__PURE__ */ jsx23("div", { className: "font-medium text-sec-900 truncate", children: file.name }),
4670
+ /* @__PURE__ */ jsxs18("div", { className: "text-sm text-sec-500", children: [
4667
4671
  formatFileSize(file.size),
4668
4672
  isCompleted && result && " \u2022 Uploaded",
4669
4673
  isError && progress.error && ` \u2022 ${progress.error}`
4670
4674
  ] }),
4671
- showProgress && (isUploading2 || isError) && /* @__PURE__ */ jsxs19("div", { className: "mt-2", children: [
4672
- /* @__PURE__ */ jsx24("div", { className: "w-full bg-sec-200 rounded-full h-2", children: /* @__PURE__ */ jsx24(
4675
+ showProgress && (isUploading2 || isError) && /* @__PURE__ */ jsxs18("div", { className: "mt-2", children: [
4676
+ /* @__PURE__ */ jsx23("div", { className: "w-full bg-sec-200 rounded-full h-2", children: /* @__PURE__ */ jsx23(
4673
4677
  "div",
4674
4678
  {
4675
4679
  className: `h-2 rounded-full transition-all duration-300 ${isError ? "bg-acc-500" : "bg-main-500"}`,
4676
4680
  style: { width: `${progress.percentage}%` }
4677
4681
  }
4678
4682
  ) }),
4679
- isUploading2 && /* @__PURE__ */ jsxs19("div", { className: "text-xs text-sec-500 mt-1", children: [
4683
+ isUploading2 && /* @__PURE__ */ jsxs18("div", { className: "text-xs text-sec-500 mt-1", children: [
4680
4684
  progress.percentage,
4681
4685
  "% \u2022 ",
4682
4686
  formatFileSize(progress.loaded),
@@ -4685,10 +4689,10 @@ function FileUpload({
4685
4689
  ] })
4686
4690
  ] })
4687
4691
  ] }),
4688
- /* @__PURE__ */ jsxs19("div", { className: "flex-shrink-0", children: [
4689
- isCompleted && /* @__PURE__ */ jsx24("span", { className: "text-success-500 text-xl", children: "\u2713" }),
4690
- isError && /* @__PURE__ */ jsx24("span", { className: "text-acc-500 text-xl", children: "\u2715" }),
4691
- isUploading2 && /* @__PURE__ */ jsx24(
4692
+ /* @__PURE__ */ jsxs18("div", { className: "flex-shrink-0", children: [
4693
+ isCompleted && /* @__PURE__ */ jsx23("span", { className: "text-success-500 text-xl", children: "\u2713" }),
4694
+ isError && /* @__PURE__ */ jsx23("span", { className: "text-acc-500 text-xl", children: "\u2715" }),
4695
+ isUploading2 && /* @__PURE__ */ jsx23(
4692
4696
  "div",
4693
4697
  {
4694
4698
  className: "animate-spin rounded-full size-5 border-b-2 border-main-500",
@@ -4703,7 +4707,7 @@ function FileUpload({
4703
4707
  fileId
4704
4708
  );
4705
4709
  }) }),
4706
- appIdError && /* @__PURE__ */ jsx24(
4710
+ appIdError && /* @__PURE__ */ jsx23(
4707
4711
  "div",
4708
4712
  {
4709
4713
  className: "p-3 bg-acc-50 border border-acc-200 rounded-lg text-sm text-acc-600",
@@ -4712,7 +4716,7 @@ function FileUpload({
4712
4716
  children: appIdError
4713
4717
  }
4714
4718
  ),
4715
- error && /* @__PURE__ */ jsx24(
4719
+ error && /* @__PURE__ */ jsx23(
4716
4720
  "div",
4717
4721
  {
4718
4722
  className: "p-3 bg-acc-50 border border-acc-200 rounded-lg text-sm text-acc-600",
@@ -4725,9 +4729,9 @@ function FileUpload({
4725
4729
  }
4726
4730
 
4727
4731
  // src/components/Table/Table.tsx
4728
- import * as React19 from "react";
4729
- import { jsx as jsx25 } from "react/jsx-runtime";
4730
- var Table = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4732
+ import * as React20 from "react";
4733
+ import { jsx as jsx24 } from "react/jsx-runtime";
4734
+ var Table = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4731
4735
  "table",
4732
4736
  {
4733
4737
  ref,
@@ -4736,9 +4740,9 @@ var Table = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
4736
4740
  }
4737
4741
  ));
4738
4742
  Table.displayName = "Table";
4739
- var TableHeader = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
4743
+ var TableHeader = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
4740
4744
  TableHeader.displayName = "TableHeader";
4741
- var TableBody = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4745
+ var TableBody = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4742
4746
  "tbody",
4743
4747
  {
4744
4748
  ref,
@@ -4747,7 +4751,7 @@ var TableBody = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE_
4747
4751
  }
4748
4752
  ));
4749
4753
  TableBody.displayName = "TableBody";
4750
- var TableFooter = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4754
+ var TableFooter = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4751
4755
  "tfoot",
4752
4756
  {
4753
4757
  ref,
@@ -4759,7 +4763,7 @@ var TableFooter = React19.forwardRef(({ className, ...props }, ref) => /* @__PUR
4759
4763
  }
4760
4764
  ));
4761
4765
  TableFooter.displayName = "TableFooter";
4762
- var TableRow = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4766
+ var TableRow = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4763
4767
  "tr",
4764
4768
  {
4765
4769
  ref,
@@ -4771,7 +4775,7 @@ var TableRow = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__
4771
4775
  }
4772
4776
  ));
4773
4777
  TableRow.displayName = "TableRow";
4774
- var TableHead = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4778
+ var TableHead = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4775
4779
  "th",
4776
4780
  {
4777
4781
  ref,
@@ -4783,7 +4787,7 @@ var TableHead = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE_
4783
4787
  }
4784
4788
  ));
4785
4789
  TableHead.displayName = "TableHead";
4786
- var TableCell = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4790
+ var TableCell = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4787
4791
  "td",
4788
4792
  {
4789
4793
  ref,
@@ -4792,7 +4796,7 @@ var TableCell = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE_
4792
4796
  }
4793
4797
  ));
4794
4798
  TableCell.displayName = "TableCell";
4795
- var TableCaption = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4799
+ var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
4796
4800
  "caption",
4797
4801
  {
4798
4802
  ref,
@@ -4803,7 +4807,7 @@ var TableCaption = React19.forwardRef(({ className, ...props }, ref) => /* @__PU
4803
4807
  TableCaption.displayName = "TableCaption";
4804
4808
 
4805
4809
  // src/components/PublicLayout/PublicPageLayout.tsx
4806
- import { Fragment as Fragment10, jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
4810
+ import { Fragment as Fragment11, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
4807
4811
  function PublicPageHeader({
4808
4812
  event,
4809
4813
  eventCode,
@@ -4816,11 +4820,11 @@ function PublicPageHeader({
4816
4820
  customEventLogo
4817
4821
  }) {
4818
4822
  const { appName } = useAppConfig();
4819
- return /* @__PURE__ */ jsxs20("header", { className: cn(
4823
+ return /* @__PURE__ */ jsxs19("header", { className: cn(
4820
4824
  "w-full px-[max(0rem,calc((100vw-var(--app-width))/2-0.5rem))] grid grid-cols-[auto_1fr_auto] place-items-center gap-2",
4821
4825
  className
4822
4826
  ), children: [
4823
- showAppLogo && appName && /* @__PURE__ */ jsx26(
4827
+ showAppLogo && appName && /* @__PURE__ */ jsx25(
4824
4828
  "img",
4825
4829
  {
4826
4830
  className: "ml-4 max-w-36 object-contain row-span-2",
@@ -4828,9 +4832,9 @@ function PublicPageHeader({
4828
4832
  alt: appName
4829
4833
  }
4830
4834
  ),
4831
- event && /* @__PURE__ */ jsxs20(Fragment10, { children: [
4832
- /* @__PURE__ */ jsx26("h1", { children: event.event_name }),
4833
- showEventLogo && event && /* @__PURE__ */ jsx26(Fragment10, { children: customEventLogo || /* @__PURE__ */ jsx26(
4835
+ event && /* @__PURE__ */ jsxs19(Fragment11, { children: [
4836
+ /* @__PURE__ */ jsx25("h1", { children: event.event_name }),
4837
+ showEventLogo && event && /* @__PURE__ */ jsx25(Fragment11, { children: customEventLogo || /* @__PURE__ */ jsx25(
4834
4838
  FileDisplay,
4835
4839
  {
4836
4840
  table_name: "event",
@@ -4847,13 +4851,13 @@ function PublicPageHeader({
4847
4851
  }
4848
4852
  }
4849
4853
  ) }),
4850
- event.event_venue && /* @__PURE__ */ jsx26("h4", { children: event.event_venue })
4854
+ event.event_venue && /* @__PURE__ */ jsx25("h4", { children: event.event_venue })
4851
4855
  ] }),
4852
- title && /* @__PURE__ */ jsxs20(Fragment10, { children: [
4853
- /* @__PURE__ */ jsx26("h1", { children: title }),
4854
- description && /* @__PURE__ */ jsx26("p", { className: "text-lg text-sec-600 max-w-3xl mx-auto", children: description })
4856
+ title && /* @__PURE__ */ jsxs19(Fragment11, { children: [
4857
+ /* @__PURE__ */ jsx25("h1", { children: title }),
4858
+ description && /* @__PURE__ */ jsx25("p", { className: "text-lg text-sec-600 max-w-3xl mx-auto", children: description })
4855
4859
  ] }),
4856
- children && /* @__PURE__ */ jsx26(Fragment10, { children })
4860
+ children && /* @__PURE__ */ jsx25(Fragment11, { children })
4857
4861
  ] });
4858
4862
  }
4859
4863
  function PublicPageFooter({
@@ -4867,11 +4871,11 @@ function PublicPageFooter({
4867
4871
  children
4868
4872
  }) {
4869
4873
  const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
4870
- return /* @__PURE__ */ jsx26("footer", { className: cn("mt-8 py-6 flex justify-center", className), children: /* @__PURE__ */ jsxs20("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
4871
- logo && /* @__PURE__ */ jsx26("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
4872
- children && /* @__PURE__ */ jsx26(Fragment10, { children }),
4873
- /* @__PURE__ */ jsx26("span", { className: "text-muted-foreground", children: copyrightText }),
4874
- links && links.length > 0 && /* @__PURE__ */ jsx26("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsx26("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
4874
+ return /* @__PURE__ */ jsx25("footer", { className: cn("mt-8 py-6 flex justify-center", className), children: /* @__PURE__ */ jsxs19("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
4875
+ logo && /* @__PURE__ */ jsx25("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
4876
+ children && /* @__PURE__ */ jsx25(Fragment11, { children }),
4877
+ /* @__PURE__ */ jsx25("span", { className: "text-muted-foreground", children: copyrightText }),
4878
+ links && links.length > 0 && /* @__PURE__ */ jsx25("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx25("li", { children: /* @__PURE__ */ jsx25("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
4875
4879
  ] }) });
4876
4880
  }
4877
4881
  function PublicPageLayout({
@@ -4882,7 +4886,6 @@ function PublicPageLayout({
4882
4886
  error = null,
4883
4887
  refetch,
4884
4888
  showFooter = true,
4885
- className = "",
4886
4889
  errorFallback: ErrorFallback,
4887
4890
  loadingFallback: LoadingFallback,
4888
4891
  customHeader,
@@ -4895,44 +4898,44 @@ function PublicPageLayout({
4895
4898
  });
4896
4899
  if (isLoading) {
4897
4900
  if (LoadingFallback) {
4898
- return /* @__PURE__ */ jsx26(LoadingFallback, {});
4901
+ return /* @__PURE__ */ jsx25(LoadingFallback, {});
4899
4902
  }
4900
- return /* @__PURE__ */ jsx26("div", { className: "min-h-screen bg-background flex items-center justify-center", children: /* @__PURE__ */ jsxs20("div", { className: "max-w-md mx-auto text-center px-4", children: [
4901
- /* @__PURE__ */ jsx26(LoadingSpinner, { size: "lg", className: "mx-auto mb-4" }),
4902
- loadingMessage && /* @__PURE__ */ jsx26("p", { className: "text-sec-600", children: loadingMessage })
4903
+ return /* @__PURE__ */ jsx25("div", { className: "min-h-screen bg-background flex items-center justify-center", children: /* @__PURE__ */ jsxs19("div", { className: "max-w-md mx-auto text-center px-4", children: [
4904
+ /* @__PURE__ */ jsx25(LoadingSpinner, { size: "lg", className: "mx-auto mb-4" }),
4905
+ loadingMessage && /* @__PURE__ */ jsx25("p", { className: "text-sec-600", children: loadingMessage })
4903
4906
  ] }) });
4904
4907
  }
4905
4908
  if (error && showValidationErrors) {
4906
4909
  if (ErrorFallback) {
4907
- return /* @__PURE__ */ jsx26(ErrorFallback, { error, retry: handleRefetch });
4910
+ return /* @__PURE__ */ jsx25(ErrorFallback, { error, retry: handleRefetch });
4908
4911
  }
4909
- return /* @__PURE__ */ jsxs20("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
4910
- /* @__PURE__ */ jsx26("h1", { children: "Event Not Found" }),
4911
- /* @__PURE__ */ jsxs20("p", { children: [
4912
+ return /* @__PURE__ */ jsxs19("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
4913
+ /* @__PURE__ */ jsx25("h1", { children: "Event Not Found" }),
4914
+ /* @__PURE__ */ jsxs19("p", { children: [
4912
4915
  'The event code "',
4913
4916
  eventCode,
4914
4917
  '" is invalid or the event is not available for public viewing.'
4915
4918
  ] }),
4916
- /* @__PURE__ */ jsx26(Button, { onClick: handleRefetch, children: "Try Again" })
4919
+ /* @__PURE__ */ jsx25(Button, { onClick: handleRefetch, children: "Try Again" })
4917
4920
  ] });
4918
4921
  }
4919
4922
  if (!event && showValidationErrors) {
4920
- return /* @__PURE__ */ jsxs20("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
4921
- /* @__PURE__ */ jsx26("h1", { children: "Event Not Available" }),
4922
- /* @__PURE__ */ jsx26("p", { children: "This event is not available for public viewing." }),
4923
- handleRefetch && /* @__PURE__ */ jsx26(Button, { onClick: handleRefetch, children: "Try Again" })
4923
+ return /* @__PURE__ */ jsxs19("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
4924
+ /* @__PURE__ */ jsx25("h1", { children: "Event Not Available" }),
4925
+ /* @__PURE__ */ jsx25("p", { children: "This event is not available for public viewing." }),
4926
+ handleRefetch && /* @__PURE__ */ jsx25(Button, { onClick: handleRefetch, children: "Try Again" })
4924
4927
  ] });
4925
4928
  }
4926
- return /* @__PURE__ */ jsx26(ErrorBoundary, { componentName: "PublicPageLayout", children: /* @__PURE__ */ jsxs20(Fragment10, { children: [
4927
- customHeader || /* @__PURE__ */ jsx26(
4929
+ return /* @__PURE__ */ jsx25(ErrorBoundary, { componentName: "PublicPageLayout", children: /* @__PURE__ */ jsxs19(Fragment11, { children: [
4930
+ customHeader || /* @__PURE__ */ jsx25(
4928
4931
  PublicPageHeader,
4929
4932
  {
4930
4933
  event: event || void 0,
4931
4934
  eventCode
4932
4935
  }
4933
4936
  ),
4934
- /* @__PURE__ */ jsx26("main", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children }),
4935
- showFooter && event && (customFooter || /* @__PURE__ */ jsx26(PublicPageFooter, { event }))
4937
+ /* @__PURE__ */ jsx25("main", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children }),
4938
+ showFooter && event && (customFooter || /* @__PURE__ */ jsx25(PublicPageFooter, { event }))
4936
4939
  ] }) });
4937
4940
  }
4938
4941
 
@@ -4964,8 +4967,7 @@ export {
4964
4967
  Form,
4965
4968
  FormField,
4966
4969
  LoginForm,
4967
- EventSelector,
4968
- OrganisationSelector,
4970
+ ContextSelector,
4969
4971
  PasswordChangeForm,
4970
4972
  UserMenu,
4971
4973
  NavigationMenu,
@@ -4988,4 +4990,4 @@ export {
4988
4990
  PublicPageFooter,
4989
4991
  PublicPageLayout
4990
4992
  };
4991
- //# sourceMappingURL=chunk-GLK6VM3F.js.map
4993
+ //# sourceMappingURL=chunk-ZNIWI3UC.js.map