@jmruthers/pace-core 0.6.1 → 0.6.2

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 (502) hide show
  1. package/CHANGELOG.md +43 -10
  2. package/cursor-rules/00-pace-core-compliance.mdc +18 -91
  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-BPvc3Ka0.d.ts} +54 -0
  14. package/dist/{DataTable-CH1U5Tpy.d.ts → DataTable-BMRU8a1j.d.ts} +33 -1
  15. package/dist/{DataTable-DQ7RSOHE.js → DataTable-TPTKCX4D.js} +10 -9
  16. package/dist/{PublicPageProvider-ce4xlHYA.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +356 -111
  17. package/dist/{UnifiedAuthProvider-ATAP5UTR.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
  18. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
  19. package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
  20. package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
  21. package/dist/chunk-24UVZUZG.js.map +1 -0
  22. package/dist/{chunk-4N5C5XZU.js → chunk-2UOI2FG5.js} +4 -4
  23. package/dist/chunk-2UOI2FG5.js.map +1 -0
  24. package/dist/{chunk-T33XF5ZC.js → chunk-3XC4CPTD.js} +4317 -3963
  25. package/dist/chunk-3XC4CPTD.js.map +1 -0
  26. package/dist/{chunk-4ZC4GX36.js → chunk-6J4GEEJR.js} +172 -45
  27. package/dist/chunk-6J4GEEJR.js.map +1 -0
  28. package/dist/{chunk-3QRJFVBR.js → chunk-6SOIHG6Z.js} +1 -1
  29. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  30. package/dist/{chunk-BYFSK72L.js → chunk-EHMR7VYL.js} +4 -4
  31. package/dist/chunk-EHMR7VYL.js.map +1 -0
  32. package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
  33. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  34. package/dist/{chunk-LXQLPRQ2.js → chunk-FFQEQTNW.js} +6 -8
  35. package/dist/chunk-FFQEQTNW.js.map +1 -0
  36. package/dist/chunk-FMUCXFII.js +76 -0
  37. package/dist/chunk-FMUCXFII.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-3XTALGJF.js → chunk-MMZ7JXPU.js} +60 -223
  43. package/dist/chunk-MMZ7JXPU.js.map +1 -0
  44. package/dist/{chunk-GLK6VM3F.js → chunk-NECFR5MM.js} +254 -170
  45. package/dist/chunk-NECFR5MM.js.map +1 -0
  46. package/dist/{chunk-JBKQ3SAO.js → chunk-SFZUDBL5.js} +40 -4
  47. package/dist/chunk-SFZUDBL5.js.map +1 -0
  48. package/dist/{chunk-XM25TVIE.js → chunk-XWQCNGTQ.js} +724 -363
  49. package/dist/chunk-XWQCNGTQ.js.map +1 -0
  50. package/dist/components.d.ts +5 -5
  51. package/dist/components.js +14 -11
  52. package/dist/components.js.map +1 -1
  53. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  54. package/dist/hooks.d.ts +55 -122
  55. package/dist/hooks.js +8 -12
  56. package/dist/hooks.js.map +1 -1
  57. package/dist/index.d.ts +60 -13
  58. package/dist/index.js +19 -19
  59. package/dist/index.js.map +1 -1
  60. package/dist/providers.d.ts +21 -3
  61. package/dist/providers.js +2 -2
  62. package/dist/rbac/index.d.ts +145 -114
  63. package/dist/rbac/index.js +8 -11
  64. package/dist/theming/runtime.d.ts +1 -13
  65. package/dist/theming/runtime.js +1 -1
  66. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  67. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  68. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  69. package/dist/types.d.ts +2 -2
  70. package/dist/{usePublicRouteParams-BJAlWfuJ.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +31 -1
  71. package/dist/utils.d.ts +4 -5
  72. package/dist/utils.js +14 -14
  73. package/dist/utils.js.map +1 -1
  74. package/docs/api/README.md +7 -1
  75. package/docs/api/classes/ColumnFactory.md +8 -8
  76. package/docs/api/classes/InvalidScopeError.md +4 -4
  77. package/docs/api/classes/Logger.md +1 -1
  78. package/docs/api/classes/MissingUserContextError.md +4 -4
  79. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  80. package/docs/api/classes/PermissionDeniedError.md +4 -4
  81. package/docs/api/classes/RBACAuditManager.md +1 -1
  82. package/docs/api/classes/RBACCache.md +1 -1
  83. package/docs/api/classes/RBACEngine.md +1 -1
  84. package/docs/api/classes/RBACError.md +4 -4
  85. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  86. package/docs/api/classes/SecureSupabaseClient.md +18 -15
  87. package/docs/api/classes/StorageUtils.md +1 -1
  88. package/docs/api/enums/FileCategory.md +1 -1
  89. package/docs/api/enums/LogLevel.md +1 -1
  90. package/docs/api/enums/RBACErrorCode.md +1 -1
  91. package/docs/api/enums/RPCFunction.md +1 -1
  92. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  93. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  94. package/docs/api/interfaces/AggregateConfig.md +4 -4
  95. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  96. package/docs/api/interfaces/AvatarProps.md +1 -1
  97. package/docs/api/interfaces/BadgeProps.md +9 -2
  98. package/docs/api/interfaces/ButtonProps.md +7 -4
  99. package/docs/api/interfaces/CalendarProps.md +8 -5
  100. package/docs/api/interfaces/CardProps.md +8 -5
  101. package/docs/api/interfaces/ColorPalette.md +1 -1
  102. package/docs/api/interfaces/ColorShade.md +1 -1
  103. package/docs/api/interfaces/ComplianceResult.md +1 -1
  104. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  105. package/docs/api/interfaces/DataRecord.md +1 -1
  106. package/docs/api/interfaces/DataTableAction.md +24 -21
  107. package/docs/api/interfaces/DataTableColumn.md +31 -31
  108. package/docs/api/interfaces/DataTableProps.md +1 -1
  109. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  110. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  111. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  112. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  113. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  114. package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
  115. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
  116. package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
  117. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  118. package/docs/api/interfaces/ExportColumn.md +1 -1
  119. package/docs/api/interfaces/ExportOptions.md +8 -8
  120. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  121. package/docs/api/interfaces/FileMetadata.md +1 -1
  122. package/docs/api/interfaces/FileReference.md +1 -1
  123. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  124. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  125. package/docs/api/interfaces/FileUploadProps.md +26 -23
  126. package/docs/api/interfaces/FooterProps.md +10 -8
  127. package/docs/api/interfaces/FormFieldProps.md +10 -10
  128. package/docs/api/interfaces/FormProps.md +1 -1
  129. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  130. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  131. package/docs/api/interfaces/InputProps.md +7 -4
  132. package/docs/api/interfaces/LabelProps.md +1 -1
  133. package/docs/api/interfaces/LoggerConfig.md +1 -1
  134. package/docs/api/interfaces/LoginFormProps.md +14 -11
  135. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  136. package/docs/api/interfaces/NavigationContextType.md +1 -1
  137. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  138. package/docs/api/interfaces/NavigationItem.md +11 -11
  139. package/docs/api/interfaces/NavigationMenuProps.md +15 -15
  140. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  141. package/docs/api/interfaces/Organisation.md +1 -1
  142. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  143. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  144. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  145. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  146. package/docs/api/interfaces/PaceAppLayoutProps.md +30 -27
  147. package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
  148. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  149. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  150. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  151. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  152. package/docs/api/interfaces/PaletteData.md +1 -1
  153. package/docs/api/interfaces/ParsedAddress.md +1 -1
  154. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  155. package/docs/api/interfaces/ProgressProps.md +1 -1
  156. package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
  157. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  158. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  159. package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
  160. package/docs/api/interfaces/QuickFix.md +1 -1
  161. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  162. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  163. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  164. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  165. package/docs/api/interfaces/RBACConfig.md +1 -1
  166. package/docs/api/interfaces/RBACContext.md +1 -1
  167. package/docs/api/interfaces/RBACLogger.md +1 -1
  168. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  169. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  170. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  171. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  172. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  173. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  174. package/docs/api/interfaces/RBACResult.md +1 -1
  175. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  176. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  177. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  178. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  179. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  180. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  181. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  182. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  183. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  184. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  185. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  186. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  187. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  188. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  189. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  190. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  191. package/docs/api/interfaces/RouteConfig.md +1 -1
  192. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  193. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  194. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  195. package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
  196. package/docs/api/interfaces/SetupIssue.md +1 -1
  197. package/docs/api/interfaces/StorageConfig.md +1 -1
  198. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  199. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  200. package/docs/api/interfaces/StorageListOptions.md +1 -1
  201. package/docs/api/interfaces/StorageListResult.md +1 -1
  202. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  203. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  204. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  205. package/docs/api/interfaces/StyleImport.md +1 -1
  206. package/docs/api/interfaces/SwitchProps.md +1 -1
  207. package/docs/api/interfaces/TabsContentProps.md +1 -1
  208. package/docs/api/interfaces/TabsListProps.md +1 -1
  209. package/docs/api/interfaces/TabsProps.md +1 -1
  210. package/docs/api/interfaces/TabsTriggerProps.md +3 -3
  211. package/docs/api/interfaces/TextareaProps.md +1 -1
  212. package/docs/api/interfaces/ToastActionElement.md +4 -1
  213. package/docs/api/interfaces/ToastProps.md +1 -1
  214. package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
  215. package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
  216. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  217. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  218. package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
  219. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  220. package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
  221. package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
  222. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  223. package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
  224. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  225. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
  226. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
  227. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  228. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  229. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  230. package/docs/api/interfaces/UserEventAccess.md +14 -11
  231. package/docs/api/interfaces/UserMenuProps.md +8 -6
  232. package/docs/api/interfaces/UserProfile.md +1 -1
  233. package/docs/api/modules.md +575 -634
  234. package/docs/architecture/database-schema-requirements.md +161 -0
  235. package/docs/core-concepts/rbac-system.md +3 -3
  236. package/docs/documentation-index.md +2 -4
  237. package/docs/getting-started/cursor-rules.md +2 -1
  238. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  239. package/docs/migration/MIGRATION_GUIDE.md +2 -24
  240. package/docs/migration/README.md +52 -6
  241. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  242. package/docs/migration/database-changes-december-2025.md +3 -3
  243. package/docs/rbac/event-based-apps.md +1 -1
  244. package/docs/rbac/getting-started.md +1 -1
  245. package/docs/rbac/quick-start.md +1 -1
  246. package/docs/standards/README.md +1 -0
  247. package/package.json +2 -1
  248. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  249. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  250. package/scripts/audit/core/checks/bundle.cjs +142 -0
  251. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +714 -687
  252. package/scripts/audit/core/checks/config.cjs +54 -0
  253. package/scripts/audit/core/checks/coverage.cjs +84 -0
  254. package/scripts/audit/core/checks/dependencies.cjs +454 -0
  255. package/scripts/audit/core/checks/documentation.cjs +203 -0
  256. package/scripts/audit/core/checks/environment.cjs +128 -0
  257. package/scripts/audit/core/checks/error-handling.cjs +299 -0
  258. package/scripts/audit/core/checks/forms.cjs +172 -0
  259. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  260. package/scripts/audit/core/checks/hooks.cjs +334 -0
  261. package/scripts/audit/core/checks/imports.cjs +244 -0
  262. package/scripts/audit/core/checks/performance.cjs +325 -0
  263. package/scripts/audit/core/checks/routes.cjs +117 -0
  264. package/scripts/audit/core/checks/state.cjs +130 -0
  265. package/scripts/audit/core/checks/structure.cjs +65 -0
  266. package/scripts/audit/core/checks/style.cjs +584 -0
  267. package/scripts/audit/core/checks/testing.cjs +122 -0
  268. package/scripts/audit/core/checks/typescript.cjs +61 -0
  269. package/scripts/audit/core/scanner.cjs +199 -0
  270. package/scripts/audit/core/utils.cjs +137 -0
  271. package/scripts/audit/index.cjs +223 -0
  272. package/scripts/audit/reporters/console.cjs +151 -0
  273. package/scripts/audit/reporters/json.cjs +54 -0
  274. package/scripts/audit/reporters/markdown.cjs +124 -0
  275. package/scripts/audit-consuming-app.cjs +61 -936
  276. package/scripts/build-docs/build-decision.js +240 -0
  277. package/scripts/build-docs/cache-utils.js +105 -0
  278. package/scripts/build-docs/content-normalization.js +150 -0
  279. package/scripts/build-docs/file-utils.js +105 -0
  280. package/scripts/build-docs/git-utils.js +86 -0
  281. package/scripts/build-docs/hash-utils.js +116 -0
  282. package/scripts/build-docs/typedoc-runner.js +220 -0
  283. package/scripts/build-docs-incremental.js +77 -913
  284. package/scripts/utils/command-runner.js +16 -11
  285. package/scripts/validate-formats.js +61 -56
  286. package/scripts/validate-master.js +74 -69
  287. package/scripts/validate-pre-publish.js +70 -65
  288. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  289. package/src/components/Alert/Alert.test.tsx +12 -18
  290. package/src/components/Alert/Alert.tsx +5 -7
  291. package/src/components/Avatar/Avatar.test.tsx +4 -4
  292. package/src/components/Badge/Badge.tsx +14 -0
  293. package/src/components/Button/Button.tsx +22 -0
  294. package/src/components/Calendar/Calendar.tsx +8 -2
  295. package/src/components/Card/Card.tsx +4 -0
  296. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  297. package/src/components/Checkbox/Checkbox.tsx +2 -2
  298. package/src/components/DataTable/DataTable.tsx +38 -4
  299. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  300. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +18 -4
  301. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  302. package/src/components/DataTable/components/AccessDeniedPage.tsx +16 -25
  303. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  304. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
  305. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  306. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  307. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  308. package/src/components/DataTable/components/DataTableCore.tsx +196 -554
  309. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  310. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  311. package/src/components/DataTable/components/DataTableModals.tsx +8 -0
  312. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  313. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  314. package/src/components/DataTable/components/EditFields.tsx +307 -0
  315. package/src/components/DataTable/components/EditableRow.tsx +8 -0
  316. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  317. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  318. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  319. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  320. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  321. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  322. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  323. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  324. package/src/components/DataTable/components/UnifiedTableBody.tsx +61 -849
  325. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  326. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  327. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  328. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  329. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  330. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  331. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  332. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  333. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  334. package/src/components/DataTable/hooks/useColumnReordering.ts +12 -0
  335. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  336. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  337. package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
  338. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  339. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  340. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  341. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  342. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  343. package/src/components/DataTable/styles.ts +6 -6
  344. package/src/components/DataTable/types.ts +6 -10
  345. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  346. package/src/components/DataTable/utils/debugTools.ts +18 -113
  347. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  348. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  349. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  350. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  351. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  352. package/src/components/Dialog/Dialog.tsx +2 -2
  353. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  354. package/src/components/ErrorBoundary/ErrorBoundary.tsx +45 -5
  355. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  356. package/src/components/ErrorBoundary/index.ts +27 -2
  357. package/src/components/EventSelector/EventSelector.tsx +3 -0
  358. package/src/components/FileDisplay/FileDisplay.tsx +32 -18
  359. package/src/components/FileUpload/FileUpload.tsx +22 -2
  360. package/src/components/Footer/Footer.test.tsx +16 -16
  361. package/src/components/Footer/Footer.tsx +14 -11
  362. package/src/components/Form/Form.tsx +1 -0
  363. package/src/components/Header/Header.tsx +21 -10
  364. package/src/components/Input/Input.test.tsx +2 -2
  365. package/src/components/Input/Input.tsx +8 -4
  366. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  367. package/src/components/LoginForm/LoginForm.tsx +4 -0
  368. package/src/components/NavigationMenu/NavigationMenu.tsx +14 -513
  369. package/src/components/NavigationMenu/types.ts +56 -0
  370. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  371. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
  372. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +4 -2
  373. package/src/components/PaceAppLayout/PaceAppLayout.tsx +32 -11
  374. package/src/components/PaceAppLayout/test-setup.tsx +1 -2
  375. package/src/components/PaceLoginPage/PaceLoginPage.tsx +3 -0
  376. package/src/components/PasswordChange/PasswordChangeForm.tsx +9 -0
  377. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  378. package/src/components/PublicLayout/PublicPageLayout.tsx +2 -5
  379. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  380. package/src/components/Select/Select.tsx +80 -434
  381. package/src/components/Select/context.ts +23 -0
  382. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  383. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  384. package/src/components/Select/hooks/useSelectState.ts +104 -0
  385. package/src/components/Select/index.ts +9 -1
  386. package/src/components/Select/types.ts +123 -0
  387. package/src/components/Select/utils/text.ts +26 -0
  388. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +4 -5
  389. package/src/components/Switch/Switch.tsx +4 -4
  390. package/src/components/Tabs/Tabs.tsx +1 -1
  391. package/src/components/Toast/Toast.tsx +4 -0
  392. package/src/components/Tooltip/Tooltip.tsx +2 -2
  393. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  394. package/src/components/UserMenu/UserMenu.tsx +21 -18
  395. package/src/components/index.ts +2 -2
  396. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  397. package/src/hooks/index.ts +1 -2
  398. package/src/hooks/public/usePublicEvent.ts +4 -0
  399. package/src/hooks/public/usePublicEventLogo.ts +4 -0
  400. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  401. package/src/hooks/public/usePublicRouteParams.ts +4 -0
  402. package/src/hooks/services/useAuth.ts +32 -0
  403. package/src/hooks/services/useCurrentEvent.ts +6 -0
  404. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  405. package/src/hooks/useDebounce.ts +9 -0
  406. package/src/hooks/useEventTheme.ts +6 -0
  407. package/src/hooks/useFileDisplay.ts +4 -0
  408. package/src/hooks/useFileReference.ts +25 -7
  409. package/src/hooks/useFileUrl.ts +11 -1
  410. package/src/hooks/useFocusManagement.ts +14 -0
  411. package/src/hooks/useFocusTrap.ts +3 -0
  412. package/src/hooks/useInactivityTracker.ts +3 -0
  413. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  414. package/src/hooks/useOrganisationPermissions.ts +4 -0
  415. package/src/hooks/useOrganisationSecurity.ts +4 -0
  416. package/src/hooks/usePerformanceMonitor.ts +4 -0
  417. package/src/hooks/usePermissionCache.ts +7 -0
  418. package/src/hooks/useQueryCache.ts +12 -1
  419. package/src/hooks/useSessionRestoration.ts +4 -0
  420. package/src/hooks/useStorage.ts +4 -0
  421. package/src/hooks/useToast.ts +1 -1
  422. package/src/index.ts +2 -1
  423. package/src/providers/__tests__/OrganisationProvider.test.tsx +92 -70
  424. package/src/providers/services/AuthServiceProvider.tsx +18 -0
  425. package/src/providers/services/EventServiceProvider.tsx +18 -0
  426. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  427. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  428. package/src/providers/services/UnifiedAuthProvider.tsx +36 -0
  429. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +29 -13
  430. package/src/rbac/README.md +1 -1
  431. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +2 -2
  432. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  433. package/src/rbac/adapters.tsx +14 -5
  434. package/src/rbac/api.ts +100 -67
  435. package/src/rbac/components/NavigationProvider.tsx +4 -1
  436. package/src/rbac/components/PagePermissionGuard.tsx +157 -17
  437. package/src/rbac/components/RoleBasedRouter.tsx +5 -1
  438. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  439. package/src/rbac/components/SecureDataProvider.tsx +20 -5
  440. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  441. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  442. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  443. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  444. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  445. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  446. package/src/rbac/engine.ts +38 -14
  447. package/src/rbac/hooks/permissions/index.ts +7 -0
  448. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  449. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  450. package/src/rbac/hooks/permissions/useCan.ts +347 -0
  451. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  452. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  453. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  454. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  455. package/src/rbac/hooks/useCan.test.ts +71 -64
  456. package/src/rbac/hooks/usePermissions.ts +14 -995
  457. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  458. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  459. package/src/rbac/hooks/useSecureSupabase.ts +33 -13
  460. package/src/rbac/permissions.ts +0 -30
  461. package/src/rbac/secureClient.ts +200 -61
  462. package/src/rbac/types.ts +8 -0
  463. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  464. package/src/theming/parseEventColours.ts +5 -19
  465. package/src/types/vitest-globals.d.ts +51 -26
  466. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  467. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  468. package/src/utils/__tests__/index.unit.test.ts +2 -2
  469. package/src/utils/audit/audit.ts +0 -3
  470. package/src/utils/core/cn.ts +1 -1
  471. package/src/utils/file-reference/index.ts +53 -1
  472. package/src/utils/formatting/formatting.ts +8 -18
  473. package/src/utils/index.ts +0 -1
  474. package/dist/chunk-3QRJFVBR.js.map +0 -1
  475. package/dist/chunk-3XTALGJF.js.map +0 -1
  476. package/dist/chunk-4N5C5XZU.js.map +0 -1
  477. package/dist/chunk-4ZC4GX36.js.map +0 -1
  478. package/dist/chunk-BYFSK72L.js.map +0 -1
  479. package/dist/chunk-EXUD6RNJ.js +0 -451
  480. package/dist/chunk-EXUD6RNJ.js.map +0 -1
  481. package/dist/chunk-GLK6VM3F.js.map +0 -1
  482. package/dist/chunk-I7PSE6JW.js.map +0 -1
  483. package/dist/chunk-JBKQ3SAO.js.map +0 -1
  484. package/dist/chunk-KNC55RTG.js.map +0 -1
  485. package/dist/chunk-LXQLPRQ2.js.map +0 -1
  486. package/dist/chunk-R77UEZ4E.js.map +0 -1
  487. package/dist/chunk-SQGMNID3.js.map +0 -1
  488. package/dist/chunk-T33XF5ZC.js.map +0 -1
  489. package/dist/chunk-XM25TVIE.js.map +0 -1
  490. package/docs/api/classes/ErrorBoundary.md +0 -144
  491. package/docs/migration/quick-migration-guide.md +0 -356
  492. package/docs/migration/service-architecture.md +0 -281
  493. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  494. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  495. package/src/hooks/useSecureDataAccess.ts +0 -681
  496. /package/dist/{DataTable-DQ7RSOHE.js.map → DataTable-TPTKCX4D.js.map} +0 -0
  497. /package/dist/{UnifiedAuthProvider-ATAP5UTR.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
  498. /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
  499. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  500. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  501. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  502. /package/docs/migration/{REACT_19_MIGRATION.md → V0.6.0_REACT_19_MIGRATION.md} +0 -0
@@ -25,12 +25,13 @@ import {
25
25
  SelectSeparator,
26
26
  SelectTrigger,
27
27
  SelectValue
28
- } from "./chunk-T33XF5ZC.js";
28
+ } from "./chunk-3XC4CPTD.js";
29
29
  import {
30
30
  useCan,
31
31
  usePermissions,
32
- useRBAC
33
- } from "./chunk-XM25TVIE.js";
32
+ useRBAC,
33
+ useResolvedScope
34
+ } from "./chunk-XWQCNGTQ.js";
34
35
  import {
35
36
  createFileReferenceService,
36
37
  generateFileUrlsBatch,
@@ -42,27 +43,26 @@ import {
42
43
  useFileDisplay,
43
44
  usePreventTabReload,
44
45
  usePublicFileDisplay
45
- } from "./chunk-JBKQ3SAO.js";
46
+ } from "./chunk-SFZUDBL5.js";
46
47
  import {
47
48
  useToast
48
- } from "./chunk-3QRJFVBR.js";
49
+ } from "./chunk-6SOIHG6Z.js";
49
50
  import {
50
51
  ErrorBoundary,
51
52
  PublicPageContext,
52
53
  useAppConfig,
53
54
  useEvents,
54
- useIsPublicPage,
55
- useResolvedScope
56
- } from "./chunk-3XTALGJF.js";
55
+ useIsPublicPage
56
+ } from "./chunk-MMZ7JXPU.js";
57
57
  import {
58
58
  EventServiceContext,
59
59
  useOrganisations,
60
60
  useSessionRestoration,
61
61
  useUnifiedAuth
62
- } from "./chunk-BYFSK72L.js";
62
+ } from "./chunk-EHMR7VYL.js";
63
63
  import {
64
64
  isSuperAdmin
65
- } from "./chunk-KNC55RTG.js";
65
+ } from "./chunk-24UVZUZG.js";
66
66
  import {
67
67
  assertAppId
68
68
  } from "./chunk-QXHPKYJV.js";
