@jmruthers/pace-core 0.5.75 → 0.5.77

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 (507) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/dist/{RBACService-C4udt_Zp.d.ts → AuthService-SBHZQtCH.d.ts} +5 -118
  3. package/dist/{DataTable-ntgmhO2W.d.ts → DataTable-BE0OXZKQ.d.ts} +9 -2
  4. package/dist/DataTable-QCNCV6IK.js +157 -0
  5. package/dist/{PublicLoadingSpinner-BKNBT6b6.d.ts → PublicLoadingSpinner-CnUaz0vG.d.ts} +33 -19
  6. package/dist/{UnifiedAuthProvider-Bj6YCf7c.d.ts → UnifiedAuthProvider-B391Aqum.d.ts} +42 -45
  7. package/dist/{UnifiedAuthProvider-3NKDOSOK.js → UnifiedAuthProvider-Z2FWNW7O.js} +4 -5
  8. package/dist/{api-DDMUKIUD.js → api-KG4A2X7P.js} +9 -3
  9. package/dist/{audit-6TOCAMKO.js → audit-65VNHEV2.js} +2 -2
  10. package/dist/{chunk-2DFZ432F.js → chunk-7PX43UYN.js} +197 -629
  11. package/dist/chunk-7PX43UYN.js.map +1 -0
  12. package/dist/{chunk-DAXLNIDY.js → chunk-C4RQ3GQA.js} +108 -32
  13. package/dist/chunk-C4RQ3GQA.js.map +1 -0
  14. package/dist/{chunk-LW7MMEAQ.js → chunk-CRKP3HXI.js} +2 -2
  15. package/dist/{chunk-XLZ7U46Z.js → chunk-CVMVPYAL.js} +9 -60
  16. package/dist/chunk-CVMVPYAL.js.map +1 -0
  17. package/dist/{chunk-CY3AHGO4.js → chunk-DDPG7FCX.js} +3395 -3254
  18. package/dist/chunk-DDPG7FCX.js.map +1 -0
  19. package/dist/{chunk-URUTVZ7N.js → chunk-DVHZ5L55.js} +2 -2
  20. package/dist/{chunk-5BSLGBYI.js → chunk-JCQZ6LA7.js} +2 -8
  21. package/dist/{chunk-5BSLGBYI.js.map → chunk-JCQZ6LA7.js.map} +1 -1
  22. package/dist/{chunk-WN6XJWOS.js → chunk-JDQ7T3QB.js} +256 -743
  23. package/dist/chunk-JDQ7T3QB.js.map +1 -0
  24. package/dist/{chunk-ZTT2AXMX.js → chunk-LMYTEMUH.js} +153 -132
  25. package/dist/chunk-LMYTEMUH.js.map +1 -0
  26. package/dist/{chunk-33PHABLB.js → chunk-NKT2DLZI.js} +13 -130
  27. package/dist/chunk-NKT2DLZI.js.map +1 -0
  28. package/dist/chunk-PUKTJMRT.js +732 -0
  29. package/dist/chunk-PUKTJMRT.js.map +1 -0
  30. package/dist/{chunk-B2WTCLCV.js → chunk-Q7APDV6H.js} +18 -8
  31. package/dist/chunk-Q7APDV6H.js.map +1 -0
  32. package/dist/{chunk-FGMFQSHX.js → chunk-S63MFSY6.js} +500 -551
  33. package/dist/chunk-S63MFSY6.js.map +1 -0
  34. package/dist/{chunk-NTNILOBC.js → chunk-TLD5BEU6.js} +4 -4
  35. package/dist/chunk-WUXCWRL6.js +20 -0
  36. package/dist/chunk-WUXCWRL6.js.map +1 -0
  37. package/dist/{chunk-YNUBMSMV.js → chunk-YCKPEMJA.js} +186 -263
  38. package/dist/chunk-YCKPEMJA.js.map +1 -0
  39. package/dist/{chunk-A4FUBC7B.js → chunk-Z3T6RK3K.js} +2 -4
  40. package/dist/{chunk-A4FUBC7B.js.map → chunk-Z3T6RK3K.js.map} +1 -1
  41. package/dist/components.d.ts +6 -6
  42. package/dist/components.js +17 -20
  43. package/dist/components.js.map +1 -1
  44. package/dist/{database-C3Szpi5J.d.ts → database-BXAfr2Y_.d.ts} +18 -0
  45. package/dist/hooks.d.ts +21 -44
  46. package/dist/hooks.js +12 -13
  47. package/dist/hooks.js.map +1 -1
  48. package/dist/index.d.ts +19 -27
  49. package/dist/index.js +27 -33
  50. package/dist/index.js.map +1 -1
  51. package/dist/{organisation-BtshODVF.d.ts → organisation-D6qRDtbF.d.ts} +1 -1
  52. package/dist/providers.d.ts +7 -21
  53. package/dist/providers.js +3 -10
  54. package/dist/rbac/index.d.ts +118 -215
  55. package/dist/rbac/index.js +18 -18
  56. package/dist/{types-CGX9Vyf5.d.ts → types-BDg1mAGG.d.ts} +36 -6
  57. package/dist/types.d.ts +3 -3
  58. package/dist/types.js +61 -18
  59. package/dist/types.js.map +1 -1
  60. package/dist/{unified-CM7T0aTK.d.ts → unified-DQ4VcT7H.d.ts} +1 -1
  61. package/dist/{usePublicRouteParams-B-CumWRc.d.ts → usePublicRouteParams-BlgwXweB.d.ts} +3 -3
  62. package/dist/utils.d.ts +2 -2
  63. package/dist/utils.js +52 -9
  64. package/dist/utils.js.map +1 -1
  65. package/docs/CONTENT_AUDIT_REPORT.md +253 -0
  66. package/docs/DOCUMENTATION_AUDIT.md +172 -0
  67. package/docs/README.md +142 -147
  68. package/docs/STYLE_GUIDE.md +37 -0
  69. package/docs/api/classes/ColumnFactory.md +17 -17
  70. package/docs/api/classes/ErrorBoundary.md +1 -1
  71. package/docs/api/classes/InvalidScopeError.md +4 -4
  72. package/docs/api/classes/MissingUserContextError.md +4 -4
  73. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  74. package/docs/api/classes/PermissionDeniedError.md +5 -5
  75. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  76. package/docs/api/classes/RBACAuditManager.md +8 -8
  77. package/docs/api/classes/RBACCache.md +35 -5
  78. package/docs/api/classes/RBACEngine.md +49 -20
  79. package/docs/api/classes/RBACError.md +4 -4
  80. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  81. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  82. package/docs/api/classes/StorageUtils.md +1 -1
  83. package/docs/api/enums/FileCategory.md +1 -1
  84. package/docs/api/interfaces/AggregateConfig.md +4 -4
  85. package/docs/api/interfaces/ButtonProps.md +1 -1
  86. package/docs/api/interfaces/CardProps.md +1 -1
  87. package/docs/api/interfaces/ColorPalette.md +1 -1
  88. package/docs/api/interfaces/ColorShade.md +1 -1
  89. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  90. package/docs/api/interfaces/DataRecord.md +11 -0
  91. package/docs/api/interfaces/DataTableAction.md +65 -29
  92. package/docs/api/interfaces/DataTableColumn.md +36 -23
  93. package/docs/api/interfaces/DataTableProps.md +80 -38
  94. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  95. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  96. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  97. package/docs/api/interfaces/EventLogoProps.md +1 -1
  98. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  99. package/docs/api/interfaces/FileMetadata.md +1 -1
  100. package/docs/api/interfaces/FileReference.md +1 -1
  101. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  102. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  103. package/docs/api/interfaces/FileUploadProps.md +1 -1
  104. package/docs/api/interfaces/FooterProps.md +1 -1
  105. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  106. package/docs/api/interfaces/InputProps.md +1 -1
  107. package/docs/api/interfaces/LabelProps.md +1 -1
  108. package/docs/api/interfaces/LoginFormProps.md +1 -1
  109. package/docs/api/interfaces/NavigationAccessRecord.md +11 -11
  110. package/docs/api/interfaces/NavigationContextType.md +9 -9
  111. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  112. package/docs/api/interfaces/NavigationItem.md +1 -1
  113. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  114. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  115. package/docs/api/interfaces/Organisation.md +1 -1
  116. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  117. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  118. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  119. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  120. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  121. package/docs/api/interfaces/PaceLoginPageProps.md +16 -3
  122. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  123. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  124. package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
  125. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  126. package/docs/api/interfaces/PaletteData.md +1 -1
  127. package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
  128. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  129. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  130. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  131. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  132. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  133. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  134. package/docs/api/interfaces/RBACConfig.md +1 -1
  135. package/docs/api/interfaces/RBACLogger.md +1 -1
  136. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  137. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  138. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  139. package/docs/api/interfaces/RouteConfig.md +2 -2
  140. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  141. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  142. package/docs/api/interfaces/StorageConfig.md +1 -1
  143. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  144. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  145. package/docs/api/interfaces/StorageListOptions.md +1 -1
  146. package/docs/api/interfaces/StorageListResult.md +1 -1
  147. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  148. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  149. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  150. package/docs/api/interfaces/StyleImport.md +1 -1
  151. package/docs/api/interfaces/SwitchProps.md +1 -1
  152. package/docs/api/interfaces/ToastActionElement.md +1 -1
  153. package/docs/api/interfaces/ToastProps.md +1 -1
  154. package/docs/api/interfaces/UnifiedAuthContextType.md +94 -521
  155. package/docs/api/interfaces/UnifiedAuthProviderProps.md +16 -16
  156. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  157. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  158. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  159. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  160. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  161. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  162. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  163. package/docs/api/interfaces/UseResolvedScopeOptions.md +47 -0
  164. package/docs/api/interfaces/UseResolvedScopeReturn.md +47 -0
  165. package/docs/api/interfaces/UserEventAccess.md +11 -11
  166. package/docs/api/interfaces/UserMenuProps.md +1 -1
  167. package/docs/api/interfaces/UserProfile.md +1 -1
  168. package/docs/api/modules.md +303 -275
  169. package/docs/api-reference/components.md +193 -0
  170. package/docs/api-reference/hooks.md +265 -0
  171. package/docs/api-reference/providers.md +32 -7
  172. package/docs/api-reference/types.md +6 -0
  173. package/docs/api-reference/utilities.md +207 -0
  174. package/docs/architecture/README.md +6 -0
  175. package/docs/{database-schema-requirements.md → architecture/database-schema-requirements.md} +6 -0
  176. package/docs/architecture/rbac-security-architecture.md +258 -0
  177. package/docs/architecture/services.md +9 -1
  178. package/docs/best-practices/README.md +26 -0
  179. package/docs/best-practices/accessibility.md +572 -0
  180. package/docs/{common-patterns.md → best-practices/common-patterns.md} +6 -0
  181. package/docs/best-practices/deployment.md +6 -0
  182. package/docs/best-practices/performance.md +475 -2
  183. package/docs/best-practices/security.md +6 -0
  184. package/docs/best-practices/testing.md +6 -0
  185. package/docs/core-concepts/authentication.md +21 -7
  186. package/docs/core-concepts/events.md +6 -0
  187. package/docs/core-concepts/organisations.md +6 -0
  188. package/docs/core-concepts/permissions.md +6 -0
  189. package/docs/core-concepts/rbac-system.md +6 -0
  190. package/docs/documentation-index.md +121 -182
  191. package/docs/{consuming-app-vite-config.md → getting-started/consuming-app-vite-config.md} +6 -0
  192. package/docs/getting-started/documentation-index.md +40 -0
  193. package/docs/getting-started/examples/README.md +878 -35
  194. package/docs/{faq.md → getting-started/faq.md} +7 -1
  195. package/docs/getting-started/installation-guide.md +6 -0
  196. package/docs/{quick-reference.md → getting-started/quick-reference.md} +6 -0
  197. package/docs/implementation-guides/app-layout.md +6 -0
  198. package/docs/implementation-guides/authentication.md +1021 -0
  199. package/docs/implementation-guides/component-styling.md +416 -0
  200. package/docs/implementation-guides/data-tables.md +1264 -2076
  201. package/docs/implementation-guides/dynamic-colors.md +6 -0
  202. package/docs/implementation-guides/event-theming-summary.md +6 -0
  203. package/docs/{file-reference-system.md → implementation-guides/file-reference-system.md} +6 -0
  204. package/docs/implementation-guides/file-upload-storage.md +6 -0
  205. package/docs/implementation-guides/forms.md +6 -0
  206. package/docs/implementation-guides/inactivity-tracking.md +6 -0
  207. package/docs/implementation-guides/navigation.md +6 -0
  208. package/docs/implementation-guides/organisation-security.md +6 -0
  209. package/docs/implementation-guides/permission-enforcement.md +6 -0
  210. package/docs/implementation-guides/public-pages-advanced.md +6 -0
  211. package/docs/implementation-guides/public-pages.md +6 -0
  212. package/docs/migration/MIGRATION_GUIDE.md +827 -351
  213. package/docs/migration/README.md +7 -1
  214. package/docs/migration/organisation-context-timing-fix.md +6 -0
  215. package/docs/migration/rbac-migration.md +44 -1
  216. package/docs/migration/service-architecture.md +6 -0
  217. package/docs/migration/v0.4.15-tailwind-scanning.md +6 -0
  218. package/docs/migration/v0.4.16-css-first-approach.md +6 -0
  219. package/docs/migration/v0.4.17-source-path-fix.md +6 -0
  220. package/docs/rbac/README-rbac-rls-integration.md +6 -0
  221. package/docs/rbac/README.md +6 -0
  222. package/docs/rbac/advanced-patterns.md +6 -0
  223. package/docs/rbac/api-reference.md +7 -1
  224. package/docs/rbac/breaking-changes-v3.md +222 -0
  225. package/docs/rbac/examples/rbac-rls-integration-example.md +6 -0
  226. package/docs/rbac/examples.md +6 -0
  227. package/docs/rbac/getting-started.md +6 -0
  228. package/docs/rbac/migration-guide.md +260 -0
  229. package/docs/rbac/quick-start.md +6 -0
  230. package/docs/rbac/rbac-rls-integration.md +6 -0
  231. package/docs/rbac/super-admin-guide.md +6 -0
  232. package/docs/rbac/troubleshooting.md +6 -0
  233. package/docs/security/README.md +6 -0
  234. package/docs/security/checklist.md +6 -0
  235. package/docs/styles/README.md +7 -1
  236. package/docs/{usage.md → styles/usage.md} +6 -0
  237. package/docs/testing/README.md +6 -0
  238. package/docs/{visual-testing.md → testing/visual-testing.md} +6 -0
  239. package/docs/troubleshooting/README.md +387 -5
  240. package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +6 -0
  241. package/docs/troubleshooting/common-issues.md +6 -0
  242. package/docs/troubleshooting/database-view-compatibility.md +6 -0
  243. package/docs/troubleshooting/organisation-context-setup.md +6 -0
  244. package/docs/troubleshooting/react-hooks-issue-analysis.md +6 -0
  245. package/docs/troubleshooting/styling-issues.md +6 -0
  246. package/docs/troubleshooting/tailwind-content-scanning.md +6 -0
  247. package/package.json +1 -1
  248. package/src/__tests__/TEST_GUIDE_CURSOR.md +290 -0
  249. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -1
  250. package/src/__tests__/helpers/supabaseMock.ts +48 -2
  251. package/src/__tests__/helpers/test-providers.tsx +3 -53
  252. package/src/components/DataTable/DataTable.test.tsx +319 -0
  253. package/src/components/DataTable/DataTable.tsx +32 -11
  254. package/src/components/DataTable/__tests__/{DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx.skip} +6 -4
  255. package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +17 -6
  256. package/src/components/DataTable/__tests__/{DataTable.test.tsx → DataTable.test.tsx.skip} +6 -4
  257. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +96 -10
  258. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +601 -0
  259. package/src/components/DataTable/__tests__/keyboard.test.tsx +615 -0
  260. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +639 -0
  261. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx.skip +330 -0
  262. package/src/components/DataTable/components/AccessDeniedPage.tsx +2 -2
  263. package/src/components/DataTable/components/ActionButtons.tsx +88 -104
  264. package/src/components/DataTable/components/DataTableCore.tsx +442 -665
  265. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +4 -2
  266. package/src/components/DataTable/components/DataTableModals.tsx +22 -1
  267. package/src/components/DataTable/components/EditableRow.tsx +69 -84
  268. package/src/components/DataTable/components/EmptyState.tsx +5 -1
  269. package/src/components/DataTable/components/ImportModal.tsx +65 -36
  270. package/src/components/DataTable/components/PaginationControls.tsx +40 -100
  271. package/src/components/DataTable/components/UnifiedTableBody.tsx +222 -278
  272. package/src/components/DataTable/components/index.ts +1 -2
  273. package/src/components/DataTable/context/DataTableContext.tsx +1 -1
  274. package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +208 -275
  275. package/src/components/DataTable/core/ColumnFactory.ts +5 -0
  276. package/src/components/DataTable/core/index.ts +1 -8
  277. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +12 -10
  278. package/src/components/DataTable/examples/HierarchicalExample.tsx +1 -1
  279. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +1 -0
  280. package/src/components/DataTable/examples/PerformanceExample.tsx +1 -0
  281. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +521 -0
  282. package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +570 -0
  283. package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +167 -0
  284. package/src/components/DataTable/hooks/__tests__/useHierarchicalState.test.ts +214 -0
  285. package/src/components/DataTable/hooks/__tests__/useTableColumns.test.ts +224 -0
  286. package/src/components/DataTable/hooks/index.ts +13 -0
  287. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +32 -15
  288. package/src/components/DataTable/hooks/useColumnReordering.ts +1 -0
  289. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +102 -0
  290. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +89 -0
  291. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +117 -0
  292. package/src/components/DataTable/hooks/useDataTablePermissions.ts +193 -0
  293. package/src/components/DataTable/hooks/useDataTableState.ts +51 -17
  294. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +33 -0
  295. package/src/components/DataTable/hooks/useHierarchicalState.ts +41 -9
  296. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +447 -0
  297. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +94 -0
  298. package/src/components/DataTable/hooks/useTableColumns.ts +156 -0
  299. package/src/components/DataTable/hooks/useTableHandlers.ts +174 -0
  300. package/src/components/DataTable/index.ts +13 -12
  301. package/src/components/DataTable/types.ts +129 -9
  302. package/src/components/DataTable/utils/__tests__/COVERAGE_NOTE.md +89 -0
  303. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +162 -28
  304. package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +573 -0
  305. package/src/components/DataTable/utils/__tests__/hierarchicalSorting.test.ts +247 -0
  306. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +8 -6
  307. package/src/components/DataTable/utils/__tests__/performanceUtils.test.ts +466 -0
  308. package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +251 -0
  309. package/src/components/DataTable/utils/a11yUtils.ts +244 -0
  310. package/src/components/DataTable/utils/debugTools.ts +47 -21
  311. package/src/components/DataTable/utils/errorHandling.ts +52 -460
  312. package/src/components/DataTable/utils/exportUtils.ts +157 -28
  313. package/src/components/DataTable/utils/flexibleImport.ts +202 -32
  314. package/src/components/DataTable/utils/hierarchicalSorting.ts +50 -3
  315. package/src/components/DataTable/utils/hierarchicalUtils.ts +167 -34
  316. package/src/components/DataTable/utils/index.ts +7 -0
  317. package/src/components/DataTable/utils/paginationUtils.ts +350 -0
  318. package/src/components/DataTable/utils/rowUtils.ts +69 -0
  319. package/src/components/EventSelector/EventSelector.test.tsx +672 -0
  320. package/src/components/Label/__tests__/Label.test.tsx +434 -0
  321. package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -24
  322. package/src/components/NavigationMenu/NavigationMenu.tsx +19 -8
  323. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +1 -23
  324. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +56 -6
  325. package/src/components/PaceLoginPage/PaceLoginPage.tsx +137 -13
  326. package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +190 -0
  327. package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +185 -0
  328. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +1 -1
  329. package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +313 -0
  330. package/src/components/Select/Select.test.tsx +143 -120
  331. package/src/components/Select/Select.tsx +48 -212
  332. package/src/components/Select/hooks.ts +36 -1
  333. package/src/components/Select/index.ts +2 -1
  334. package/src/components/examples/PermissionExample.tsx +173 -0
  335. package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
  336. package/src/examples/PublicEventPage.tsx +274 -0
  337. package/src/examples/PublicPageApp.tsx +308 -0
  338. package/src/examples/PublicPageUsageExample.tsx +216 -0
  339. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +12 -1
  340. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +129 -17
  341. package/src/hooks/__tests__/useRBAC.unit.test.ts +151 -846
  342. package/src/hooks/useOrganisationPermissions.test.ts +42 -18
  343. package/src/hooks/useOrganisationPermissions.ts +12 -6
  344. package/src/hooks/useOrganisationSecurity.test.ts +138 -85
  345. package/src/hooks/useOrganisationSecurity.ts +41 -10
  346. package/src/hooks/useSecureDataAccess.test.ts +32 -29
  347. package/src/index.ts +0 -1
  348. package/src/providers/AuthProvider.simplified.tsx +880 -0
  349. package/src/providers/UnifiedAuthProvider.test.simple.tsx +8 -8
  350. package/src/providers/__tests__/ProviderLifecycle.test.tsx +341 -0
  351. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +29 -19
  352. package/src/providers/index.ts +0 -1
  353. package/src/providers/services/EventServiceProvider.tsx +19 -15
  354. package/src/providers/services/InactivityServiceProvider.tsx +19 -15
  355. package/src/providers/services/OrganisationServiceProvider.tsx +19 -15
  356. package/src/providers/services/UnifiedAuthProvider.tsx +156 -127
  357. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +1 -1
  358. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -3
  359. package/src/rbac/README.md +1 -1
  360. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +25 -27
  361. package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +313 -0
  362. package/src/rbac/__tests__/engine.comprehensive.test.ts +114 -348
  363. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +28 -110
  364. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +33 -85
  365. package/src/rbac/__tests__/scenarios.user-role.test.tsx +2 -2
  366. package/src/rbac/adapters.tsx +26 -69
  367. package/src/rbac/api.test.ts +90 -27
  368. package/src/rbac/api.ts +61 -10
  369. package/src/rbac/audit.test.ts +33 -38
  370. package/src/rbac/audit.ts +21 -6
  371. package/src/rbac/cache.ts +33 -1
  372. package/src/rbac/components/NavigationGuard.tsx +11 -11
  373. package/src/rbac/components/NavigationProvider.test.tsx +11 -5
  374. package/src/rbac/components/NavigationProvider.tsx +37 -13
  375. package/src/rbac/components/PagePermissionGuard.tsx +111 -50
  376. package/src/rbac/components/PagePermissionProvider.tsx +5 -5
  377. package/src/rbac/components/PermissionEnforcer.tsx +11 -11
  378. package/src/rbac/components/RoleBasedRouter.tsx +5 -5
  379. package/src/rbac/components/SecureDataProvider.tsx +5 -5
  380. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +8 -8
  381. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +14 -14
  382. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +12 -12
  383. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +6 -6
  384. package/src/rbac/engine.test.simple.ts +19 -13
  385. package/src/rbac/engine.test.ts +1 -0
  386. package/src/rbac/engine.ts +330 -766
  387. package/src/rbac/errors.ts +156 -0
  388. package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +437 -0
  389. package/src/rbac/hooks/index.ts +2 -0
  390. package/src/rbac/hooks/usePermissions.ts +32 -10
  391. package/src/rbac/hooks/useRBAC.test.ts +126 -512
  392. package/src/rbac/hooks/useRBAC.ts +147 -193
  393. package/src/rbac/hooks/useResolvedScope.ts +244 -0
  394. package/src/rbac/index.ts +7 -4
  395. package/src/rbac/security.ts +109 -18
  396. package/src/rbac/types.ts +12 -1
  397. package/src/services/AuthService.ts +2 -15
  398. package/src/services/EventService.ts +26 -46
  399. package/src/services/OrganisationService.ts +51 -31
  400. package/src/services/__tests__/AuthService.test.ts +1 -1
  401. package/src/services/__tests__/EventService.test.ts +1 -1
  402. package/src/services/__tests__/InactivityService.lifecycle.test.ts +411 -0
  403. package/src/services/__tests__/OrganisationService.pagination.test.ts +375 -0
  404. package/src/services/__tests__/OrganisationService.test.ts +1 -1
  405. package/src/styles/base.css +208 -0
  406. package/src/styles/semantic.css +24 -0
  407. package/src/types/__tests__/README.md +114 -0
  408. package/src/types/__tests__/validation.test.ts +731 -0
  409. package/src/types/database.generated.ts +7347 -0
  410. package/src/types/database.ts +20 -0
  411. package/src/utils/__tests__/file-reference.test.ts +383 -0
  412. package/src/utils/__tests__/performanceBenchmark.test.ts +175 -0
  413. package/src/utils/appNameResolver.test.ts +54 -0
  414. package/src/utils/logger.ts +179 -0
  415. package/src/utils/organisationContext.ts +11 -4
  416. package/src/utils/storage/__tests__/helpers.unit.test.ts +6 -2
  417. package/src/validation/__tests__/csrf.unit.test.ts +63 -0
  418. package/src/validation/__tests__/passwordSchema.unit.test.ts +105 -0
  419. package/dist/DataTable-HWZQGASI.js +0 -102
  420. package/dist/appNameResolver-UURKN7NF.js +0 -22
  421. package/dist/audit-6TOCAMKO.js.map +0 -1
  422. package/dist/chunk-2CHATWBF.js +0 -523
  423. package/dist/chunk-2CHATWBF.js.map +0 -1
  424. package/dist/chunk-2DFZ432F.js.map +0 -1
  425. package/dist/chunk-33PHABLB.js.map +0 -1
  426. package/dist/chunk-B2WTCLCV.js.map +0 -1
  427. package/dist/chunk-CY3AHGO4.js.map +0 -1
  428. package/dist/chunk-DAXLNIDY.js.map +0 -1
  429. package/dist/chunk-FGMFQSHX.js.map +0 -1
  430. package/dist/chunk-TYHR5X4W.js +0 -33
  431. package/dist/chunk-TYHR5X4W.js.map +0 -1
  432. package/dist/chunk-ULBI5JGB.js +0 -109
  433. package/dist/chunk-ULBI5JGB.js.map +0 -1
  434. package/dist/chunk-WN6XJWOS.js.map +0 -1
  435. package/dist/chunk-XLZ7U46Z.js.map +0 -1
  436. package/dist/chunk-YNUBMSMV.js.map +0 -1
  437. package/dist/chunk-ZTT2AXMX.js.map +0 -1
  438. package/dist/eventContext-BBA42P6G.js +0 -14
  439. package/dist/eventContext-BBA42P6G.js.map +0 -1
  440. package/docs/DOCUMENTATION_CHECKLIST.md +0 -281
  441. package/docs/api/interfaces/RBACContextType.md +0 -468
  442. package/docs/api/interfaces/RBACProviderProps.md +0 -107
  443. package/docs/breaking-changes.md +0 -179
  444. package/docs/consuming-app-example.md +0 -290
  445. package/docs/documentation-style-checklist.md +0 -294
  446. package/docs/examples/navigation-menu-auth-fix.md +0 -344
  447. package/docs/getting-started/examples/basic-auth-app.md +0 -520
  448. package/docs/getting-started/examples/full-featured-app.md +0 -616
  449. package/docs/getting-started/quick-start.md +0 -426
  450. package/docs/implementation-guides/datatable-filtering.md +0 -313
  451. package/docs/implementation-guides/datatable-rbac-usage.md +0 -317
  452. package/docs/implementation-guides/hierarchical-datatable.md +0 -850
  453. package/docs/implementation-guides/large-datasets.md +0 -281
  454. package/docs/implementation-guides/performance.md +0 -403
  455. package/docs/migration/quick-migration-guide.md +0 -320
  456. package/docs/migration-guide.md +0 -193
  457. package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +0 -226
  458. package/docs/performance/README.md +0 -551
  459. package/docs/style-guide.md +0 -925
  460. package/docs/troubleshooting/authentication-issues.md +0 -334
  461. package/docs/troubleshooting/debugging.md +0 -1117
  462. package/docs/troubleshooting/migration.md +0 -918
  463. package/src/__tests__/hooks/usePermissions.test.ts +0 -261
  464. package/src/components/DataTable/components/DataTableBody.tsx +0 -488
  465. package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -144
  466. package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -515
  467. package/src/components/DataTable/core/ActionManager.ts +0 -235
  468. package/src/components/DataTable/core/ColumnManager.ts +0 -215
  469. package/src/components/DataTable/core/DataManager.ts +0 -188
  470. package/src/components/DataTable/core/DataTableContext.tsx +0 -181
  471. package/src/components/DataTable/core/LocalDataAdapter.ts +0 -264
  472. package/src/components/DataTable/core/PluginRegistry.ts +0 -229
  473. package/src/components/DataTable/core/StateManager.ts +0 -311
  474. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -634
  475. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +0 -193
  476. package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -519
  477. package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -714
  478. package/src/components/DataTable/core/interfaces.ts +0 -338
  479. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +0 -574
  480. package/src/components/Select/Select.bug-test.tsx +0 -69
  481. package/src/components/Select/Select.refactored.tsx +0 -497
  482. package/src/hooks/__tests__/ServiceHooks.test.tsx +0 -613
  483. package/src/hooks/services/usePermissions.ts +0 -70
  484. package/src/hooks/services/useRBACService.ts +0 -30
  485. package/src/hooks/usePermissionCheck.ts +0 -150
  486. package/src/providers/__tests__/ServiceProviders.test.tsx +0 -477
  487. package/src/providers/services/RBACServiceProvider.tsx +0 -79
  488. package/src/rbac/__tests__/integration.authflow.test.tsx +0 -119
  489. package/src/rbac/__tests__/integration.navigation.test.tsx +0 -69
  490. package/src/rbac/__tests__/integration.securedata.test.tsx +0 -92
  491. package/src/rbac/__tests__/integration.smoke.test.tsx +0 -73
  492. package/src/rbac/providers/RBACProvider.tsx +0 -645
  493. package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +0 -688
  494. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +0 -1186
  495. package/src/rbac/providers/index.ts +0 -11
  496. package/src/services/RBACService.ts +0 -522
  497. package/src/services/__tests__/RBACService.test.ts +0 -492
  498. package/src/services/interfaces/IRBACService.ts +0 -62
  499. package/src/utils/appNameResolver.test 2.ts +0 -494
  500. /package/dist/{DataTable-HWZQGASI.js.map → DataTable-QCNCV6IK.js.map} +0 -0
  501. /package/dist/{UnifiedAuthProvider-3NKDOSOK.js.map → UnifiedAuthProvider-Z2FWNW7O.js.map} +0 -0
  502. /package/dist/{api-DDMUKIUD.js.map → api-KG4A2X7P.js.map} +0 -0
  503. /package/dist/{appNameResolver-UURKN7NF.js.map → audit-65VNHEV2.js.map} +0 -0
  504. /package/dist/{chunk-LW7MMEAQ.js.map → chunk-CRKP3HXI.js.map} +0 -0
  505. /package/dist/{chunk-URUTVZ7N.js.map → chunk-DVHZ5L55.js.map} +0 -0
  506. /package/dist/{chunk-NTNILOBC.js.map → chunk-TLD5BEU6.js.map} +0 -0
  507. /package/docs/{app.css.example → styles/app.css.example} +0 -0
