@jmruthers/pace-core 0.5.135 → 0.5.137

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 (544) hide show
  1. package/dist/{DataTable-A36PJG6N.js → DataTable-6M4L6BI2.js} +26 -13
  2. package/dist/{DataTable-C7GaRZye.d.ts → DataTable-CWAZZcXC.d.ts} +1 -1
  3. package/dist/{PublicLoadingSpinner-CUAnTvcg.d.ts → EventLogo-rFL_kRjk.d.ts} +123 -135
  4. package/dist/{UnifiedAuthProvider-BVKmQd9u.d.ts → UnifiedAuthProvider-DJxGTftH.d.ts} +1 -1
  5. package/dist/{UnifiedAuthProvider-CQDZRJIS.js → UnifiedAuthProvider-XIQQ7LVU.js} +5 -5
  6. package/dist/{api-TNIBJWLM.js → api-45XYYO2A.js} +4 -3
  7. package/dist/{audit-T36HM7IM.js → audit-64X3VJXB.js} +3 -2
  8. package/dist/{chunk-F64FFPOZ.js → chunk-22WKWKRX.js} +26 -20
  9. package/dist/chunk-22WKWKRX.js.map +1 -0
  10. package/dist/{chunk-VZ5OR6HD.js → chunk-4C7EXCAR.js} +62 -150
  11. package/dist/chunk-4C7EXCAR.js.map +1 -0
  12. package/dist/{chunk-PYUXFQJ3.js → chunk-56XJ3TU6.js} +2 -2
  13. package/dist/chunk-56XJ3TU6.js.map +1 -0
  14. package/dist/{chunk-CTJRBUX2.js → chunk-6LAAY47Q.js} +2 -2
  15. package/dist/{chunk-UJI6WSMD.js → chunk-7QCC6MCP.js} +90 -3
  16. package/dist/chunk-7QCC6MCP.js.map +1 -0
  17. package/dist/{chunk-66C4BSAY.js → chunk-ANBQRTPX.js} +9 -2
  18. package/dist/chunk-ANBQRTPX.js.map +1 -0
  19. package/dist/{chunk-CQZU6TFE.js → chunk-BCIBECNB.js} +100 -62
  20. package/dist/chunk-BCIBECNB.js.map +1 -0
  21. package/dist/{chunk-GKHF54DI.js → chunk-BESYRHQM.js} +10 -4
  22. package/dist/chunk-BESYRHQM.js.map +1 -0
  23. package/dist/chunk-BJPBT3CU.js +21 -0
  24. package/dist/chunk-BJPBT3CU.js.map +1 -0
  25. package/dist/{chunk-BYXRHAIF.js → chunk-BLCXZEYF.js} +23 -14
  26. package/dist/chunk-BLCXZEYF.js.map +1 -0
  27. package/dist/{chunk-WP5I5GLN.js → chunk-BVYWGZVV.js} +112 -97
  28. package/dist/chunk-BVYWGZVV.js.map +1 -0
  29. package/dist/{chunk-GEVIB2UB.js → chunk-ERISIBYU.js} +14 -5
  30. package/dist/chunk-ERISIBYU.js.map +1 -0
  31. package/dist/{chunk-O3NWNXDY.js → chunk-FMUCXFII.js} +2 -2
  32. package/dist/chunk-FMUCXFII.js.map +1 -0
  33. package/dist/{chunk-GVDR7WNV.js → chunk-HAWZXGR2.js} +334 -614
  34. package/dist/chunk-HAWZXGR2.js.map +1 -0
  35. package/dist/{chunk-ZV77RZMU.js → chunk-INQLMHPF.js} +2 -2
  36. package/dist/chunk-JISYG63F.js +70 -0
  37. package/dist/chunk-JISYG63F.js.map +1 -0
  38. package/dist/{chunk-HMNOSGVA.js → chunk-KYRHUBIU.js} +576 -767
  39. package/dist/chunk-KYRHUBIU.js.map +1 -0
  40. package/dist/{chunk-M6DDYFUD.js → chunk-LS353YLY.js} +19 -16
  41. package/dist/chunk-LS353YLY.js.map +1 -0
  42. package/dist/{chunk-TGIY2AR2.js → chunk-MA6EPSGZ.js} +4 -3
  43. package/dist/{chunk-TGIY2AR2.js.map → chunk-MA6EPSGZ.js.map} +1 -1
  44. package/dist/chunk-OWAG3GSU.js +58 -0
  45. package/dist/chunk-OWAG3GSU.js.map +1 -0
  46. package/dist/{chunk-JCQZ6LA7.js → chunk-Q5QRDWKI.js} +9 -3
  47. package/dist/chunk-Q5QRDWKI.js.map +1 -0
  48. package/dist/chunk-S5OFRT4M.js +94 -0
  49. package/dist/chunk-S5OFRT4M.js.map +1 -0
  50. package/dist/{chunk-3DBFLLLU.js → chunk-SBVILCCA.js} +14 -9
  51. package/dist/chunk-SBVILCCA.js.map +1 -0
  52. package/dist/{chunk-ZYZCRSBD.js → chunk-T6JN6LH6.js} +16 -11
  53. package/dist/chunk-T6JN6LH6.js.map +1 -0
  54. package/dist/chunk-XDNLUEXI.js +138 -0
  55. package/dist/chunk-XDNLUEXI.js.map +1 -0
  56. package/dist/{chunk-3CG5L6RN.js → chunk-YCWDTTUK.js} +90 -75
  57. package/dist/chunk-YCWDTTUK.js.map +1 -0
  58. package/dist/{chunk-5F3NDPJV.js → chunk-ZZ2SS7NI.js} +10 -5
  59. package/dist/chunk-ZZ2SS7NI.js.map +1 -0
  60. package/dist/components.d.ts +7 -287
  61. package/dist/components.js +27 -157
  62. package/dist/components.js.map +1 -1
  63. package/dist/{file-reference-C9isKNPn.d.ts → file-reference-C6Gkn77H.d.ts} +1 -1
  64. package/dist/{formatting-DFcCxUEk.d.ts → formatting-CvUXy2mF.d.ts} +1 -1
  65. package/dist/hooks.d.ts +3 -3
  66. package/dist/hooks.js +21 -16
  67. package/dist/hooks.js.map +1 -1
  68. package/dist/index.d.ts +101 -9
  69. package/dist/index.js +44 -31
  70. package/dist/index.js.map +1 -1
  71. package/dist/providers.d.ts +1 -1
  72. package/dist/providers.js +4 -4
  73. package/dist/rbac/index.js +12 -12
  74. package/dist/schema-DTDZQe2u.d.ts +28 -0
  75. package/dist/styles/index.js +2 -1
  76. package/dist/theming/runtime.d.ts +2 -19
  77. package/dist/theming/runtime.js +2 -1
  78. package/dist/{types-D5rqZQXk.d.ts → types-Dfz9dmVH.d.ts} +12 -1
  79. package/dist/types.d.ts +153 -4
  80. package/dist/types.js +51 -16
  81. package/dist/types.js.map +1 -1
  82. package/dist/{useInactivityTracker-MRUU55XI.js → useInactivityTracker-TO6ZOF35.js} +3 -2
  83. package/dist/{usePublicRouteParams-Dyt1tzI9.d.ts → usePublicRouteParams-B7PabvuH.d.ts} +1 -1
  84. package/dist/utils.d.ts +221 -173
  85. package/dist/utils.js +185 -225
  86. package/dist/utils.js.map +1 -1
  87. package/dist/validation.d.ts +24 -115
  88. package/dist/validation.js +19 -474
  89. package/dist/validation.js.map +1 -1
  90. package/docs/api/classes/ColumnFactory.md +1 -1
  91. package/docs/api/classes/ErrorBoundary.md +6 -6
  92. package/docs/api/classes/InvalidScopeError.md +1 -1
  93. package/docs/api/classes/MissingUserContextError.md +1 -1
  94. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  95. package/docs/api/classes/PermissionDeniedError.md +1 -1
  96. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  97. package/docs/api/classes/RBACAuditManager.md +6 -6
  98. package/docs/api/classes/RBACCache.md +1 -1
  99. package/docs/api/classes/RBACEngine.md +7 -7
  100. package/docs/api/classes/RBACError.md +1 -1
  101. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  102. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  103. package/docs/api/classes/StorageUtils.md +1 -1
  104. package/docs/api/enums/FileCategory.md +1 -1
  105. package/docs/api/interfaces/AggregateConfig.md +4 -4
  106. package/docs/api/interfaces/BadgeProps.md +27 -0
  107. package/docs/api/interfaces/ButtonProps.md +1 -1
  108. package/docs/api/interfaces/CardProps.md +1 -1
  109. package/docs/api/interfaces/ColorPalette.md +1 -1
  110. package/docs/api/interfaces/ColorShade.md +29 -4
  111. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  112. package/docs/api/interfaces/DataRecord.md +1 -1
  113. package/docs/api/interfaces/DataTableAction.md +18 -18
  114. package/docs/api/interfaces/DataTableColumn.md +61 -1
  115. package/docs/api/interfaces/DataTableProps.md +1 -1
  116. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  117. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  118. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +14 -14
  119. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  120. package/docs/api/interfaces/EventLogoProps.md +152 -0
  121. package/docs/api/interfaces/ExportColumn.md +1 -1
  122. package/docs/api/interfaces/ExportOptions.md +8 -8
  123. package/docs/api/interfaces/FileDisplayProps.md +15 -15
  124. package/docs/api/interfaces/FileMetadata.md +1 -1
  125. package/docs/api/interfaces/FileReference.md +1 -1
  126. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  127. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  128. package/docs/api/interfaces/FileUploadProps.md +1 -1
  129. package/docs/api/interfaces/FooterProps.md +1 -1
  130. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  131. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  132. package/docs/api/interfaces/InputProps.md +1 -1
  133. package/docs/api/interfaces/LabelProps.md +1 -1
  134. package/docs/api/interfaces/LoginFormProps.md +1 -1
  135. package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
  136. package/docs/api/interfaces/NavigationContextType.md +9 -9
  137. package/docs/api/interfaces/NavigationGuardProps.md +10 -10
  138. package/docs/api/interfaces/NavigationItem.md +1 -1
  139. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  140. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  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 +27 -27
  147. package/docs/api/interfaces/PaceLoginPageProps.md +4 -4
  148. package/docs/api/interfaces/PageAccessRecord.md +8 -8
  149. package/docs/api/interfaces/PagePermissionContextType.md +8 -8
  150. package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
  151. package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
  152. package/docs/api/interfaces/PaletteData.md +4 -4
  153. package/docs/api/interfaces/PermissionEnforcerProps.md +11 -11
  154. package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
  155. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  156. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  157. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  158. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  159. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  160. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  161. package/docs/api/interfaces/RBACConfig.md +1 -1
  162. package/docs/api/interfaces/RBACLogger.md +1 -1
  163. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  164. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  165. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  166. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  167. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  168. package/docs/api/interfaces/RouteConfig.md +10 -10
  169. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  170. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  171. package/docs/api/interfaces/SessionRestorationLoaderProps.md +21 -0
  172. package/docs/api/interfaces/StorageConfig.md +1 -1
  173. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  174. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  175. package/docs/api/interfaces/StorageListOptions.md +1 -1
  176. package/docs/api/interfaces/StorageListResult.md +1 -1
  177. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  178. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  179. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  180. package/docs/api/interfaces/StyleImport.md +1 -1
  181. package/docs/api/interfaces/SwitchProps.md +1 -1
  182. package/docs/api/interfaces/ToastActionElement.md +1 -1
  183. package/docs/api/interfaces/ToastProps.md +1 -1
  184. package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
  185. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  186. package/docs/api/interfaces/UseInactivityTrackerOptions.md +9 -9
  187. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  188. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  189. package/docs/api/interfaces/UsePublicEventReturn.md +5 -5
  190. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  191. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +9 -9
  192. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  193. package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
  194. package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
  195. package/docs/api/interfaces/UserEventAccess.md +11 -11
  196. package/docs/api/interfaces/UserMenuProps.md +1 -1
  197. package/docs/api/interfaces/UserProfile.md +1 -1
  198. package/docs/api/modules.md +591 -220
  199. package/docs/api-reference/components.md +106 -26
  200. package/docs/architecture/README.md +0 -3
  201. package/docs/implementation-guides/data-tables.md +277 -13
  202. package/docs/implementation-guides/forms.md +1 -16
  203. package/docs/implementation-guides/permission-enforcement.md +8 -2
  204. package/docs/styles/README.md +0 -2
  205. package/examples/README.md +30 -14
  206. package/examples/STRUCTURE.md +125 -0
  207. package/examples/components 2/DataTable/HierarchicalActionsExample.tsx +421 -0
  208. package/examples/components 2/DataTable/HierarchicalExample.tsx +475 -0
  209. package/examples/components 2/DataTable/InitialPageSizeExample.tsx +177 -0
  210. package/examples/components 2/DataTable/PerformanceExample.tsx +506 -0
  211. package/examples/components 2/DataTable/index.ts +13 -0
  212. package/examples/components 2/Dialog/BasicHtmlTest.tsx +55 -0
  213. package/examples/components 2/Dialog/DebugHtmlExample.tsx +68 -0
  214. package/examples/components 2/Dialog/HtmlDialogExample.tsx +202 -0
  215. package/examples/components 2/Dialog/ScrollableDialogExample.tsx +290 -0
  216. package/examples/components 2/Dialog/SimpleHtmlTest.tsx +61 -0
  217. package/examples/components 2/Dialog/SmartDialogExample.tsx +322 -0
  218. package/examples/components 2/Dialog/index.ts +15 -0
  219. package/examples/components 2/index.ts +11 -0
  220. package/examples/features/index.ts +12 -0
  221. package/{src/examples → examples/features/public-pages}/CorrectPublicPageImplementation.tsx +14 -17
  222. package/{src/examples → examples/features/public-pages}/PublicEventPage.tsx +14 -27
  223. package/{src/examples → examples/features/public-pages}/PublicPageApp.tsx +15 -28
  224. package/{src/examples → examples/features/public-pages}/PublicPageUsageExample.tsx +8 -10
  225. package/examples/features/public-pages/index.ts +14 -0
  226. package/examples/features/rbac/CompleteRBACExample.tsx +324 -0
  227. package/examples/features/rbac/EventBasedApp.tsx +239 -0
  228. package/examples/features/rbac/PermissionExample.tsx +151 -0
  229. package/examples/features/rbac/index.ts +13 -0
  230. package/examples/index.ts +11 -3
  231. package/package.json +30 -19
  232. package/src/__tests__/TEST_STANDARD.md +92 -0
  233. package/src/components/Alert/Alert.tsx +1 -1
  234. package/src/components/Avatar/Avatar.tsx +1 -1
  235. package/src/components/Badge/Badge.test.tsx +314 -0
  236. package/src/components/Badge/Badge.tsx +304 -0
  237. package/src/components/Badge/index.ts +3 -0
  238. package/src/components/Button/Button.tsx +1 -1
  239. package/src/components/Card/Card.tsx +1 -1
  240. package/src/components/Checkbox/Checkbox.tsx +1 -1
  241. package/src/components/DataTable/DataTable.test.tsx +1 -1
  242. package/src/components/DataTable/DataTable.tsx +1 -30
  243. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +562 -0
  244. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +217 -0
  245. package/src/components/DataTable/__tests__/styles.test.ts +3 -3
  246. package/src/components/DataTable/components/ActionButtons.tsx +0 -15
  247. package/src/components/DataTable/components/ColumnFilter.tsx +8 -4
  248. package/src/components/DataTable/components/DataTableBody.tsx +461 -0
  249. package/src/components/DataTable/components/DataTableCore.tsx +4 -185
  250. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +1 -1
  251. package/src/components/DataTable/components/DataTableModals.tsx +1 -27
  252. package/src/components/DataTable/components/DraggableColumnHeader.tsx +144 -0
  253. package/src/components/DataTable/components/EditableRow.tsx +1 -1
  254. package/src/components/DataTable/components/FilterRow.tsx +9 -3
  255. package/src/components/DataTable/components/ImportModal.tsx +2 -14
  256. package/src/components/DataTable/components/PaginationControls.tsx +2 -1
  257. package/src/components/DataTable/components/UnifiedTableBody.tsx +109 -82
  258. package/src/components/DataTable/components/VirtualizedDataTable.tsx +513 -0
  259. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +14 -68
  260. package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +1 -1
  261. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +62 -0
  262. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +1 -1
  263. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +1 -1
  264. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +43 -0
  265. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +1 -1
  266. package/src/components/DataTable/core/ActionManager.ts +235 -0
  267. package/src/components/DataTable/core/ColumnManager.ts +205 -0
  268. package/src/components/DataTable/core/DataManager.ts +188 -0
  269. package/src/components/DataTable/core/DataTableContext.tsx +181 -0
  270. package/src/components/DataTable/core/LocalDataAdapter.ts +273 -0
  271. package/src/components/DataTable/core/PluginRegistry.ts +229 -0
  272. package/src/components/DataTable/core/StateManager.ts +311 -0
  273. package/src/components/DataTable/core/interfaces.ts +338 -0
  274. package/src/components/DataTable/examples/GroupingAggregationExample.tsx +273 -0
  275. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +1 -1
  276. package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +1 -1
  277. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +1 -1
  278. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +1 -1
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +2 -23
  280. package/src/components/DataTable/index.ts +4 -0
  281. package/src/components/DataTable/styles.ts +28 -7
  282. package/src/components/DataTable/types.ts +13 -0
  283. package/src/components/DataTable/utils/__tests__/columnUtils.test.ts +94 -0
  284. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +1 -1
  285. package/src/components/DataTable/utils/aggregationUtils.ts +161 -0
  286. package/src/components/DataTable/utils/columnUtils.ts +40 -0
  287. package/src/components/DataTable/utils/debugTools.ts +609 -0
  288. package/src/components/DataTable/utils/exportUtils.ts +1 -1
  289. package/src/components/DataTable/utils/flexibleImport.ts +1 -11
  290. package/src/components/DataTable/utils/index.ts +2 -0
  291. package/src/components/DataTable/utils/paginationUtils.ts +1 -1
  292. package/src/components/Dialog/Dialog.tsx +2 -2
  293. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +8 -1
  294. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +35 -7
  295. package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -4
  296. package/src/components/EventSelector/EventSelector.tsx +3 -2
  297. package/src/components/FileDisplay/FileDisplay.tsx +2 -36
  298. package/src/components/FileUpload/FileUpload.test.tsx +2 -2
  299. package/src/components/FileUpload/FileUpload.tsx +2 -2
  300. package/src/components/Footer/Footer.test.tsx +1 -1
  301. package/src/components/Footer/Footer.tsx +1 -1
  302. package/src/components/Form/Form.test.tsx +5 -510
  303. package/src/components/Form/Form.tsx +1 -1
  304. package/src/components/Form/FormField.tsx +1 -1
  305. package/src/components/Form/index.ts +0 -12
  306. package/src/components/Header/Header.tsx +1 -1
  307. package/src/components/Input/Input.tsx +1 -1
  308. package/src/components/Label/Label.tsx +1 -1
  309. package/src/components/LoginForm/LoginForm.test.tsx +1 -1
  310. package/src/components/LoginForm/LoginForm.tsx +1 -1
  311. package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -3
  312. package/src/components/NavigationMenu/NavigationMenu.tsx +9 -8
  313. package/src/components/OrganisationSelector/OrganisationSelector.tsx +4 -3
  314. package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -12
  315. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +0 -16
  316. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +76 -10
  317. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +0 -1
  318. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -9
  319. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +35 -3
  320. package/src/components/PaceLoginPage/PaceLoginPage.tsx +14 -13
  321. package/src/components/PasswordReset/PasswordChangeForm.tsx +1 -1
  322. package/src/components/PasswordReset/index.ts +0 -2
  323. package/src/components/Progress/Progress.tsx +1 -1
  324. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +35 -8
  325. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -2
  326. package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
  327. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +1 -1
  328. package/src/components/PublicLayout/PublicPageContextChecker.tsx +44 -43
  329. package/src/components/PublicLayout/PublicPageFooter.tsx +1 -1
  330. package/src/components/PublicLayout/PublicPageHeader.tsx +1 -15
  331. package/src/components/PublicLayout/PublicPageProvider.tsx +3 -2
  332. package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +2 -0
  333. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +1 -1
  334. package/src/components/PublicLayout/index.ts +4 -2
  335. package/src/components/Select/Select.test.tsx +1 -1
  336. package/src/components/Select/Select.tsx +21 -9
  337. package/src/components/{SessionRestorationLoader.tsx → SessionRestorationLoader/SessionRestorationLoader.tsx} +3 -2
  338. package/src/components/SessionRestorationLoader/index.ts +3 -0
  339. package/src/components/Switch/Switch.tsx +1 -1
  340. package/src/components/Table/Table.tsx +1 -1
  341. package/src/components/Table/__tests__/Table.test.tsx +1 -1
  342. package/src/components/Toast/Toast.tsx +1 -1
  343. package/src/components/Tooltip/Tooltip.tsx +1 -1
  344. package/src/components/index.ts +7 -10
  345. package/src/hooks/__tests__/hooks.integration.test.tsx +37 -22
  346. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +33 -17
  347. package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +28 -3
  348. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +36 -9
  349. package/src/hooks/__tests__/useFileUrl.unit.test.ts +83 -85
  350. package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +26 -2
  351. package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +19 -6
  352. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -4
  353. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +17 -4
  354. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +26 -6
  355. package/src/hooks/__tests__/usePublicFileDisplay.test.ts +16 -6
  356. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +3 -3
  357. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +17 -3
  358. package/src/hooks/public/usePublicEvent.ts +7 -6
  359. package/src/hooks/public/usePublicEventLogo.ts +7 -4
  360. package/src/hooks/public/usePublicFileDisplay.ts +6 -150
  361. package/src/hooks/useComponentPerformance.ts +4 -1
  362. package/src/hooks/useDataTablePerformance.ts +4 -3
  363. package/src/hooks/useEventTheme.test.ts +18 -5
  364. package/src/hooks/useEventTheme.ts +4 -1
  365. package/src/hooks/useEvents.ts +2 -0
  366. package/src/hooks/useFileDisplay.ts +9 -8
  367. package/src/hooks/useFileReference.ts +4 -1
  368. package/src/hooks/useFileUrl.ts +4 -1
  369. package/src/hooks/useInactivityTracker.ts +5 -4
  370. package/src/hooks/useOrganisationSecurity.test.ts +33 -12
  371. package/src/hooks/useOrganisationSecurity.ts +8 -7
  372. package/src/hooks/usePerformanceMonitor.ts +6 -3
  373. package/src/hooks/usePermissionCache.ts +13 -6
  374. package/src/hooks/useSecureDataAccess.test.ts +2 -2
  375. package/src/hooks/useSecureDataAccess.ts +9 -8
  376. package/src/hooks/useSessionRestoration.ts +4 -1
  377. package/src/hooks/useStorage.ts +4 -1
  378. package/src/index.ts +20 -7
  379. package/src/providers/services/AuthServiceProvider.tsx +3 -2
  380. package/src/providers/services/EventServiceProvider.tsx +2 -1
  381. package/src/providers/services/InactivityServiceProvider.tsx +2 -1
  382. package/src/providers/services/OrganisationServiceProvider.tsx +2 -1
  383. package/src/providers/services/UnifiedAuthProvider.tsx +4 -3
  384. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +22 -2
  385. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +24 -2
  386. package/src/rbac/__tests__/cache-invalidation.test.ts +20 -6
  387. package/src/rbac/api.ts +5 -2
  388. package/src/rbac/audit-enhanced.ts +6 -6
  389. package/src/rbac/audit.test.ts +60 -38
  390. package/src/rbac/audit.ts +8 -8
  391. package/src/rbac/cache-invalidation.ts +7 -4
  392. package/src/rbac/components/EnhancedNavigationMenu.tsx +11 -5
  393. package/src/rbac/components/NavigationGuard.tsx +7 -3
  394. package/src/rbac/components/NavigationProvider.tsx +6 -3
  395. package/src/rbac/components/PagePermissionGuard.tsx +28 -16
  396. package/src/rbac/components/PagePermissionProvider.tsx +4 -1
  397. package/src/rbac/components/PermissionEnforcer.tsx +9 -3
  398. package/src/rbac/components/RoleBasedRouter.tsx +3 -1
  399. package/src/rbac/components/SecureDataProvider.tsx +7 -3
  400. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +87 -61
  401. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +83 -33
  402. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +36 -13
  403. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +2 -2
  404. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +22 -8
  405. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +19 -6
  406. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +43 -17
  407. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +42 -17
  408. package/src/rbac/engine.ts +15 -7
  409. package/src/rbac/hooks/usePermissions.ts +7 -3
  410. package/src/rbac/hooks/useResolvedScope.test.ts +2 -2
  411. package/src/rbac/hooks/useResolvedScope.ts +10 -7
  412. package/src/rbac/permissions.ts +5 -2
  413. package/src/rbac/security.test.ts +27 -16
  414. package/src/rbac/security.ts +5 -4
  415. package/src/services/AuthService.ts +22 -21
  416. package/src/services/EventService.ts +12 -12
  417. package/src/services/InactivityService.ts +5 -4
  418. package/src/services/OrganisationService.ts +26 -25
  419. package/src/services/__tests__/AuthService.test.ts +51 -19
  420. package/src/services/__tests__/EventService.test.ts +37 -5
  421. package/src/services/__tests__/InactivityService.test.ts +38 -4
  422. package/src/services/__tests__/OrganisationService.test.ts +3 -8
  423. package/src/services/base/BaseService.ts +3 -1
  424. package/src/styles/core.css +3 -0
  425. package/src/theming/__tests__/runtime.test.ts +21 -12
  426. package/src/theming/parseEventColours.ts +5 -19
  427. package/src/theming/runtime.ts +8 -4
  428. package/src/types/validation.ts +2 -29
  429. package/src/utils/__tests__/appConfig.unit.test.ts +1 -1
  430. package/src/utils/__tests__/audit.unit.test.ts +1 -1
  431. package/src/utils/__tests__/auth-utils.unit.test.ts +1 -1
  432. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +19 -19
  433. package/src/utils/__tests__/cn.unit.test.ts +1 -1
  434. package/src/utils/__tests__/debugLogger.test.ts +1 -1
  435. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -1
  436. package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -1
  437. package/src/utils/__tests__/formatting.unit.test.ts +1 -1
  438. package/src/utils/__tests__/lazyLoad.unit.test.tsx +1 -1
  439. package/src/utils/__tests__/logger.unit.test.ts +1 -1
  440. package/src/utils/__tests__/organisationContext.unit.test.ts +1 -1
  441. package/src/utils/__tests__/performanceBenchmark.test.ts +1 -1
  442. package/src/utils/__tests__/performanceBudgets.unit.test.ts +1 -1
  443. package/src/utils/__tests__/permissionTypes.unit.test.ts +1 -1
  444. package/src/utils/__tests__/permissionUtils.unit.test.ts +1 -1
  445. package/src/utils/__tests__/sanitization.unit.test.ts +1 -1
  446. package/src/utils/__tests__/schemaUtils.unit.test.ts +1 -1
  447. package/src/utils/__tests__/secureDataAccess.unit.test.ts +1 -1
  448. package/src/utils/__tests__/secureErrors.unit.test.ts +33 -15
  449. package/src/utils/__tests__/secureStorage.unit.test.ts +1 -1
  450. package/src/utils/__tests__/security.unit.test.ts +40 -18
  451. package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -1
  452. package/src/utils/__tests__/sessionTracking.unit.test.ts +40 -29
  453. package/src/utils/__tests__/validationUtils.unit.test.ts +19 -6
  454. package/src/utils/app/appConfig.ts +47 -0
  455. package/src/utils/app/appIdResolver.test.ts +497 -0
  456. package/src/utils/app/appIdResolver.ts +133 -0
  457. package/src/utils/app/appNameResolver.simple.test.ts +212 -0
  458. package/src/utils/app/appNameResolver.test.ts +121 -0
  459. package/src/utils/app/appNameResolver.ts +195 -0
  460. package/src/utils/audit/audit.ts +127 -0
  461. package/src/utils/context/organisationContext.test.ts +322 -0
  462. package/src/utils/context/organisationContext.ts +156 -0
  463. package/src/utils/context/sessionTracking.ts +125 -0
  464. package/src/utils/core/cn.ts +7 -0
  465. package/src/utils/core/debugLogger.ts +67 -0
  466. package/src/utils/core/logger.ts +181 -0
  467. package/src/utils/device/deviceFingerprint.ts +215 -0
  468. package/src/utils/dynamic/dynamicUtils.ts +105 -0
  469. package/src/utils/dynamic/lazyLoad.tsx +44 -0
  470. package/src/utils/file-reference/__tests__/file-reference.test.ts +788 -0
  471. package/src/utils/file-reference/index.ts +501 -0
  472. package/src/utils/formatting/formatDate.test.ts +237 -0
  473. package/src/utils/formatting/formatting.ts +133 -0
  474. package/src/utils/index.ts +39 -54
  475. package/src/utils/performance/bundleAnalysis.ts +129 -0
  476. package/src/utils/performance/performanceBenchmark.ts +64 -0
  477. package/src/utils/performance/performanceBudgets.ts +110 -0
  478. package/src/utils/permissions/permissionTypes.ts +37 -0
  479. package/src/utils/permissions/permissionUtils.test.ts +393 -0
  480. package/src/utils/permissions/permissionUtils.ts +34 -0
  481. package/src/utils/security/auth-utils.ts +96 -0
  482. package/src/utils/security/secureDataAccess.test.ts +711 -0
  483. package/src/utils/security/secureDataAccess.ts +377 -0
  484. package/src/utils/security/secureErrors.ts +82 -0
  485. package/src/utils/security/secureStorage.ts +244 -0
  486. package/src/utils/security/security.ts +159 -0
  487. package/src/utils/security/securityMonitor.ts +45 -0
  488. package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -4
  489. package/src/utils/storage/helpers.ts +15 -8
  490. package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +598 -0
  491. package/src/{validation → utils/validation}/csrf.ts +1 -1
  492. package/src/utils/validation/htmlSanitization.ts +184 -0
  493. package/src/utils/validation/index.ts +79 -0
  494. package/src/utils/validation/sanitization.ts +333 -0
  495. package/src/{validation/schemaUtils.ts → utils/validation/schema.ts} +11 -6
  496. package/src/{validation → utils/validation}/sqlInjectionProtection.ts +2 -0
  497. package/src/utils/validation/validation.ts +111 -0
  498. package/src/utils/validation/validationUtils.ts +123 -0
  499. package/src/validation/index.ts +3 -34
  500. package/dist/chunk-24MKLB7U.js +0 -81
  501. package/dist/chunk-24MKLB7U.js.map +0 -1
  502. package/dist/chunk-3CG5L6RN.js.map +0 -1
  503. package/dist/chunk-3DBFLLLU.js.map +0 -1
  504. package/dist/chunk-5F3NDPJV.js.map +0 -1
  505. package/dist/chunk-66C4BSAY.js.map +0 -1
  506. package/dist/chunk-BDZUMRBD.js +0 -87
  507. package/dist/chunk-BDZUMRBD.js.map +0 -1
  508. package/dist/chunk-BYXRHAIF.js.map +0 -1
  509. package/dist/chunk-CDQ3PX7L.js +0 -18
  510. package/dist/chunk-CDQ3PX7L.js.map +0 -1
  511. package/dist/chunk-CQZU6TFE.js.map +0 -1
  512. package/dist/chunk-F64FFPOZ.js.map +0 -1
  513. package/dist/chunk-GEVIB2UB.js.map +0 -1
  514. package/dist/chunk-GKHF54DI.js.map +0 -1
  515. package/dist/chunk-GVDR7WNV.js.map +0 -1
  516. package/dist/chunk-HMNOSGVA.js.map +0 -1
  517. package/dist/chunk-JCQZ6LA7.js.map +0 -1
  518. package/dist/chunk-M6DDYFUD.js.map +0 -1
  519. package/dist/chunk-O3NWNXDY.js.map +0 -1
  520. package/dist/chunk-PYUXFQJ3.js.map +0 -1
  521. package/dist/chunk-UJI6WSMD.js.map +0 -1
  522. package/dist/chunk-VZ5OR6HD.js.map +0 -1
  523. package/dist/chunk-WP5I5GLN.js.map +0 -1
  524. package/dist/chunk-ZYZCRSBD.js.map +0 -1
  525. package/dist/validation-DnhrNMju.d.ts +0 -159
  526. package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +0 -185
  527. package/src/validation/__tests__/common.unit.test.ts +0 -101
  528. package/src/validation/__tests__/csrf.unit.test.ts +0 -365
  529. package/src/validation/__tests__/passwordSchema.unit.test.ts +0 -203
  530. package/src/validation/__tests__/sanitization.unit.test.ts +0 -250
  531. package/src/validation/__tests__/schemaUtils.unit.test.ts +0 -451
  532. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +0 -462
  533. package/src/validation/__tests__/user.unit.test.ts +0 -440
  534. package/src/validation/sanitization.ts +0 -96
  535. /package/dist/{DataTable-A36PJG6N.js.map → DataTable-6M4L6BI2.js.map} +0 -0
  536. /package/dist/{UnifiedAuthProvider-CQDZRJIS.js.map → UnifiedAuthProvider-XIQQ7LVU.js.map} +0 -0
  537. /package/dist/{api-TNIBJWLM.js.map → api-45XYYO2A.js.map} +0 -0
  538. /package/dist/{audit-T36HM7IM.js.map → audit-64X3VJXB.js.map} +0 -0
  539. /package/dist/{chunk-CTJRBUX2.js.map → chunk-6LAAY47Q.js.map} +0 -0
  540. /package/dist/{chunk-ZV77RZMU.js.map → chunk-INQLMHPF.js.map} +0 -0
  541. /package/dist/{useInactivityTracker-MRUU55XI.js.map → useInactivityTracker-TO6ZOF35.js.map} +0 -0
  542. /package/src/{validation → utils/validation}/common.ts +0 -0
  543. /package/src/{validation → utils/validation}/passwordSchema.ts +0 -0
  544. /package/src/{validation → utils/validation}/user.ts +0 -0