@@ -72,13 +72,13 @@ import {
72
72
  } from "./chunk-J36DSWQK.js";
73
73
  import {
74
74
  cn
75
- } from "./chunk-R77UEZ4E.js";
75
+ } from "./chunk-M43Y4SSO.js";
76
76
  import {
77
77
  getCurrentAppName
78
- } from "./chunk-I7PSE6JW.js";
78
+ } from "./chunk-F2IMUDXZ.js";
79
79
  import {
80
80
  clearPalette
81
- } from "./chunk-SQGMNID3.js";
81
+ } from "./chunk-L4OXEN46.js";
82
82
  import {
83
83
  createLogger,
84
84
  logger
@@ -423,6 +423,12 @@ function useFileUrl(fileReference, options) {
423
423
  setError(null);
424
424
  return;
425
425
  }
426
+ if (!supabase) {
427
+ setUrl(null);
428
+ setIsLoading(false);
429
+ setError(new Error("Supabase client is required for URL generation"));
430
+ return;
431
+ }
426
432
  if (isLoading || url && fileReferenceIdRef.current === fileReference.id) {
427
433
  return;
428
434
  }
@@ -554,10 +560,14 @@ function FileDisplayContent({
554
560
  };
555
561
  const handleDeleteConfirm = async () => {
556
562
  setDeleteDialogOpen(false);
557
- if (onDelete) {
558
- await onDelete();
563
+ try {
564
+ if (onDelete) {
565
+ await onDelete();
566
+ }
567
+ setImageError(false);
568
+ } catch (error2) {
569
+ setImageError(false);
559
570
  }
560
- setImageError(false);
561
571
  };
562
572
  const handleImageError = () => {
563
573
  setImageError(true);
@@ -971,9 +981,7 @@ function FileDisplayAuthenticated({
971
981
  showMetadata
972
982
  }) {
973
983
  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
- }
984
+ const [displayOnlyFileReference, setDisplayOnlyFileReference] = useState3(null);
977
985
  const {
978
986
  fileUrl,
979
987
  fileReference,
@@ -988,16 +996,15 @@ function FileDisplayAuthenticated({
988
996
  record_id,
989
997
  organisation_id,
990
998
  category,
991
- { supabase }
999
+ { supabase: supabase || null }
992
1000
  );
993
- const [displayOnlyFileReference, setDisplayOnlyFileReference] = useState3(null);
994
1001
  const displayOnlyFileUrlFromMap = displayOnlyFileReference ? fileUrls.get(displayOnlyFileReference.id) : null;
995
1002
  const displayOnlyFileUrlHook = useFileUrl(
996
1003
  displayOnlyFileReference && !displayOnlyFileUrlFromMap ? displayOnlyFileReference : null,
997
1004
  {
998
- supabase,
1005
+ supabase: supabase || null,
999
1006
  organisation_id,
1000
- autoLoad: !displayOnlyFileUrlFromMap && !!displayOnlyFileReference
1007
+ autoLoad: !displayOnlyFileUrlFromMap && !!displayOnlyFileReference && !!supabase
1001
1008
  }
1002
1009
  );
1003
1010
  const displayOnlyFileUrl = displayOnlyFileUrlFromMap || displayOnlyFileUrlHook.url;
@@ -1012,6 +1019,9 @@ function FileDisplayAuthenticated({
1012
1019
  setDisplayOnlyFileReference(null);
1013
1020
  }
1014
1021
  }, [displayOnly, category, fileReferences, fileUrls]);
1022
+ if (!supabase) {
1023
+ return /* @__PURE__ */ jsx4("figure", { className, title: "Error", children: /* @__PURE__ */ jsx4("p", { className: getFallbackClasses(fallbackSize || "md"), children: "Supabase client not available in authenticated context" }) });
1024
+ }
1015
1025
  const handleDelete = async () => {
1016
1026
  };
1017
1027
  let finalFileReference = fileReference;
@@ -1428,13 +1438,17 @@ function useFileReferenceById(supabase, fileReferenceId, organisationId) {
1428
1438
  return;
1429
1439
  }
1430
1440
  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);
1441
+ try {
1442
+ const service = createFileReferenceService(supabase);
1443
+ const url = await service.getFileUrl(
1444
+ fileReference.table_name,
1445
+ fileReference.record_id,
1446
+ organisationId
1447
+ );
1448
+ setFileUrl(url);
1449
+ } catch (error2) {
1450
+ setFileUrl(null);
1451
+ }
1438
1452
  };
1439
1453
  loadUrl();
1440
1454
  }, [fileReference, fileReferenceId, organisationId, supabase]);
@@ -1982,7 +1996,7 @@ var Calendar = React7.forwardRef(
1982
1996
  ] })