@@ -0,0 +1,308 @@
1
+ /**
2
+ * @file Public Page App Example
3
+ * @package @jmruthers/pace-core
4
+ * @module Examples/PublicPages
5
+ * @since 1.0.0
6
+ *
7
+ * A complete example showing how to properly implement public pages
8
+ * that are completely isolated from the authentication context.
9
+ *
10
+ * This example demonstrates the correct architecture for public pages:
11
+ * 1. Separate routing structure outside authentication context
12
+ * 2. PublicPageProvider for environment variables
13
+ * 3. No authentication context initialization
14
+ * 4. Proper error handling and loading states
15
+ *
16
+ * @example
17
+ * ```tsx
18
+ * import { PublicPageApp } from '@jmruthers/pace-core/examples';
19
+ *
20
+ * // In your main App.tsx, use this for public routes
21
+ * function App() {
22
+ * return (
23
+ * <BrowserRouter>
24
+ * <Routes>
25
+ * <Route path="/public/*" element={<PublicPageApp />} />
26
+ * <Route path="/*" element={<AuthenticatedApp />} />
27
+ * </Routes>
28
+ * </BrowserRouter>
29
+ * );
30
+ * }
31
+ * ```
32
+ */
33
+
34
+ import React from 'react';
35
+ import { Routes, Route } from 'react-router-dom';
36
+ import {
37
+ PublicPageProvider,
38
+ PublicPageLayout,
39
+ PublicPageHeader,
40
+ PublicPageFooter,
41
+ EventLogo,
42
+ usePublicEvent,
43
+ usePublicRouteParams,
44
+ PublicLoadingSpinner,
45
+ PublicErrorBoundary
46
+ } from '../index';
47
+
48
+ /**
49
+ * Complete public page application that works independently
50
+ * of the main application's authentication context.
51
+ *
52
+ * This component should be used for all public routes that don't
53
+ * require authentication, such as:
54
+ * - Event pages: /events/:eventCode/recipe-grid-report
55
+ * - Public reports: /reports/:reportId
56
+ * - Public information: /info/:pageId
57
+ */
58
+ export function PublicPageApp() {
59
+ return (
60
+ <PublicPageProvider>
61
+ <Routes>
62
+ {/* Public event pages */}
63
+ <Route path="/events/:eventCode/recipe-grid-report" element={<PublicRecipeGridReportPage />} />
64
+ <Route path="/events/:eventCode" element={<PublicEventPage />} />
65
+
66
+ {/* Add more public routes as needed */}
67
+ <Route path="/info/:pageId" element={<PublicInfoPage />} />
68
+ <Route path="/reports/:reportId" element={<PublicReportPage />} />
69
+ </Routes>
70
+ </PublicPageProvider>
71
+ );
72
+ }
73
+
74
+ /**
75
+ * Public recipe grid report page
76
+ *
77
+ * This is the specific page mentioned in the bug report.
78
+ * It demonstrates the correct usage pattern for public pages.
79
+ */
80
+ function PublicRecipeGridReportPage() {
81
+ // Step 1: Extract event code from URL (no auth context triggered)
82
+ const { eventCode } = usePublicRouteParams({ fetchEventData: false });
83
+
84
+ // Step 2: Fetch event data using the event code
85
+ const { event, isLoading, error, refetch } = usePublicEvent(eventCode || '');
86
+
87
+ // Step 3: Handle loading state
88
+ if (isLoading) {
89
+ return (
90
+ <PublicLoadingSpinner
91
+ message="Loading recipe grid report..."
92
+ />
93
+ );
94
+ }
95
+
96
+ // Step 4: Handle error state
97
+ if (error) {
98
+ return (
99
+ <div className="min-h-screen bg-white flex items-center justify-center">
100
+ <div className="max-w-md mx-auto text-center px-4">
101
+ <div className="mb-6">
102
+ <div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4">
103
+ <svg className="h-6 w-6 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
104
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
105
+ </svg>
106
+ </div>
107
+ <h1 className="text-2xl font-bold text-gray-900 mb-2">
108
+ Recipe Grid Report Not Found
109
+ </h1>
110
+ <p className="text-gray-600 mb-6">
111
+ The event code "{eventCode}" is invalid or the recipe grid report is not available for public viewing.
112
+ </p>
113
+ <button
114
+ onClick={refetch}
115
+ className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
116
+ >
117
+ Try Again
118
+ </button>
119
+ </div>
120
+ </div>
121
+ </div>
122
+ );
123
+ }
124
+
125
+ // Step 5: Handle missing event
126
+ if (!event) {
127
+ return (
128
+ <div className="min-h-screen bg-white flex items-center justify-center">
129
+ <div className="max-w-md mx-auto text-center px-4">
130
+ <h1 className="text-2xl font-bold text-gray-900 mb-4">
131
+ Recipe Grid Report Not Available
132
+ </h1>
133
+ <p className="text-gray-600 mb-6">
134
+ This recipe grid report is not available for public viewing.
135
+ </p>
136
+ <button
137
+ onClick={refetch}
138
+ className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
139
+ >
140
+ Try Again
141
+ </button>
142
+ </div>
143
+ </div>
144
+ );
145
+ }
146
+
147
+ // Step 6: Render the public page with event data
148
+ return (
149
+ <PublicPageLayout eventCode={eventCode || ''} event={event}>
150
+ <PublicPageHeader
151
+ event={event}
152
+ eventCode={eventCode || ''}
153
+ title="Recipe Grid Report"
154
+ description="Public recipe grid report for this event"
155
+ />
156
+
157
+ <main className="max-w-6xl mx-auto px-4 py-8">
158
+ {/* Recipe Grid Report Content */}
159
+ <div className="mb-12">
160
+ <div className="bg-green-50 border border-green-200 rounded-lg p-6">
161
+ <h3 className="font-semibold text-green-900 mb-2">Recipe Grid Report</h3>
162
+ <p className="text-green-800">
163
+ This is where your recipe grid report content would go.
164
+ The public page is now working correctly without authentication context conflicts.
165
+ </p>
166
+ <div className="mt-4 text-sm text-green-700">
167
+ <p><strong>Event Code:</strong> {eventCode}</p>
168
+ <p><strong>Event ID:</strong> {event.event_id}</p>
169
+ <p><strong>Event Name:</strong> {event.event_name}</p>
170
+ </div>
171
+ </div>
172
+ </div>
173
+
174
+ {/* Event Information */}
175
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12">
176
+ <div className="lg:col-span-2 space-y-6">
177
+ <div>
178
+ <h2 className="text-2xl font-bold text-gray-900 mb-4">Event Information</h2>
179
+ <div className="bg-gray-50 rounded-lg p-6 space-y-4">
180
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
181
+ <div>
182
+ <h3 className="font-semibold text-gray-700">Date</h3>
183
+ <p className="text-gray-900">
184
+ {event.event_date ? new Date(event.event_date).toLocaleDateString('en-AU', {
185
+ weekday: 'long',
186
+ year: 'numeric',
187
+ month: 'long',
188
+ day: 'numeric'
189
+ }) : 'TBA'}
190
+ </p>
191
+ </div>
192
+ <div>
193
+ <h3 className="font-semibold text-gray-700">Venue</h3>
194
+ <p className="text-gray-900">{event.event_venue || 'TBA'}</p>
195
+ </div>
196
+ <div>
197
+ <h3 className="font-semibold text-gray-700">Participants</h3>
198
+ <p className="text-gray-900">{event.event_participants || 'TBA'}</p>
199
+ </div>
200
+ <div>
201
+ <h3 className="font-semibold text-gray-700">Event Code</h3>
202
+ <p className="text-gray-900 font-mono">{event.event_code}</p>
203
+ </div>
204
+ </div>
205
+ </div>
206
+ </div>
207
+ </div>
208
+
209
+ {/* Event Logo */}
210
+ <div className="flex justify-center lg:justify-start">
211
+ <div className="text-center">
212
+ <EventLogo
213
+ eventId={event.event_id}
214
+ eventName={event.event_name}
215
+ organisationId={event.organisation_id}
216
+ size="2xl"
217
+ className="rounded-lg shadow-lg"
218
+ />
219
+ <p className="mt-4 text-sm text-gray-600">Event Logo</p>
220
+ </div>
221
+ </div>
222
+ </div>
223
+ </main>
224
+
225
+ <PublicPageFooter event={event} />
226
+ </PublicPageLayout>
227
+ );
228
+ }
229
+
230
+ /**
231
+ * Generic public event page
232
+ */
233
+ function PublicEventPage() {
234
+ const { eventCode } = usePublicRouteParams({ fetchEventData: false });
235
+ const { event, isLoading, error, refetch } = usePublicEvent(eventCode || '');
236
+
237
+ if (isLoading) return <PublicLoadingSpinner message="Loading event..." />;
238
+ if (error || !event) return <div>Event not found</div>;
239
+
240
+ return (
241
+ <PublicPageLayout eventCode={eventCode || ''} event={event}>
242
+ <PublicPageHeader
243
+ event={event}
244
+ eventCode={eventCode || ''}
245
+ title="Event Details"
246
+ description="Public information about this event"
247
+ />
248
+
249
+ <main className="max-w-4xl mx-auto px-4 py-6">
250
+ <div className="text-center mb-6">
251
+ <EventLogo
252
+ eventId={event.event_id}
253
+ eventName={event.event_name}
254
+ organisationId={event.organisation_id}
255
+ size="xl"
256
+ className="mx-auto mb-4"
257
+ />
258
+ <h1 className="text-2xl font-bold text-gray-900">{event.event_name}</h1>
259
+ {event.event_date && (
260
+ <p className="text-gray-600 mt-2">
261
+ {new Date(event.event_date).toLocaleDateString('en-AU')}
262
+ </p>
263
+ )}
264
+ </div>
265
+ </main>
266
+
267
+ <PublicPageFooter event={event} />
268
+ </PublicPageLayout>
269
+ );
270
+ }
271
+
272
+ /**
273
+ * Generic public info page
274
+ */
275
+ function PublicInfoPage() {
276
+ return (
277
+ <div className="min-h-screen bg-white flex items-center justify-center">
278
+ <div className="max-w-md mx-auto text-center px-4">
279
+ <h1 className="text-2xl font-bold text-gray-900 mb-4">
280
+ Public Information Page
281
+ </h1>
282
+ <p className="text-gray-600">
283
+ This is a public information page that doesn't require authentication.
284
+ </p>
285
+ </div>
286
+ </div>
287
+ );
288
+ }
289
+
290
+ /**
291
+ * Generic public report page
292
+ */
293
+ function PublicReportPage() {
294
+ return (
295
+ <div className="min-h-screen bg-white flex items-center justify-center">
296
+ <div className="max-w-md mx-auto text-center px-4">
297
+ <h1 className="text-2xl font-bold text-gray-900 mb-4">
298
+ Public Report Page
299
+ </h1>
300
+ <p className="text-gray-600">
301
+ This is a public report page that doesn't require authentication.
302
+ </p>
303
+ </div>
304
+ </div>
305
+ );
306
+ }
307
+
308
+ export default PublicPageApp;
@@ -0,0 +1,216 @@
1
+ /**
2
+ * @file Public Page Usage Example
3
+ * @package @jmruthers/pace-core
4
+ * @module Examples/PublicPages
5
+ * @since 1.0.0
6
+ *
7
+ * A complete example showing the correct usage pattern for public pages.
8
+ * This example demonstrates how to properly implement public pages without
9
+ * authentication context conflicts.
10
+ *
11
+ * @example
12
+ * ```tsx
13
+ * import { PublicPageUsageExample } from '@jmruthers/pace-core/examples';
14
+ *
15
+ * function App() {
16
+ * return (
17
+ * <BrowserRouter>
18
+ * <Routes>
19
+ * <Route path="/events/:eventCode/recipe-grid-report" element={<PublicPageUsageExample />} />
20
+ * </Routes>
21
+ * </BrowserRouter>
22
+ * );
23
+ * }
24
+ * ```
25
+ */
26
+
27
+ import React from 'react';
28
+ import {
29
+ PublicPageLayout,
30
+ PublicPageHeader,
31
+ PublicPageFooter,
32
+ EventLogo,
33
+ usePublicEvent,
34
+ usePublicRouteParams,
35
+ PublicLoadingSpinner,
36
+ PublicErrorBoundary
37
+ } from '../index';
38
+
39
+ /**
40
+ * Correct usage pattern for public pages
41
+ *
42
+ * This component demonstrates the proper way to implement public pages:
43
+ * 1. Use usePublicRouteParams to get the eventCode from URL
44
+ * 2. Use usePublicEvent to fetch event data
45
+ * 3. Pass event data to PublicPageLayout
46
+ * 4. No authentication context is triggered
47
+ */
48
+ export function PublicPageUsageExample() {
49
+ // Step 1: Extract event code from URL parameters
50
+ const { eventCode } = usePublicRouteParams({ fetchEventData: false });
51
+
52
+ // Step 2: Fetch event data using the event code
53
+ const { event, isLoading, error, refetch } = usePublicEvent(eventCode || '');
54
+
55
+ // Step 3: Handle loading state
56
+ if (isLoading) {
57
+ return (
58
+ <PublicLoadingSpinner
59
+ message="Loading event details..."
60
+ />
61
+ );
62
+ }
63
+
64
+ // Step 4: Handle error state
65
+ if (error) {
66
+ return (
67
+ <div className="min-h-screen bg-white flex items-center justify-center">
68
+ <div className="max-w-md mx-auto text-center px-4">
69
+ <div className="mb-6">
70
+ <div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4">
71
+ <svg className="h-6 w-6 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
72
+ <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
73
+ </svg>
74
+ </div>
75
+ <h1 className="text-2xl font-bold text-gray-900 mb-2">
76
+ Event Not Found
77
+ </h1>
78
+ <p className="text-gray-600 mb-6">
79
+ The event code "{eventCode}" is invalid or the event is not available for public viewing.
80
+ </p>
81
+ <button
82
+ onClick={refetch}
83
+ className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
84
+ >
85
+ Try Again
86
+ </button>
87
+ </div>
88
+ </div>
89
+ </div>
90
+ );
91
+ }
92
+
93
+ // Step 5: Handle missing event
94
+ if (!event) {
95
+ return (
96
+ <div className="min-h-screen bg-white flex items-center justify-center">
97
+ <div className="max-w-md mx-auto text-center px-4">
98
+ <h1 className="text-2xl font-bold text-gray-900 mb-4">
99
+ Event Not Available
100
+ </h1>
101
+ <p className="text-gray-600 mb-6">
102
+ This event is not available for public viewing.
103
+ </p>
104
+ <button
105
+ onClick={refetch}
106
+ className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
107
+ >
108
+ Try Again
109
+ </button>
110
+ </div>
111
+ </div>
112
+ );
113
+ }
114
+
115
+ // Step 6: Render the public page with event data
116
+ return (
117
+ <PublicErrorBoundary>
118
+ <PublicPageLayout eventCode={eventCode || ''} event={event}>
119
+ <PublicPageHeader
120
+ event={event}
121
+ eventCode={eventCode || ''}
122
+ title="Recipe Grid Report"
123
+ description="Public recipe grid report for this event"
124
+ />
125
+
126
+ <main className="max-w-6xl mx-auto px-4 py-8">
127
+ {/* Event Overview */}
128
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12">
129
+ {/* Event Information */}
130
+ <div className="lg:col-span-2 space-y-6">
131
+ <div>
132
+ <h2 className="text-2xl font-bold text-gray-900 mb-4">Event Information</h2>
133
+ <div className="bg-gray-50 rounded-lg p-6 space-y-4">
134
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
135
+ <div>
136
+ <h3 className="font-semibold text-gray-700">Date</h3>
137
+ <p className="text-gray-900">
138
+ {event.event_date ? new Date(event.event_date).toLocaleDateString('en-AU', {
139
+ weekday: 'long',
140
+ year: 'numeric',
141
+ month: 'long',
142
+ day: 'numeric'
143
+ }) : 'TBA'}
144
+ </p>
145
+ </div>
146
+ <div>
147
+ <h3 className="font-semibold text-gray-700">Venue</h3>
148
+ <p className="text-gray-900">{event.event_venue || 'TBA'}</p>
149
+ </div>
150
+ <div>
151
+ <h3 className="font-semibold text-gray-700">Participants</h3>
152
+ <p className="text-gray-900">{event.event_participants || 'TBA'}</p>
153
+ </div>
154
+ <div>
155
+ <h3 className="font-semibold text-gray-700">Event Code</h3>
156
+ <p className="text-gray-900 font-mono">{event.event_code}</p>
157
+ </div>
158
+ </div>
159
+
160
+ {event.event_news && (
161
+ <div>
162
+ <h3 className="font-semibold text-gray-700 mb-2">Event News</h3>
163
+ <p className="text-gray-900">{event.event_news}</p>
164
+ </div>
165
+ )}
166
+ </div>
167
+ </div>
168
+ </div>
169
+
170
+ {/* Event Logo */}
171
+ <div className="flex justify-center lg:justify-start">
172
+ <div className="text-center">
173
+ <EventLogo
174
+ eventId={event.event_id}
175
+ eventName={event.event_name}
176
+ organisationId={event.organisation_id}
177
+ size="2xl"
178
+ className="rounded-lg shadow-lg"
179
+ />
180
+ <p className="mt-4 text-sm text-gray-600">Event Logo</p>
181
+ </div>
182
+ </div>
183
+ </div>
184
+
185
+ {/* Recipe Grid Report Content */}
186
+ <div className="mb-12">
187
+ <div className="bg-green-50 border border-green-200 rounded-lg p-6">
188
+ <h3 className="font-semibold text-green-900 mb-2">Recipe Grid Report</h3>
189
+ <p className="text-green-800">
190
+ This is where your recipe grid report content would go.
191
+ The public page is now working correctly without authentication context conflicts.
192
+ </p>
193
+ <div className="mt-4 text-sm text-green-700">
194
+ <p><strong>Event Code:</strong> {eventCode}</p>
195
+ <p><strong>Event ID:</strong> {event.event_id}</p>
196
+ <p><strong>Event Name:</strong> {event.event_name}</p>
197
+ </div>
198
+ </div>
199
+ </div>
200
+
201
+ {/* Event Footer Information */}
202
+ {event.event_footer && (
203
+ <div className="bg-gray-50 rounded-lg p-6">
204
+ <h3 className="font-semibold text-gray-900 mb-2">Additional Information</h3>
205
+ <p className="text-gray-700">{event.event_footer}</p>
206
+ </div>
207
+ )}
208
+ </main>
209
+
210
+ <PublicPageFooter event={event} />
211
+ </PublicPageLayout>
212
+ </PublicErrorBoundary>
213
+ );
214
+ }
215
+
216
+ export default PublicPageUsageExample;
@@ -15,6 +15,17 @@ vi.mock('../../providers/OrganisationProvider', () => ({
15
15
  useOrganisations: vi.fn(() => mockUseOrganisations)
16
16
  }));
17
17
 
18
+ // Mock useOrganisationSecurity to avoid provider dependencies
19
+ vi.mock('../useOrganisationSecurity', () => ({
20
+ useOrganisationSecurity: vi.fn(() => ({
21
+ superAdminContext: {
22
+ isSuperAdmin: false,
23
+ hasGlobalAccess: false,
24
+ canManageAllOrganisations: false
25
+ }
26
+ }))
27
+ }));
28
+
18
29
  describe('useOrganisationPermissions', () => {
19
30
  describe('Basic functionality', () => {
20
31
  it('should return default values when no organisation context', () => {
@@ -108,7 +119,7 @@ describe('useOrganisationPermissions', () => {
108
119
  const { result } = renderHook(() => useOrganisationPermissions());
109
120
 
110
121
  expect(result.current.isOrgAdmin).toBe(true);
111
- expect(result.current.isSuperAdmin).toBe(true);
122
+ expect(result.current.isSuperAdmin).toBe(false); // Super admin requires database query, not role-based
112
123
  expect(result.current.canModerate).toBe(true);
113
124
  expect(result.current.canManageMembers).toBe(true);
114
125
  expect(result.current.canManageSettings).toBe(true);