@@ -16,7 +16,7 @@ let mockPerformanceNowValue = 0;
16
16
  const mockPerformanceNow = vi.fn(() => mockPerformanceNowValue);
17
17
 
18
18
  // Mock performanceBudgetMonitor
19
- vi.mock('../../utils/performanceBudgets', () => ({
19
+ vi.mock('../../utils/performance/performanceBudgets', () => ({
20
20
  performanceBudgetMonitor: {
21
21
  measure: vi.fn(() => ({
22
22
  passed: true,
@@ -30,7 +30,21 @@ vi.mock('../../utils/performanceBudgets', () => ({
30
30
  },
31
31
  }));
32
32
 
33
- import { performanceBudgetMonitor } from '../../utils/performanceBudgets';
33
+ // Mock the Logger module
34
+ vi.mock('../../utils/core/logger', () => {
35
+ const mockLoggerInstance = {
36
+ warn: vi.fn(),
37
+ };
38
+ return {
39
+ createLogger: vi.fn(() => mockLoggerInstance),
40
+ };
41
+ });
42
+
43
+ // Get the mock instance after mock is set up
44
+ import { createLogger as createLoggerImport } from '../../utils/core/logger';
45
+ const getMockLogger = () => createLoggerImport('test');
46
+
47
+ import { performanceBudgetMonitor } from '../../utils/performance/performanceBudgets';
34
48
 
35
49
  // Mock window.performance
36
50
  Object.defineProperty(window, 'performance', {
@@ -458,7 +472,7 @@ describe('usePerformanceMonitor', () => {
458
472
  });
459
473
 
460
474
  it('logs warning when budget is exceeded in development', () => {
461
- const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
475
+ vi.clearAllMocks();
462
476
 
463
477
  vi.mocked(performanceBudgetMonitor.measure).mockReturnValue({
464
478
  passed: false,
@@ -492,11 +506,10 @@ describe('usePerformanceMonitor', () => {
492
506
  result2.current.endMeasurement();
493
507
  });
494
508
 
495
- expect(consoleWarnSpy).toHaveBeenCalledWith(
509
+ const logger = getMockLogger();
510
+ expect(vi.mocked(logger.warn)).toHaveBeenCalledWith(
496
511
  expect.stringContaining('Performance budget exceeded')
497
512
  );
498
-
499
- consoleWarnSpy.mockRestore();
500
513
  });
501
514
  });
502
515
 
@@ -15,6 +15,20 @@ vi.mock('../../rbac/api', async () => {
15
15
  };
16
16
  });
17
17
 
18
+ // Mock logger
19
+ vi.mock('../../utils/core/logger', () => {
20
+ const mockLoggerInstance = {
21
+ debug: vi.fn(),
22
+ info: vi.fn(),
23
+ warn: vi.fn(),
24
+ error: vi.fn(),
25
+ };
26
+ return {
27
+ createLogger: vi.fn(() => mockLoggerInstance),
28
+ logger: mockLoggerInstance,
29
+ };
30
+ });
31
+
18
32
  // Mock useOrganisations hook (required by usePermissionCache)
19
33
  const mockOrganisationContext = {
20
34
  selectedOrganisation: {
@@ -115,7 +129,7 @@ describe('usePermissionCache - Simple Tests', () => {
115
129
  });
116
130
 
117
131
  it('should handle permission check errors gracefully', async () => {
118
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
132
+ const { logger } = await import('../../utils/core/logger');
119
133
  mockIsPermittedCached.mockRejectedValueOnce(new Error('Database error'));
120
134
 
121
135
  mockUseRBAC.mockReturnValue({
@@ -130,9 +144,8 @@ describe('usePermissionCache - Simple Tests', () => {
130
144
  const permission = await result.current.checkPermission('read', 'dashboard');
131
145
 
132
146
  expect(permission).toBe(false);
133
- expect(consoleSpy).toHaveBeenCalled();
134
-
135
- consoleSpy.mockRestore();
147
+ // Verify error was logged using logger
148
+ expect(logger.error).toHaveBeenCalled();
136
149
  });
137
150
 
138
151
  it('should provide debug information', () => {
@@ -26,6 +26,20 @@ vi.mock('../../rbac/api', async () => {
26
26
  };
27
27
  });
28
28
 
29
+ // Mock logger
30
+ vi.mock('../../utils/core/logger', () => {
31
+ const mockLoggerInstance = {
32
+ debug: vi.fn(),
33
+ info: vi.fn(),
34
+ warn: vi.fn(),
35
+ error: vi.fn(),
36
+ };
37
+ return {
38
+ createLogger: vi.fn(() => mockLoggerInstance),
39
+ logger: mockLoggerInstance,
40
+ };
41
+ });
42
+
29
43
  // Mock useOrganisations hook (required by usePermissionCache)
30
44
  const mockOrganisationContext = {
31
45
  selectedOrganisation: {
@@ -184,7 +198,7 @@ describe('usePermissionCache', () => {
184
198
  });
185
199
 
186
200
  it('handles permission check errors gracefully', async () => {
187
- const consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
201
+ const { logger } = await import('../../utils/core/logger');
188
202
  mockIsPermittedCached.mockRejectedValueOnce(new Error('Database error'));
189
203
 
190
204
  mockUseRBAC.mockReturnValue({
@@ -199,9 +213,8 @@ describe('usePermissionCache', () => {
199
213
  const permission = await result.current.checkPermission('read', 'dashboard');
200
214
 
201
215
  expect(permission).toBe(false);
202
- expect(consoleSpy).toHaveBeenCalled();
203
-
204
- consoleSpy.mockRestore();
216
+ // Verify error was logged using logger
217
+ expect(logger.error).toHaveBeenCalled();
205
218
  });
206
219
  });
207
220
 
@@ -41,7 +41,21 @@ vi.mock('@supabase/supabase-js', () => ({
41
41
  const originalEnv = import.meta.env;
42
42
 
43
43
  describe('usePublicEvent - Simple Tests', () => {
44
+ let originalMode: string | undefined;
45
+
44
46
  beforeEach(() => {
47
+ // Ensure logger is enabled by setting MODE to development
48
+ originalMode = import.meta.env.MODE;
49
+ (import.meta.env as any).MODE = 'development';
50
+
51
+ import('../../utils/core/logger').then(({ Logger, LogLevel }) => {
52
+ Logger.configure({
53
+ level: LogLevel.DEBUG,
54
+ includeTimestamp: false,
55
+ includeComponent: true,
56
+ });
57
+ });
58
+
45
59
  vi.clearAllMocks();
46
60
  clearPublicEventCache();
47
61
 
@@ -62,6 +76,10 @@ describe('usePublicEvent - Simple Tests', () => {
62
76
  });
63
77
 
64
78
  afterEach(() => {
79
+ // Restore original mode
80
+ if (originalMode !== undefined) {
81
+ (import.meta.env as any).MODE = originalMode;
82
+ }
65
83
  vi.clearAllMocks();
66
84
  clearPublicEventCache();
67
85
  Object.defineProperty(import.meta, 'env', {
@@ -623,7 +641,7 @@ describe('usePublicEvent - Simple Tests', () => {
623
641
  expect(result.current.error).toEqual(new Error('Event not found'));
624
642
  });
625
643
 
626
- it('handles missing Supabase environment variables', () => {
644
+ it('handles missing Supabase environment variables', async () => {
627
645
  // Mock usePublicPageContext to return null environment
628
646
  vi.mocked(usePublicPageContext).mockReturnValue({
629
647
  environment: {
@@ -638,20 +656,22 @@ describe('usePublicEvent - Simple Tests', () => {
638
656
  writable: true
639
657
  });
640
658
 
641
- const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
659
+ const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
642
660
 
643
661
  const { result } = renderHook(() => usePublicEvent('test-event'));
644
662
 
645
- expect(consoleSpy).toHaveBeenCalledWith(
646
- '[usePublicEvent] Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.'
647
- );
663
+ await waitFor(() => {
664
+ expect(consoleWarnSpy).toHaveBeenCalledWith(
665
+ expect.stringContaining('[WARN] [usePublicEvent] Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.')
666
+ );
667
+ }, { timeout: 2000 });
648
668
 
649
669
  // Should still initialize but with error
650
670
  expect(result.current.isLoading).toBe(false);
651
671
  expect(result.current.error).toBeInstanceOf(Error);
652
672
  expect(result.current.error?.message).toContain('Invalid event code or Supabase client not available');
653
673
 
654
- consoleSpy.mockRestore();
674
+ consoleWarnSpy.mockRestore();
655
675
  });
656
676
 
657
677
  it('handles server-side rendering (window undefined)', () => {
@@ -26,6 +26,16 @@ vi.mock('../../utils/storage/helpers', () => ({
26
26
  getPublicUrl: vi.fn((supabase: any, path: string) => `https://example.com/${path}`)
27
27
  }));
28
28
 
29
+ // Mock logger
30
+ vi.mock('../../utils/core/logger', () => ({
31
+ logger: {
32
+ debug: vi.fn(),
33
+ info: vi.fn(),
34
+ warn: vi.fn(),
35
+ error: vi.fn(),
36
+ },
37
+ }));
38
+
29
39
  import { getPublicUrl } from '../../utils/storage/helpers';
30
40
 
31
41
  describe('usePublicFileDisplay Hook', () => {
@@ -618,7 +628,7 @@ describe('usePublicFileDisplay Hook', () => {
618
628
  });
619
629
 
620
630
  it('validates UUID format for organisation_id', async () => {
621
- const consoleSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
631
+ const { logger } = await import('../../utils/core/logger');
622
632
 
623
633
  (mockSupabase.rpc as any).mockResolvedValue({
624
634
  data: [],
@@ -638,12 +648,12 @@ describe('usePublicFileDisplay Hook', () => {
638
648
  { timeout: 2000 }
639
649
  );
640
650
 
641
- expect(consoleSpy).toHaveBeenCalledWith(
642
- '[usePublicFileDisplay] Invalid organisationId format (not a valid UUID):',
643
- 'invalid-uuid'
651
+ // Verify warning was logged using logger
652
+ expect(logger.warn).toHaveBeenCalledWith(
653
+ 'usePublicFileDisplay',
654
+ 'Invalid organisationId format (not a valid UUID)',
655
+ { organisation_id: 'invalid-uuid' }
644
656
  );
645
-
646
- consoleSpy.mockRestore();
647
657
  });
648
658
  });
649
659
 
@@ -18,7 +18,7 @@ vi.mock('../../hooks/useOrganisations', () => ({
18
18
  useOrganisations: vi.fn(),
19
19
  }));
20
20
 
21
- vi.mock('../../utils/organisationContext', () => ({
21
+ vi.mock('../../utils/context/organisationContext', () => ({
22
22
  setOrganisationContext: vi.fn().mockResolvedValue(undefined),
23
23
  }));
24
24
 
@@ -621,8 +621,8 @@ describe('useSecureDataAccess', () => {
621
621
  organisation_id: 'org-123'
622
622
  })
623
623
  );
624
- // Verify RPC was called correctly
625
- expect(mockSupabase.rpc).toHaveBeenCalledTimes(1);
624
+ // Verify RPC was called correctly (may be called multiple times due to React strict mode or other effects)
625
+ expect(mockSupabase.rpc).toHaveBeenCalled();
626
626
 
627
627
  consoleSpy.mockRestore();
628
628
  });
@@ -14,6 +14,20 @@ import { useSessionRestoration } from '../useSessionRestoration';
14
14
  import { AuthServiceContext } from '../../providers/services/AuthServiceProvider';
15
15
  import type { SessionRestorationState } from '../../types/auth';
16
16
 
17
+ // Mock the Logger module
18
+ vi.mock('../../utils/core/logger', () => {
19
+ const mockLoggerInstance = {
20
+ warn: vi.fn(),
21
+ };
22
+ return {
23
+ createLogger: vi.fn(() => mockLoggerInstance),
24
+ };
25
+ });
26
+
27
+ // Get the mock instance after mock is set up
28
+ import { createLogger } from '../../utils/core/logger';
29
+ const getMockLogger = () => createLogger('test');
30
+
17
31
  const SESSION_RESTORATION_TIMEOUT_MS = 5000;
18
32
 
19
33
  describe('useSessionRestoration', () => {
@@ -30,7 +44,6 @@ describe('useSessionRestoration', () => {
30
44
  beforeEach(() => {
31
45
  vi.clearAllMocks();
32
46
  vi.useFakeTimers();
33
- vi.spyOn(console, 'warn').mockImplementation(() => {});
34
47
 
35
48
  mockContext = {
36
49
  sessionRestoration: {
@@ -128,8 +141,9 @@ describe('useSessionRestoration', () => {
128
141
  // With fake timers, the timeout should fire immediately
129
142
  expect(result.current.hasTimedOut).toBe(true);
130
143
 
131
- expect(console.warn).toHaveBeenCalledWith(
132
- '[useSessionRestoration] Session restoration timed out'
144
+ const logger = getMockLogger();
145
+ expect(vi.mocked(logger.warn)).toHaveBeenCalledWith(
146
+ 'Session restoration timed out'
133
147
  );
134
148
  });
135
149
 
@@ -64,6 +64,7 @@ import { createClient } from '@supabase/supabase-js';
64
64
  import type { Event } from '../../types/unified';
65
65
  import type { Database } from '../../types/database';
66
66
  import { usePublicPageContext } from '../../components/PublicLayout/PublicPageProvider';
67
+ import { logger } from '../../utils/core/logger';
67
68
 
68
69
  // Simple in-memory cache for public data
69
70
  const publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
@@ -127,7 +128,7 @@ export function usePublicEvent(
127
128
  if (typeof window === 'undefined') return null;
128
129
 
129
130
  if (!environment.supabaseUrl || !environment.supabaseKey) {
130
- console.warn('[usePublicEvent] Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.');
131
+ logger.warn('usePublicEvent', 'Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.');
131
132
  return null;
132
133
  }
133
134
 
@@ -141,7 +142,7 @@ export function usePublicEvent(
141
142
  await (supabase as any).from('information_schema.routines').select('routine_name').limit(1);
142
143
  } catch (error) {
143
144
  // Ignore errors, this is just an attempt to refresh cache
144
- console.debug('[usePublicEvent] Schema cache refresh attempt failed:', error);
145
+ logger.debug('usePublicEvent', 'Schema cache refresh attempt failed:', error);
145
146
  }
146
147
  }, [supabase]);
147
148
 
@@ -184,7 +185,7 @@ export function usePublicEvent(
184
185
  if (rpcError.message?.includes('Could not find the function') ||
185
186
  rpcError.message?.includes('does not exist') ||
186
187
  rpcError.message?.includes('schema cache')) {
187
- console.warn('[usePublicEvent] RPC function not found or schema cache issue, attempting refresh:', rpcError.message);
188
+ logger.warn('usePublicEvent', 'RPC function not found or schema cache issue, attempting refresh:', rpcError.message);
188
189
 
189
190
  // Try to refresh schema cache first
190
191
  await refreshSchemaCache();
@@ -204,7 +205,7 @@ export function usePublicEvent(
204
205
  throw new Error('RPC still failing after cache refresh');
205
206
  }
206
207
  } catch (retryError) {
207
- console.warn('[usePublicEvent] RPC still failing after cache refresh, falling back to direct table access');
208
+ logger.warn('usePublicEvent', 'RPC still failing after cache refresh, falling back to direct table access');
208
209
 
209
210
  // Fallback: Direct table access with public RLS policy
210
211
  const tableResponse2 = await (supabase as any)
@@ -281,7 +282,7 @@ export function usePublicEvent(
281
282
  }
282
283
  } catch (rpcError) {
283
284
  // If RPC call fails for any reason (including schema cache issues), try direct table access
284
- console.warn('[usePublicEvent] RPC call failed, falling back to direct table access:', rpcError);
285
+ logger.warn('usePublicEvent', 'RPC call failed, falling back to direct table access:', rpcError);
285
286
 
286
287
  const tableResponse = await (supabase as any)
287
288
  .from('event')
@@ -372,7 +373,7 @@ export function usePublicEvent(
372
373
  }
373
374
 
374
375
  } catch (err) {
375
- console.error('[usePublicEvent] Error fetching event:', err);
376
+ logger.error('usePublicEvent', 'Error fetching event:', err);
376
377
  const error = err instanceof Error ? err : new Error('Unknown error occurred');
377
378
  setError(error);
378
379
  setEvent(null);
@@ -67,6 +67,9 @@
67
67
  import { useState, useEffect, useCallback, useMemo } from 'react';
68
68
  import type { SupabaseClient } from '@supabase/supabase-js';
69
69
  import type { Database } from '../../types/database';
70
+ import { createLogger } from '../../utils/core/logger';
71
+
72
+ const log = createLogger('usePublicEventLogo');
70
73
 
71
74
  // Simple in-memory cache for public data
72
75
  const publicDataCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
@@ -155,7 +158,7 @@ export function usePublicEventLogo(
155
158
  // Validate UUID format for organisationId to prevent database errors
156
159
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
157
160
  if (!uuidRegex.test(organisationId)) {
158
- console.warn('[usePublicEventLogo] Invalid organisationId format (not a valid UUID):', organisationId);
161
+ log.warn('Invalid organisationId format (not a valid UUID):', organisationId);
159
162
  // Don't return early - let the database handle the validation
160
163
  // This allows for more graceful error handling
161
164
  }
@@ -198,12 +201,12 @@ export function usePublicEventLogo(
198
201
  try {
199
202
  const response = await fetch(logoUrl, { method: 'HEAD' });
200
203
  if (!response.ok) {
201
- console.warn('[usePublicEventLogo] Logo URL not accessible:', logoUrl);
204
+ log.warn('Logo URL not accessible:', logoUrl);
202
205
  setLogoUrl(null);
203
206
  return;
204
207
  }
205
208
  } catch (fetchError) {
206
- console.warn('[usePublicEventLogo] Error validating logo URL:', fetchError);
209
+ log.warn('Error validating logo URL:', fetchError);
207
210
  setLogoUrl(null);
208
211
  return;
209
212
  }
@@ -221,7 +224,7 @@ export function usePublicEventLogo(
221
224
  }
222
225
 
223
226
  } catch (err) {
224
- console.error('[usePublicEventLogo] Error fetching logo:', err);
227
+ log.error('Error fetching logo:', err);
225
228
  const error = err instanceof Error ? err : new Error('Unknown error occurred');
226
229
  setError(error);
227
230
  setLogoUrl(null);
@@ -36,11 +36,12 @@
36
36
  * ```
37
37
  */
38
38
 
39
- import { useState, useEffect, useCallback, useMemo } from 'react';
39
+ import { useState, useEffect, useCallback } from 'react';
40
40
  import type { SupabaseClient } from '@supabase/supabase-js';
41
41
  import type { Database } from '../../types/database';
42
42
  import { FileReference, FileCategory } from '../../types/file-reference';
43
43
  import { getPublicUrl } from '../../utils/storage/helpers';
44
+ import { logger } from '../../utils/core/logger';
44
45
 
45
46
  // Simple in-memory cache for public file data
46
47
  const publicFileCache = new Map<string, { data: any; timestamp: number; ttl: number }>();
@@ -121,7 +122,7 @@ export function usePublicFileDisplay(
121
122
  // Validate UUID format for organisationId to prevent database errors
122
123
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
123
124
  if (!uuidRegex.test(organisation_id)) {
124
- console.warn('[usePublicFileDisplay] Invalid organisationId format (not a valid UUID):', organisation_id);
125
+ logger.warn('usePublicFileDisplay', 'Invalid organisationId format (not a valid UUID)', { organisation_id });
125
126
  }
126
127
 
127
128
  // Check cache first
@@ -158,53 +159,11 @@ export function usePublicFileDisplay(
158
159
  p_organisation_id: organisation_id
159
160
  };
160
161
 
161
- // Step 1: Log RPC call parameters with full context
162
- console.log('[usePublicFileDisplay] RPC Call Parameters:', {
163
- function: 'data_file_reference_by_category_list',
164
- parameters: rpcParams,
165
- supabaseClient: {
166
- available: !!supabase,
167
- hasAuth: !!supabase?.auth
168
- },
169
- context: 'public_page_anonymous_user',
170
- note: 'Public pages use anonymous Supabase client (no user session)'
171
- });
172
-
173
- console.log('[usePublicFileDisplay] Using RPC function for category filtering:', {
174
- table_name,
175
- record_id,
176
- category,
177
- organisation_id
178
- });
179
-
180
162
  const { data, error: rpcError } = await (supabase as any)
181
163
  .rpc('data_file_reference_by_category_list', rpcParams);
182
164
 
183
- // Step 2: Log RPC response immediately after call
184
- console.log('[usePublicFileDisplay] RPC Response:', {
185
- function: 'data_file_reference_by_category_list',
186
- dataType: Array.isArray(data) ? 'array' : typeof data,
187
- dataLength: Array.isArray(data) ? data.length : (data ? 1 : 0),
188
- dataIsNull: data === null,
189
- dataIsUndefined: data === undefined,
190
- dataIsEmpty: Array.isArray(data) ? data.length === 0 : !data,
191
- firstItem: Array.isArray(data) && data.length > 0 ? {
192
- id: data[0].id,
193
- file_path: data[0].file_path,
194
- is_public: data[0].is_public,
195
- has_metadata: !!data[0].file_metadata,
196
- category_in_metadata: data[0].file_metadata?.category
197
- } : null,
198
- error: rpcError ? {
199
- message: rpcError.message,
200
- code: rpcError.code,
201
- details: rpcError.details,
202
- hint: rpcError.hint
203
- } : null
204
- });
205
-
206
165
  if (rpcError) {
207
- console.error('[usePublicFileDisplay] RPC function error:', {
166
+ logger.error('usePublicFileDisplay', 'RPC function error', {
208
167
  function: 'data_file_reference_by_category_list',
209
168
  table_name,
210
169
  record_id,
@@ -224,28 +183,6 @@ export function usePublicFileDisplay(
224
183
  if (!data || data.length === 0) {
225
184
  files = [];
226
185
  } else {
227
- // Step 3: Log data transformation - analyze files before filtering
228
- const totalFilesFromRPC = data.length;
229
- const filesWithIsPublic = data.filter((item: any) => item.is_public === true).length;
230
- const filesWithIsPublicFalse = data.filter((item: any) => item.is_public === false).length;
231
- const filesWithIsPublicNull = data.filter((item: any) => item.is_public === null || item.is_public === undefined).length;
232
- const filesWithValidStructure = data.filter((item: any) => item.id && item.file_path && item.file_metadata).length;
233
-
234
- console.log('[usePublicFileDisplay] RPC Data Analysis (before filtering):', {
235
- totalFilesFromRPC,
236
- filesWithIsPublicTrue: filesWithIsPublic,
237
- filesWithIsPublicFalse,
238
- filesWithIsPublicNull,
239
- filesWithValidStructure,
240
- sampleItems: data.slice(0, 2).map((item: any) => ({
241
- id: item.id,
242
- is_public: item.is_public,
243
- has_id: !!item.id,
244
- has_file_path: !!item.file_path,
245
- has_metadata: !!item.file_metadata
246
- }))
247
- });
248
-
249
186
  // Construct file reference objects from RPC response
250
187
  // This avoids RLS issues - the RPC already validated permissions and filtered public files
251
188
  files = data
@@ -268,18 +205,6 @@ export function usePublicFileDisplay(
268
205
  updated_at: item.created_at || new Date().toISOString()
269
206
  };
270
207
  });
271
-
272
- // Step 3: Log after filtering
273
- console.log('[usePublicFileDisplay] Data Transformation (after filtering):', {
274
- filesBeforeFilter: totalFilesFromRPC,
275
- filesAfterFilter: files.length,
276
- constructedFileReferences: files.map(f => ({
277
- id: f.id,
278
- file_path: f.file_path,
279
- organisation_id: f.organisation_id,
280
- is_public: f.is_public
281
- }))
282
- });
283
208
  }
284
209
  } else {
285
210
  // Multiple files mode - use RPC to get all files
@@ -291,7 +216,7 @@ export function usePublicFileDisplay(
291
216
  });
292
217
 
293
218
  if (rpcError) {
294
- console.error('[usePublicFileDisplay] RPC function error:', {
219
+ logger.error('usePublicFileDisplay', 'RPC function error', {
295
220
  function: 'data_file_reference_list',
296
221
  table_name,
297
222
  record_id,
@@ -327,75 +252,6 @@ export function usePublicFileDisplay(
327
252
  const publicFiles = files.filter((f: any) => f.is_public === true);
328
253
 
329
254
  if (publicFiles.length === 0) {
330
- console.log('[usePublicFileDisplay] No public files found:', {
331
- table_name,
332
- record_id,
333
- category,
334
- organisation_id,
335
- totalFilesFound: files.length,
336
- note: 'This is expected if no public files exist. Fallback UI will be shown if showFallback is enabled.'
337
- });
338
-
339
- // Step 5: Add database query verification (for debugging only)
340
- // This helps determine if files exist but RPC is filtering them out
341
- try {
342
- console.log('[usePublicFileDisplay] Database Query Verification (debugging):', {
343
- note: 'Performing direct query to verify if files exist in database',
344
- table_name,
345
- record_id,
346
- organisation_id,
347
- category
348
- });
349
-
350
- // Direct query to check if any files exist (regardless of is_public)
351
- const { data: directQueryData, error: directQueryError } = await supabase
352
- .from('file_references')
353
- .select('id, file_path, file_metadata, is_public, organisation_id')
354
- .eq('table_name', table_name)
355
- .eq('record_id', record_id)
356
- .eq('organisation_id', organisation_id);
357
-
358
- if (directQueryError) {
359
- console.warn('[usePublicFileDisplay] Direct query error (RLS may be blocking):', {
360
- error: directQueryError.message,
361
- code: directQueryError.code,
362
- hint: 'This is expected if RLS policies block anonymous access to file_references table'
363
- });
364
- } else {
365
- const totalFilesInDB = directQueryData?.length || 0;
366
- const publicFilesInDB = directQueryData?.filter((f: any) => f.is_public === true).length || 0;
367
- const privateFilesInDB = directQueryData?.filter((f: any) => f.is_public === false).length || 0;
368
- const filesWithCategory = category ? directQueryData?.filter((f: any) =>
369
- f.file_metadata?.category === category
370
- ).length || 0 : totalFilesInDB;
371
-
372
- console.log('[usePublicFileDisplay] Database Query Results:', {
373
- totalFilesInDB,
374
- publicFilesInDB,
375
- privateFilesInDB,
376
- filesWithCategory: category ? filesWithCategory : 'N/A (no category filter)',
377
- filesWithMatchingCategoryAndPublic: category ? directQueryData?.filter((f: any) =>
378
- f.is_public === true && f.file_metadata?.category === category
379
- ).length || 0 : 'N/A',
380
- sampleFiles: directQueryData?.slice(0, 2).map((f: any) => ({
381
- id: f.id,
382
- is_public: f.is_public,
383
- category: f.file_metadata?.category,
384
- organisation_id: f.organisation_id
385
- })) || [],
386
- conclusion: totalFilesInDB === 0
387
- ? 'No files exist in database for this record'
388
- : publicFilesInDB === 0
389
- ? 'Files exist but none are marked as public (is_public = true)'
390
- : filesWithCategory === 0 && category
391
- ? `Files exist but none match category "${category}"`
392
- : 'Files exist and should be accessible - RPC function may be filtering them out'
393
- });
394
- }
395
- } catch (debugError) {
396
- console.warn('[usePublicFileDisplay] Database verification query failed:', debugError);
397
- }
398
-
399
255
  setFileUrl(null);
400
256
  setFileReference(null);
401
257
  setFileReferences([]);
@@ -477,7 +333,7 @@ export function usePublicFileDisplay(
477
333
  }
478
334
 
479
335
  } catch (err) {
480
- console.error('[usePublicFileDisplay] Error fetching files:', {
336
+ logger.error('usePublicFileDisplay', 'Error fetching files', {
481
337
  table_name,
482
338
  record_id,
483
339
  organisation_id,
@@ -1,5 +1,8 @@
1
1
 
2
2
  import { useEffect, useRef } from 'react';
3
+ import { createLogger } from '../utils/core/logger';
4
+
5
+ const log = createLogger('useComponentPerformance');
3
6
 
4
7
  interface PerformanceConfig {
5
8
  componentName: string;
@@ -23,7 +26,7 @@ export function useComponentPerformance({
23
26
  renderCount.current += 1;
24
27
 
25
28
  if (renderCount.current > 1 && renderTime > threshold) {
26
- console.warn(
29
+ log.warn(
27
30
  `Performance warning: ${componentName} rendered in ${renderTime.toFixed(2)}ms ` +
28
31
  `(render #${renderCount.current}). Consider optimizing.`
29
32
  );