1983
1997
  );
1984
1998
  }
1985
- return child;
1999
+ return React7.isValidElement(child) ? React7.cloneElement(child, { key: child.key ?? `calendar-child-${index}` }) : child;
1986
2000
  }) });
1987
2001
  });
1988
2002
  CustomMonth.displayName = "CustomMonth";
@@ -2236,6 +2250,7 @@ function FormField({
2236
2250
  type,
2237
2251
  placeholder,
2238
2252
  "data-testid": testId,
2253
+ "aria-label": label || placeholder || name,
2239
2254
  className: cn(
2240
2255
  "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
2256
  fieldError && "border-destructive focus-visible:ring-destructive"
@@ -2864,9 +2879,10 @@ var UserMenu = React12.memo(function UserMenu2({
2864
2879
  /* @__PURE__ */ jsx16(ChevronDown, { className: "size-4" })
2865
2880
  ] }) }),
2866
2881
  /* @__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 })
2882
+ /* @__PURE__ */ jsx16(SelectLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs11("li", { className: "pt-2", children: [
2883
+ userInfo.displayName,
2884
+ /* @__PURE__ */ jsx16("br", {}),
2885
+ /* @__PURE__ */ jsx16("span", { className: "text-muted-foreground", children: userInfo.email })
2870
2886
  ] }) }),
2871
2887
  /* @__PURE__ */ jsx16(SelectSeparator, {}),
2872
2888
  /* @__PURE__ */ jsx16(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(SelectItem, { value: "change-password", children: [
@@ -2901,60 +2917,54 @@ var UserMenu = React12.memo(function UserMenu2({
2901
2917
  ] });
2902
2918
  });
2903
2919
  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
- ] });
2920
+ return /* @__PURE__ */ jsxs11(
2921
+ Button,
2922
+ {
2923
+ type: "button",
2924
+ disabled: true,
2925
+ variant: "outline",
2926
+ className: "flex items-center space-x-2",
2927
+ "aria-label": "Loading user menu",
2928
+ children: [
2929
+ /* @__PURE__ */ jsx16(LoadingSpinner, { size: "sm", className: "inline-block mr-2" }),
2930
+ /* @__PURE__ */ jsx16("span", { className: "truncate max-w-[150px]", children: "Loading..." }),
2931
+ /* @__PURE__ */ jsx16(ChevronDown, { className: "w-4 h-4 text-muted-foreground" })
2932
+ ]
2933
+ }
2934
+ );
2920
2935
  });
2921
2936
  UserMenu.Loading = UserMenuLoading;
2922
2937
 
2923
2938
  // src/components/NavigationMenu/NavigationMenu.tsx
2924
- import * as React13 from "react";
2939
+ import * as React14 from "react";
2925
2940
  import { ChevronDown as ChevronDown2 } from "lucide-react";
2926
- import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
2927
- var NavigationMenu = React13.forwardRef(({
2941
+
2942
+ // src/components/NavigationMenu/useNavigationFiltering.ts
2943
+ import * as React13 from "react";
2944
+ function useNavigationFiltering({
2928
2945
  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
2946
  itemsPreFiltered = false,
2943
- ...props
2944
- }, ref) => {
2945
- const [expandedItems, setExpandedItems] = React13.useState(/* @__PURE__ */ new Set());
2946
- const buttonRef = React13.useRef(null);
2947
+ auditLog = true
2948
+ }) {
2949
+ const [resolvedAppId, setResolvedAppId] = React13.useState(void 0);
2950
+ const previousFilteredItemsRef = React13.useRef([]);
2947
2951
  let authContext = null;
2948
2952
  try {
2949
2953
  authContext = useUnifiedAuth();
2950
2954
  } catch (error) {
2951
- logger.warn("NavigationMenu", "useUnifiedAuth not available, running in unauthenticated mode");
2955
+ logger.warn(
2956
+ "NavigationMenu",
2957
+ "useUnifiedAuth not available, running in unauthenticated mode"
2958
+ );
2952
2959
  }
2953
2960
  let rbacContext = null;
2954
2961
  try {
2955
2962
  rbacContext = useRBAC();
2956
2963
  } catch (error) {
2957
- logger.warn("NavigationMenu", "useRBAC not available, permission filtering disabled");
2964
+ logger.warn(
2965
+ "NavigationMenu",
2966
+ "useRBAC not available, permission filtering disabled"
2967
+ );
2958
2968
  }
2959
2969
  const eventLoadingRaw = authContext?.eventLoading;
2960
2970
  const eventLoading = eventLoadingRaw ?? false;
@@ -2964,11 +2974,9 @@ var NavigationMenu = React13.forwardRef(({
2964
2974
  const { selectedOrganisation } = authContext || {};
2965
2975
  const { resolvedScope, isLoading: scopeLoading, error: scopeError } = useResolvedScope({
2966
2976
  supabase: itemsPreFiltered ? null : supabase || null,
2967
- // Skip expensive resolution if pre-filtered
2968
2977
  selectedOrganisationId: itemsPreFiltered ? null : selectedOrganisation?.id || null,
2969
2978
  selectedEventId: itemsPreFiltered ? null : selectedEvent?.event_id || null
2970
2979
  });
2971
- const [resolvedAppId, setResolvedAppId] = React13.useState(void 0);
2972
2980
  React13.useEffect(() => {
2973
2981
  if (!scopeLoading && !resolvedScope?.appId && selectedOrganisation?.id && authContext?.appName && authContext?.user?.id && !resolvedAppId) {
2974
2982
  if (!authContext.user || !authContext.appName) {
@@ -2976,7 +2984,7 @@ var NavigationMenu = React13.forwardRef(({
2976
2984
  }
2977
2985
  const userId2 = authContext.user.id;
2978
2986
  const appName = authContext.appName;
2979
- import("./api-N774RPUA.js").then(({ resolveAppContext }) => {
2987
+ import("./api-MVVQZLJI.js").then(({ resolveAppContext }) => {
2980
2988
  resolveAppContext({
2981
2989
  userId: userId2,
2982
2990
  appName
@@ -2984,11 +2992,19 @@ var NavigationMenu = React13.forwardRef(({
2984
2992
  if (result?.appId) {
2985
2993
  setResolvedAppId(result.appId);
2986
2994
  }
2987
- }).catch((error) => {
2995
+ }).catch(() => {
2988
2996
  });
2997
+ }).catch(() => {
2989
2998
  });
2990
2999
  }
2991
- }, [scopeLoading, resolvedScope?.appId, selectedOrganisation?.id, authContext?.appName, authContext?.user?.id, resolvedAppId]);
3000
+ }, [
3001
+ scopeLoading,
3002
+ resolvedScope?.appId,
3003
+ selectedOrganisation?.id,
3004
+ authContext?.appName,
3005
+ authContext?.user?.id,
3006
+ resolvedAppId
3007
+ ]);
2992
3008
  const effectiveScope = React13.useMemo(() => {
2993
3009
  if (resolvedScope?.organisationId) {
2994
3010
  return resolvedScope;
@@ -3019,17 +3035,17 @@ var NavigationMenu = React13.forwardRef(({
3019
3035
  };
3020
3036
  }, [scopeKey, effectiveScope]);
3021
3037
  const userId = authContext?.user?.id || "";
3022
- const { permissions: permissionMap, hasAnyPermission, isLoading: permissionsLoading, error: permissionsError } = usePermissions(
3038
+ const {
3039
+ permissions: permissionMap,
3040
+ hasAnyPermission,
3041
+ isLoading: permissionsLoading,
3042
+ error: permissionsError
3043
+ } = usePermissions(
3023
3044
  itemsPreFiltered ? null : userId,
3024
- // Pass null to trigger early return (empty string would wait 3s)
3025
3045
  itemsPreFiltered ? void 0 : stableScope.organisationId,
3026
- // Pass undefined to skip timeout
3027
3046
  itemsPreFiltered ? void 0 : stableScope.eventId,
3028
- // Skip if pre-filtered
3029
3047
  itemsPreFiltered ? void 0 : stableScope.appId
3030
- // Skip if pre-filtered
3031
3048
  );
3032
- const previousFilteredItemsRef = React13.useRef([]);
3033
3049
  const filteredItems = React13.useMemo(() => {
3034
3050
  if (itemsPreFiltered && items && items.length > 0) {
3035
3051
  const visibleItems = (items || []).filter((item) => !item.meta?.hidden);
@@ -3059,9 +3075,13 @@ var NavigationMenu = React13.forwardRef(({
3059
3075
  return [];
3060
3076
  }
3061
3077
  if (permissionsError) {
3062
- logger.warn("NavigationMenu", "Permission check error - showing no items for security", {
3063
- permissionsError: permissionsError?.message
3064
- });
3078
+ logger.warn(
3079
+ "NavigationMenu",
3080
+ "Permission check error - showing no items for security",
3081
+ {
3082
+ permissionsError: permissionsError?.message
3083
+ }
3084
+ );
3065
3085
  return [];
3066
3086
  }
3067
3087
  if (!permissionMap || Object.keys(permissionMap).length === 0) {
@@ -3087,7 +3107,7 @@ var NavigationMenu = React13.forwardRef(({
3087
3107
  if (item.permissions && item.permissions.length > 0 && !item.href) {
3088
3108
  const permissions = item.permissions.filter((p) => typeof p === "string").map((p) => p);
3089
3109
  if (permissions.length > 0) {
3090
- const hasPermission = hasAnyPermission(permissions);
3110
+ const hasPermission = hasAnyPermission?.(permissions);
3091
3111
  if (!hasPermission) {
3092
3112
  return false;
3093
3113
  }
@@ -3119,13 +3139,12 @@ var NavigationMenu = React13.forwardRef(({
3119
3139
  if (typeof item.accessLevel === "string") {
3120
3140
  const accessLevel = item.accessLevel.toLowerCase();
3121
3141
  const userEventRole = rbacContext.eventAppRole;
3122
- if (rbacContext.isSuperAdmin) {
3123
- } else {
3142
+ if (!rbacContext.isSuperAdmin) {
3124
3143
  const roleToAccessLevel = {
3125
- "viewer": "viewer",
3126
- "participant": "participant",
3127
- "planner": "planner",
3128
- "event_admin": "admin"
3144
+ viewer: "viewer",
3145
+ participant: "participant",
3146
+ planner: "planner",
3147
+ event_admin: "admin"
3129
3148
  };
3130
3149
  const userAccessLevel = userEventRole ? roleToAccessLevel[userEventRole] || "viewer" : null;
3131
3150
  const levelHierarchy = {
@@ -3178,7 +3197,6 @@ var NavigationMenu = React13.forwardRef(({
3178
3197
  }, [
3179
3198
  items,
3180
3199
  itemsPreFiltered,
3181
- // Add itemsPreFiltered to dependencies
3182
3200
  authContext,
3183
3201
  rbacContext,
3184
3202
  permissionMap,
@@ -3189,13 +3207,48 @@ var NavigationMenu = React13.forwardRef(({
3189
3207
  resolvedScope,
3190
3208
  effectiveScope,
3191
3209
  auditLog,
3192
- // Add event context state to dependencies so we re-check permissions when event context becomes available
3193
3210
  eventLoadingRaw,
3194
3211
  eventLoading,
3195
3212
  selectedEvent,
3196
3213
  orgContextReady,
3197
- selectedOrganisation?.id
3214
+ selectedOrganisation?.id,
3215
+ permissionsError,
3216
+ stableScope.organisationId,
3217
+ stableScope.eventId,
3218
+ stableScope.appId
3198
3219
  ]);
3220
+ return {
3221
+ authContext,
3222
+ rbacContext,
3223
+ filteredItems,
3224
+ permissionMap,
3225
+ hasAnyPermission: hasAnyPermission || null
3226
+ };
3227
+ }
3228
+
3229
+ // src/components/NavigationMenu/NavigationMenu.tsx
3230
+ import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
3231
+ var NavigationMenu = React14.forwardRef(({
3232
+ items,
3233
+ mode = "dropdown",
3234
+ currentPath,
3235
+ onNavigate,
3236
+ className,
3237
+ disabled = false,
3238
+ buttonText = "Menu",
3239
+ showIcons = true,
3240
+ navigationLabel = "Main navigation",
3241
+ // NEW: Phase 2 - Enhanced Security Features
3242
+ strictMode = true,
3243
+ auditLog = true,
3244
+ onNavigationAccessDenied,
3245
+ onStrictModeViolation,
3246
+ itemsPreFiltered = false,
3247
+ ...props
3248
+ }, ref) => {
3249
+ const [expandedItems, setExpandedItems] = React14.useState(/* @__PURE__ */ new Set());
3250
+ const buttonRef = React14.useRef(null);
3251
+ const { authContext, rbacContext, filteredItems, permissionMap, hasAnyPermission } = useNavigationFiltering({ items, itemsPreFiltered, auditLog });
3199
3252
  const handleHierarchicalKeyDown = (event, item) => {
3200
3253
  switch (event.key) {
3201
3254
  case "Enter":
@@ -3338,7 +3391,7 @@ var NavigationMenu = React13.forwardRef(({
3338
3391
  id: `submenu-${item.id}`,
3339
3392
  role: "menu",
3340
3393
  "aria-label": `${item.label} submenu`,
3341
- children: item.children.map((child) => /* @__PURE__ */ jsx17(React13.Fragment, { children: renderHierarchicalItem(child, level + 1) }, child.id))
3394
+ children: item.children.map((child) => /* @__PURE__ */ jsx17(React14.Fragment, { children: renderHierarchicalItem(child, level + 1) }, child.id))
3342
3395
  }
3343
3396
  )
3344
3397
  ] }) : /* @__PURE__ */ jsx17(
@@ -3400,7 +3453,7 @@ var NavigationMenu = React13.forwardRef(({
3400
3453
  className,
3401
3454
  "aria-label": navigationLabel,
3402
3455
  ...props,
3403
- children: /* @__PURE__ */ jsx17("ul", { role: "menubar", children: filteredItems.map((item) => /* @__PURE__ */ jsx17(React13.Fragment, { children: renderHierarchicalItem(item, 0) }, item.id)) })
3456
+ children: /* @__PURE__ */ jsx17("ul", { role: "menubar", children: filteredItems.map((item) => /* @__PURE__ */ jsx17(React14.Fragment, { children: renderHierarchicalItem(item, 0) }, item.id)) })
3404
3457
  }
3405
3458
  );
3406
3459
  });
@@ -3445,7 +3498,7 @@ function Header({
3445
3498
  return /* @__PURE__ */ jsx18("header", { className: cn(
3446
3499
  "w-full border-b border-main-200 h-16 shadow-sm bg-main-100 ",
3447
3500
  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: [
3501
+ ), role: "banner", children: /* @__PURE__ */ jsxs13("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: [
3449
3502
  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(
3450
3503
  "img",
3451
3504
  {
@@ -3486,32 +3539,36 @@ function Header({
3486
3539
  itemsPreFiltered: true
3487
3540
  }
3488
3541
  ),
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
- ] })
3542
+ showOrgSelector ? /* @__PURE__ */ jsx18(OrganisationSelectorConditional, {}) : null,
3543
+ showEventSelector ? /* @__PURE__ */ jsx18(
3544
+ EventSelector,
3545
+ {
3546
+ placeholder: "Select event",
3547
+ className: cn(
3548
+ "w-96",
3549
+ // If both org selector and actions exist, EventSelector uses 1 column
3550
+ // If only one exists, EventSelector spans 2 columns
3551
+ // If neither exists, EventSelector spans 3 columns
3552
+ showOrgSelector && actions ? "col-span-1" : showOrgSelector || actions ? "col-span-2" : "col-span-3"
3553
+ ),
3554
+ "data-testid": "event-selector"
3555
+ }
3556
+ ) : null,
3557
+ actions,
3558
+ showUserMenu && (userMenu ? userMenu : /* @__PURE__ */ jsx18(
3559
+ UserMenu,
3560
+ {
3561
+ user: user || null,
3562
+ onSignOut,
3563
+ onChangePassword,
3564
+ className: "w-70"
3565
+ }
3566
+ ))
3510
3567
  ] }) });
3511
3568
  }
3512
3569
 
3513
3570
  // src/components/Footer/Footer.tsx
3514
- import React14 from "react";
3571
+ import React15 from "react";
3515
3572
  import { Fragment as Fragment7, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
3516
3573
  var FooterComponent = ({
3517
3574
  companyName = "Solvera Solutions Pty Ltd",
@@ -3531,11 +3588,11 @@ var FooterComponent = ({
3531
3588
  ] }) });
3532
3589
  };
3533
3590
  FooterComponent.displayName = "Footer";
3534
- var Footer = React14.memo(FooterComponent);
3591
+ var Footer = React15.memo(FooterComponent);
3535
3592
  Footer.displayName = "Footer";
3536
3593
 
3537
3594
  // src/components/PaceAppLayout/PaceAppLayout.tsx
3538
- import { useState as useState12, useEffect as useEffect8, useMemo as useMemo9 } from "react";
3595
+ import { useState as useState13, useEffect as useEffect8, useMemo as useMemo9 } from "react";
3539
3596
  import { Outlet, useNavigate, useLocation } from "react-router-dom";
3540
3597
  import { Fragment as Fragment8, jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
3541
3598
  var EMPTY_PAGE_ID_MAPPING = {};
@@ -3579,8 +3636,8 @@ function PaceAppLayout({
3579
3636
  isLoading: organisationLoading
3580
3637
  } = useOrganisations();
3581
3638
  const { isSuperAdmin: isSuperAdminFromRBAC, isLoading: rbacLoading } = useRBAC();
3582
- const [isSuperAdminDirect, setIsSuperAdminDirect] = useState12(false);
3583
- const [isCheckingSuperAdminDirect, setIsCheckingSuperAdminDirect] = useState12(false);
3639
+ const [isSuperAdminDirect, setIsSuperAdminDirect] = useState13(false);
3640
+ const [isCheckingSuperAdminDirect, setIsCheckingSuperAdminDirect] = useState13(false);
3584
3641
  useEffect8(() => {
3585
3642
  const checkSuperAdminDirect = async () => {
3586
3643
  if (!user?.id) {
@@ -3594,8 +3651,8 @@ function PaceAppLayout({
3594
3651
  }
3595
3652
  setIsCheckingSuperAdminDirect(true);
3596
3653
  try {
3597
- const superAdminStatus = await isSuperAdmin(user.id);
3598
- setIsSuperAdminDirect(superAdminStatus);
3654
+ const superAdminStatus2 = await isSuperAdmin(user.id);
3655
+ setIsSuperAdminDirect(superAdminStatus2);
3599
3656
  } catch (error) {
3600
3657
  logger.error("PaceAppLayout", "Error checking super admin status directly", { userId: user?.id, error });
3601
3658
  setIsSuperAdminDirect(false);
@@ -3665,6 +3722,7 @@ function PaceAppLayout({
3665
3722
  return permissionString;
3666
3723
  }, [enforcePermissions, currentRoutePermission, currentPageId]);
3667
3724
  const shouldCheckPermission = enforcePermissions && !!currentPermission && !!currentPageId;
3725
+ const superAdminStatus = isSuperAdminFromRBAC ? true : isCheckingSuperAdminDirect ? null : isSuperAdminDirect;
3668
3726
  const { can: canFromHook, isLoading: isCheckingPermission, error: permissionError } = useCan(
3669
3727
  user?.id || "",
3670
3728
  scope,
@@ -3672,6 +3730,8 @@ function PaceAppLayout({
3672
3730
  shouldCheckPermission ? currentPageId : "",
3673
3731
  true,
3674
3732
  // useCache
3733
+ superAdminStatus,
3734
+ // Pass super admin status to avoid duplicate check
3675
3735
  appName
3676
3736
  // Pass appName for PORTAL/ADMIN special case
3677
3737
  );
@@ -3700,7 +3760,7 @@ function PaceAppLayout({
3700
3760
  onPageAccessDenied(currentPageId, currentRoutePermission);
3701
3761
  }
3702
3762
  }, [enforcePermissions, can, isCheckingPermission, isSuperAdmin2, currentPageId, currentRoutePermission, user?.id, strictMode, auditLog, onPageAccessDenied, onStrictModeViolation]);
3703
- const [filteredMenuItems, setFilteredMenuItems] = useState12(baseMenuItems);
3763
+ const [filteredMenuItems, setFilteredMenuItems] = useState13(baseMenuItems);
3704
3764
  useEffect8(() => {
3705
3765
  let isMounted = true;
3706
3766
  const filterItems = async () => {
@@ -3727,7 +3787,7 @@ function PaceAppLayout({
3727
3787
  return;
3728
3788
  }
3729
3789
  try {
3730
- const { isSuperAdmin: checkSuperAdminDynamic } = await import("./api-N774RPUA.js");
3790
+ const { isSuperAdmin: checkSuperAdminDynamic } = await import("./api-MVVQZLJI.js");
3731
3791
  const isSuper = await checkSuperAdminDynamic(user.id);
3732
3792
  if (isSuper) {
3733
3793
  if (isMounted) {
@@ -3742,7 +3802,7 @@ function PaceAppLayout({
3742
3802
  }
3743
3803
  }
3744
3804
  try {
3745
- const { getPermissionMap } = await import("./api-N774RPUA.js");
3805
+ const { getPermissionMap } = await import("./api-MVVQZLJI.js");
3746
3806
  const permissionScope = {
3747
3807
  organisationId: currentScope.organisationId,
3748
3808
  eventId: currentScope.eventId,
@@ -3798,7 +3858,7 @@ function PaceAppLayout({
3798
3858
  let hasAccess = true;
3799
3859
  if (currentRoute.pageId && currentRoute.permissions && currentRoute.permissions.length > 0) {
3800
3860
  try {
3801
- const { isPermittedCached } = await import("./api-N774RPUA.js");
3861
+ const { isPermittedCached } = await import("./api-MVVQZLJI.js");
3802
3862
  const hasPagePermission = await isPermittedCached({
3803
3863
  userId: user?.id || "",
3804
3864
  scope,
@@ -3814,7 +3874,7 @@ function PaceAppLayout({
3814
3874
  }
3815
3875
  }
3816
3876
  if (hasAccess && currentRoute.roles && currentRoute.roles.length > 0 && user?.id) {
3817
- const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-ATAP5UTR.js");
3877
+ const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-CH6Z342H.js");
3818
3878
  hasAccess = true;
3819
3879
  }
3820
3880
  if (!isMounted) return;
@@ -3845,20 +3905,34 @@ function PaceAppLayout({
3845
3905
  };
3846
3906
  }, [roleBasedRouting, routeConfig, location.pathname, strictMode, user?.id, fallbackRoute, scope, navigate, auditLog, onRouteAccessDenied, onRouteStrictModeViolation]);
3847
3907
  const handleSignOut = async () => {
3848
- await signOut();
3908
+ try {
3909
+ await signOut();
3910
+ } catch (error) {
3911
+ logger.error("PaceAppLayout", "Failed to sign out", { error: error instanceof Error ? error.message : String(error) });
3912
+ }
3849
3913
  };
3850
3914
  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 });
3915
+ try {
3916
+ const result = await updatePassword(newPassword);
3917
+ if (result?.error) {
3918
+ logger.error("PaceAppLayout", "Failed to change password", { error: result.error.message });
3919
+ return {
3920
+ error: {
3921
+ message: result.error.message,
3922
+ code: result.error.name || "PASSWORD_UPDATE_ERROR"
3923
+ }
3924
+ };
3925
+ }
3926
+ return {};
3927
+ } catch (error) {
3928
+ logger.error("PaceAppLayout", "Failed to change password", { error: error instanceof Error ? error.message : String(error) });
3854
3929
  return {
3855
3930
  error: {
3856
- message: result.error.message,
3857
- code: result.error.name || "PASSWORD_UPDATE_ERROR"
3931
+ message: error instanceof Error ? error.message : "An unexpected error occurred",
3932
+ code: "PASSWORD_UPDATE_ERROR"
3858
3933
  }
3859
3934
  };
3860
3935
  }
3861
- return {};
3862
3936
  };
3863
3937
  if (user?.id && organisationLoading && !isSuperAdmin2 && !isCheckingSuperAdminDirect && !rbacLoading && !selectedOrganisationId) {
3864
3938
  return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
@@ -3937,7 +4011,7 @@ function PaceAppLayout({
3937
4011
  }
3938
4012
 
3939
4013
  // src/components/PaceLoginPage/PaceLoginPage.tsx
3940
- import { useEffect as useEffect9, useState as useState13, useContext as useContext2 } from "react";
4014
+ import { useEffect as useEffect9, useState as useState14, useContext as useContext2 } from "react";
3941
4015
  import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
3942
4016
  import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
3943
4017
  var PaceLoginPage = ({
@@ -3948,9 +4022,9 @@ var PaceLoginPage = ({
3948
4022
  const { signIn, isAuthenticated, isLoading, authError, user, supabase } = useUnifiedAuth();
3949
4023
  const navigate = useNavigate2();
3950
4024
  const location = useLocation2();
3951
- const [isSigningIn, setIsSigningIn] = useState13(false);
3952
- const [accessError, setAccessError] = useState13(null);
3953
- const [isCheckingAccess, setIsCheckingAccess] = useState13(false);
4025
+ const [isSigningIn, setIsSigningIn] = useState14(false);
4026
+ const [accessError, setAccessError] = useState14(null);
4027
+ const [isCheckingAccess, setIsCheckingAccess] = useState14(false);
3954
4028
  const eventServiceContext = useContext2(EventServiceContext);
3955
4029
  const eventService = eventServiceContext?.eventService || null;
3956
4030
  useEffect9(() => {
@@ -4102,7 +4176,7 @@ var SessionRestorationLoader = ({
4102
4176
  className
4103
4177
  }) => {
4104
4178
  return /* @__PURE__ */ jsxs17(
4105
- "div",
4179
+ Alert,
4106
4180
  {
4107
4181
  className: cn(
4108
4182
  "flex flex-col items-center justify-center h-screen w-full gap-4 text-center p-4 bg-background",
@@ -4113,19 +4187,18 @@ var SessionRestorationLoader = ({
4113
4187
  "aria-label": message,
4114
4188
  children: [
4115
4189
  /* @__PURE__ */ jsx22(LoadingSpinner, { size: "lg" }),
4116
- /* @__PURE__ */ jsx22("div", { className: "text-sm text-sec-600", children: message })
4190
+ /* @__PURE__ */ jsx22("span", { className: "text-sm text-sec-600", children: message })
4117
4191
  ]
4118
4192
  }
4119
4193
  );
4120
4194
  };
4121
4195
 
4122
4196
  // src/components/ProtectedRoute/ProtectedRoute.tsx
4123
- import { useMemo as useMemo10, useEffect as useEffect10, useRef as useRef8, useState as useState14 } from "react";
4197
+ import { useMemo as useMemo10, useEffect as useEffect10, useRef as useRef9, useState as useState15 } from "react";
4124
4198
  import { Navigate, Outlet as Outlet2 } from "react-router-dom";
4125
4199
  import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
4126
4200
  function ProtectedRoute({
4127
4201
  requireEvent = false,
4128
- allowSuperAdminBypass = false,
4129
4202
  noEventsFallback,
4130
4203
  loadingFallback,
4131
4204
  loginPath = "/login"
@@ -4137,9 +4210,9 @@ function ProtectedRoute({
4137
4210
  const eventLoading = requireEvent ? eventsContext.isLoading || false : false;
4138
4211
  const sessionRestoration = useSessionRestoration();
4139
4212
  usePreventTabReload({ enabled: true, gracePeriodMs: 2e3 });
4140
- const wasAuthenticatedRef = useRef8(false);
4141
- const [shouldRedirect, setShouldRedirect] = useState14(false);
4142
- const tabJustBecameVisibleRef = useRef8(false);
4213
+ const wasAuthenticatedRef = useRef9(false);
4214
+ const [shouldRedirect, setShouldRedirect] = useState15(false);
4215
+ const tabJustBecameVisibleRef = useRef9(false);
4143
4216
  useEffect10(() => {
4144
4217
  if (isAuthenticated) {
4145
4218
  wasAuthenticatedRef.current = true;
@@ -4253,7 +4326,7 @@ function ProtectedRoute({
4253
4326
  }
4254
4327
 
4255
4328
  // src/components/FileUpload/FileUpload.tsx
4256
- import { useState as useState15, useCallback as useCallback11, useRef as useRef9, useEffect as useEffect11, useMemo as useMemo11 } from "react";
4329
+ import { useState as useState16, useCallback as useCallback11, useRef as useRef10, useEffect as useEffect11, useMemo as useMemo11 } from "react";
4257
4330
  import { Fragment as Fragment9, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
4258
4331
  function FileUpload({
4259
4332
  supabase,
@@ -4280,12 +4353,19 @@ function FileUpload({
4280
4353
  onProgress,
4281
4354
  children
4282
4355
  }) {
4283
- const [isDragging, setIsDragging] = useState15(false);
4284
- const [uploadStates, setUploadStates] = useState15(/* @__PURE__ */ new Map());
4285
- const [resolvedAppId, setResolvedAppId] = useState15(app_id || null);
4286
- const [isResolvingAppId, setIsResolvingAppId] = useState15(!app_id);
4287
- const [appIdError, setAppIdError] = useState15(null);
4288
- const fileInputRef = useRef9(null);
4356
+ if (!pageContext) {
4357
+ const errorMsg = "pageContext is required for FileUpload component. This is used for permission checks.";
4358
+ if (import.meta.env.MODE === "development") {
4359
+ console.error("[FileUpload]", errorMsg);
4360
+ }
4361
+ throw new Error(errorMsg);
4362
+ }
4363
+ const [isDragging, setIsDragging] = useState16(false);
4364
+ const [uploadStates, setUploadStates] = useState16(/* @__PURE__ */ new Map());
4365
+ const [resolvedAppId, setResolvedAppId] = useState16(app_id || null);
4366
+ const [isResolvingAppId, setIsResolvingAppId] = useState16(!app_id);
4367
+ const [appIdError, setAppIdError] = useState16(null);
4368
+ const fileInputRef = useRef10(null);
4289
4369
  const { uploadFile, isLoading, error } = useFileReference(supabase);
4290
4370
  useEffect11(() => {
4291
4371
  if (app_id) {
@@ -4447,6 +4527,10 @@ function FileUpload({
4447
4527
  const errorMsg = appIdError || "App ID not available. Please provide app_id prop or set app name.";
4448
4528
  throw new Error(errorMsg);
4449
4529
  }
4530
+ if (!pageContext) {
4531
+ const errorMsg = "pageContext is required for file upload. This is used for permission checks.";
4532
+ throw new Error(errorMsg);
4533
+ }
4450
4534
  const result = await uploadFile({
4451
4535
  table_name,
4452
4536
  record_id,
@@ -4544,7 +4628,7 @@ function FileUpload({
4544
4628
  onUploadError?.(errorMessage, file);
4545
4629
  }
4546
4630
  }
4547
- }, [uploadFile, table_name, record_id, organisation_id, resolvedAppId, category, folder, isPublic, maxSize, onUploadSuccess, onUploadError, onProgress, validateFile, generatePreview, showPreview, appIdError]);
4631
+ }, [uploadFile, table_name, record_id, organisation_id, resolvedAppId, category, folder, isPublic, maxSize, onUploadSuccess, onUploadError, onProgress, validateFile, generatePreview, showPreview, appIdError, pageContext]);
4548
4632
  const handleDragOver = useCallback11((e) => {
4549
4633
  e.preventDefault();
4550
4634
  e.stopPropagation();
@@ -4616,7 +4700,8 @@ function FileUpload({
4616
4700
  onChange: handleFileInputChange,
4617
4701
  className: "hidden",
4618
4702
  disabled: isDisabled,
4619
- "data-testid": "file-input"
4703
+ "data-testid": "file-input",
4704
+ "aria-label": accept ? `Upload file${multiple ? "s" : ""} (${accept})` : `Upload file${multiple ? "s" : ""}`
4620
4705
  }
4621
4706
  ),
4622
4707
  /* @__PURE__ */ jsx24("div", { className: "text-sec-600", children: isResolvingAppId ? "Resolving app configuration..." : isDragging ? "Drop files here..." : /* @__PURE__ */ jsxs19(Fragment9, { children: [
@@ -4725,9 +4810,9 @@ function FileUpload({
4725
4810
  }
4726
4811
 
4727
4812
  // src/components/Table/Table.tsx
4728
- import * as React19 from "react";
4813
+ import * as React20 from "react";
4729
4814
  import { jsx as jsx25 } from "react/jsx-runtime";
4730
- var Table = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4815
+ var Table = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4731
4816
  "table",
4732
4817
  {
4733
4818
  ref,
@@ -4736,9 +4821,9 @@ var Table = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
4736
4821
  }
4737
4822
  ));
4738
4823
  Table.displayName = "Table";
4739
- var TableHeader = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
4824
+ var TableHeader = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
4740
4825
  TableHeader.displayName = "TableHeader";
4741
- var TableBody = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4826
+ var TableBody = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4742
4827
  "tbody",
4743
4828
  {
4744
4829
  ref,
@@ -4747,7 +4832,7 @@ var TableBody = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE_
4747
4832
  }
4748
4833
  ));
4749
4834
  TableBody.displayName = "TableBody";
4750
- var TableFooter = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4835
+ var TableFooter = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4751
4836
  "tfoot",
4752
4837
  {
4753
4838
  ref,
@@ -4759,7 +4844,7 @@ var TableFooter = React19.forwardRef(({ className, ...props }, ref) => /* @__PUR
4759
4844
  }
4760
4845
  ));
4761
4846
  TableFooter.displayName = "TableFooter";
4762
- var TableRow = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4847
+ var TableRow = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4763
4848
  "tr",
4764
4849
  {
4765
4850
  ref,
@@ -4771,7 +4856,7 @@ var TableRow = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__
4771
4856
  }
4772
4857
  ));
4773
4858
  TableRow.displayName = "TableRow";
4774
- var TableHead = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4859
+ var TableHead = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4775
4860
  "th",
4776
4861
  {
4777
4862
  ref,
@@ -4783,7 +4868,7 @@ var TableHead = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE_
4783
4868
  }
4784
4869
  ));
4785
4870
  TableHead.displayName = "TableHead";
4786
- var TableCell = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4871
+ var TableCell = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4787
4872
  "td",
4788
4873
  {
4789
4874
  ref,
@@ -4792,7 +4877,7 @@ var TableCell = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE_
4792
4877
  }
4793
4878
  ));
4794
4879
  TableCell.displayName = "TableCell";
4795
- var TableCaption = React19.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4880
+ var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
4796
4881
  "caption",
4797
4882
  {
4798
4883
  ref,
@@ -4882,7 +4967,6 @@ function PublicPageLayout({
4882
4967
  error = null,
4883
4968
  refetch,
4884
4969
  showFooter = true,
4885
- className = "",
4886
4970
  errorFallback: ErrorFallback,
4887
4971
  loadingFallback: LoadingFallback,
4888
4972
  customHeader,
@@ -4988,4 +5072,4 @@ export {
4988
5072
  PublicPageFooter,
4989
5073
  PublicPageLayout
4990
5074
  };
4991
- //# sourceMappingURL=chunk-GLK6VM3F.js.map
5075
+ //# sourceMappingURL=chunk-NECFR5MM.js.map