@jmruthers/pace-core 0.5.184 → 0.5.186

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 (319) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +60 -1
  3. package/core-usage-manifest.json +312 -0
  4. package/dist/{DataTable-QAB34V6K.js → DataTable-IX2NBUTP.js} +6 -6
  5. package/dist/{DataTable-Bz8ffqyA.d.ts → DataTable-Z9NLVJh0.d.ts} +1 -1
  6. package/dist/{index-Bl--n7-T.d.ts → PublicPageProvider-DIzEzwKl.d.ts} +23 -10
  7. package/dist/{UnifiedAuthProvider-7F6T4B6K.js → UnifiedAuthProvider-A4BCQRJY.js} +4 -2
  8. package/dist/{UnifiedAuthProvider-F86d7dSi.d.ts → UnifiedAuthProvider-BG0AL5eE.d.ts} +2 -1
  9. package/dist/{api-ROMBCNKU.js → api-BMFCXVQX.js} +2 -2
  10. package/dist/{chunk-RA3JUFMW.js → chunk-445GEP27.js} +154 -4
  11. package/dist/{chunk-RA3JUFMW.js.map → chunk-445GEP27.js.map} +1 -1
  12. package/dist/{chunk-W22JP75J.js → chunk-DAGICKHT.js} +9 -7
  13. package/dist/chunk-DAGICKHT.js.map +1 -0
  14. package/dist/{chunk-FUEYYMX5.js → chunk-FXFJRTKI.js} +24 -3
  15. package/dist/chunk-FXFJRTKI.js.map +1 -0
  16. package/dist/{chunk-CSOFYHAG.js → chunk-GRIQLQ52.js} +374 -60
  17. package/dist/chunk-GRIQLQ52.js.map +1 -0
  18. package/dist/{chunk-NQPMQGS2.js → chunk-HDCUMOOI.js} +497 -399
  19. package/dist/chunk-HDCUMOOI.js.map +1 -0
  20. package/dist/chunk-HESYZWZW.js +388 -0
  21. package/dist/chunk-HESYZWZW.js.map +1 -0
  22. package/dist/{chunk-QUVSNGIP.js → chunk-HGPQUCBC.js} +34 -9
  23. package/dist/{chunk-QUVSNGIP.js.map → chunk-HGPQUCBC.js.map} +1 -1
  24. package/dist/{chunk-PWAHJW4G.js → chunk-OALXJH4Y.js} +86 -33
  25. package/dist/chunk-OALXJH4Y.js.map +1 -0
  26. package/dist/{chunk-MI7HBHN3.js → chunk-TC7D3CR3.js} +89 -9
  27. package/dist/chunk-TC7D3CR3.js.map +1 -0
  28. package/dist/chunk-THRPYOFK.js +215 -0
  29. package/dist/chunk-THRPYOFK.js.map +1 -0
  30. package/dist/{chunk-M7W4CP3M.js → chunk-U6WNSFX5.js} +2 -1
  31. package/dist/chunk-U6WNSFX5.js.map +1 -0
  32. package/dist/{chunk-UHNYIBXL.js → chunk-UQWSHFVX.js} +1 -1
  33. package/dist/chunk-UQWSHFVX.js.map +1 -0
  34. package/dist/{chunk-QCDXODCA.js → chunk-XAUHJD3L.js} +2 -2
  35. package/dist/components.d.ts +182 -6
  36. package/dist/components.js +157 -11
  37. package/dist/components.js.map +1 -1
  38. package/dist/{database.generated-CBmg2950.d.ts → database.generated-DI89OQeI.d.ts} +63 -9
  39. package/dist/eslint-rules/pace-core-compliance.cjs +406 -0
  40. package/dist/{file-reference-D06mEEWW.d.ts → file-reference-PRTSLxKx.d.ts} +10 -1
  41. package/dist/hooks.d.ts +52 -15
  42. package/dist/hooks.js +12 -22
  43. package/dist/hooks.js.map +1 -1
  44. package/dist/index.d.ts +12 -12
  45. package/dist/index.js +82 -18
  46. package/dist/index.js.map +1 -1
  47. package/dist/providers.d.ts +1 -1
  48. package/dist/providers.js +3 -1
  49. package/dist/rbac/index.d.ts +206 -15
  50. package/dist/rbac/index.js +28 -6
  51. package/dist/timezone-_pgH8qrY.d.ts +530 -0
  52. package/dist/{types-_x1f4QBF.d.ts → types-DUyCRSTj.d.ts} +1 -1
  53. package/dist/types.d.ts +2 -2
  54. package/dist/types.js +1 -1
  55. package/dist/{usePublicRouteParams-JJczomYq.d.ts → usePublicRouteParams-D71QLlg4.d.ts} +114 -3
  56. package/dist/utils.d.ts +110 -152
  57. package/dist/utils.js +128 -138
  58. package/dist/utils.js.map +1 -1
  59. package/docs/api/README.md +60 -1
  60. package/docs/api/classes/ColumnFactory.md +1 -1
  61. package/docs/api/classes/ErrorBoundary.md +1 -1
  62. package/docs/api/classes/InvalidScopeError.md +1 -1
  63. package/docs/api/classes/Logger.md +178 -0
  64. package/docs/api/classes/MissingUserContextError.md +1 -1
  65. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  66. package/docs/api/classes/PermissionDeniedError.md +1 -1
  67. package/docs/api/classes/RBACAuditManager.md +2 -2
  68. package/docs/api/classes/RBACCache.md +1 -1
  69. package/docs/api/classes/RBACEngine.md +2 -2
  70. package/docs/api/classes/RBACError.md +1 -1
  71. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  72. package/docs/api/classes/SecureSupabaseClient.md +5 -5
  73. package/docs/api/classes/StorageUtils.md +1 -1
  74. package/docs/api/enums/FileCategory.md +1 -1
  75. package/docs/api/enums/LogLevel.md +54 -0
  76. package/docs/api/enums/RBACErrorCode.md +1 -1
  77. package/docs/api/enums/RPCFunction.md +1 -1
  78. package/docs/api/interfaces/AggregateConfig.md +1 -1
  79. package/docs/api/interfaces/BadgeProps.md +1 -1
  80. package/docs/api/interfaces/ButtonProps.md +1 -1
  81. package/docs/api/interfaces/CalendarProps.md +18 -2
  82. package/docs/api/interfaces/CardProps.md +1 -1
  83. package/docs/api/interfaces/ColorPalette.md +1 -1
  84. package/docs/api/interfaces/ColorShade.md +1 -1
  85. package/docs/api/interfaces/ComplianceResult.md +30 -0
  86. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  87. package/docs/api/interfaces/DataRecord.md +1 -1
  88. package/docs/api/interfaces/DataTableAction.md +1 -1
  89. package/docs/api/interfaces/DataTableColumn.md +1 -1
  90. package/docs/api/interfaces/DataTableProps.md +1 -1
  91. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  92. package/docs/api/interfaces/DatabaseComplianceResult.md +85 -0
  93. package/docs/api/interfaces/DatabaseIssue.md +41 -0
  94. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  95. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  96. package/docs/api/interfaces/EventAppRoleData.md +6 -6
  97. package/docs/api/interfaces/ExportColumn.md +1 -1
  98. package/docs/api/interfaces/ExportOptions.md +1 -1
  99. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  100. package/docs/api/interfaces/FileMetadata.md +1 -1
  101. package/docs/api/interfaces/FileReference.md +1 -1
  102. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  103. package/docs/api/interfaces/FileUploadOptions.md +48 -8
  104. package/docs/api/interfaces/FileUploadProps.md +46 -13
  105. package/docs/api/interfaces/FooterProps.md +1 -1
  106. package/docs/api/interfaces/FormFieldProps.md +1 -1
  107. package/docs/api/interfaces/FormProps.md +1 -1
  108. package/docs/api/interfaces/GrantEventAppRoleParams.md +9 -9
  109. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  110. package/docs/api/interfaces/InputProps.md +1 -1
  111. package/docs/api/interfaces/LabelProps.md +1 -1
  112. package/docs/api/interfaces/LoggerConfig.md +62 -0
  113. package/docs/api/interfaces/LoginFormProps.md +1 -1
  114. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  115. package/docs/api/interfaces/NavigationContextType.md +1 -1
  116. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  117. package/docs/api/interfaces/NavigationItem.md +1 -1
  118. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  119. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  120. package/docs/api/interfaces/Organisation.md +1 -1
  121. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  122. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  123. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  124. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  125. package/docs/api/interfaces/PaceAppLayoutProps.md +36 -23
  126. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  127. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  128. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  129. package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
  130. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  131. package/docs/api/interfaces/PaletteData.md +1 -1
  132. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  133. package/docs/api/interfaces/ProgressProps.md +1 -1
  134. package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
  135. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  136. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  137. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  138. package/docs/api/interfaces/QuickFix.md +52 -0
  139. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  140. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  141. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  142. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  143. package/docs/api/interfaces/RBACConfig.md +4 -4
  144. package/docs/api/interfaces/RBACContext.md +1 -1
  145. package/docs/api/interfaces/RBACLogger.md +1 -1
  146. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  147. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  148. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  149. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  150. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  151. package/docs/api/interfaces/RBACResult.md +1 -1
  152. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  153. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  154. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  155. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  156. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  157. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  158. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  159. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  160. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  161. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  162. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  163. package/docs/api/interfaces/RevokeEventAppRoleParams.md +7 -7
  164. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  165. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  166. package/docs/api/interfaces/RoleManagementResult.md +5 -5
  167. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  168. package/docs/api/interfaces/RouteConfig.md +1 -1
  169. package/docs/api/interfaces/RuntimeComplianceResult.md +55 -0
  170. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  171. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  172. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  173. package/docs/api/interfaces/SetupIssue.md +41 -0
  174. package/docs/api/interfaces/StorageConfig.md +1 -1
  175. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  176. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  177. package/docs/api/interfaces/StorageListOptions.md +1 -1
  178. package/docs/api/interfaces/StorageListResult.md +1 -1
  179. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  180. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  181. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  182. package/docs/api/interfaces/StyleImport.md +1 -1
  183. package/docs/api/interfaces/SwitchProps.md +1 -1
  184. package/docs/api/interfaces/TabsContentProps.md +1 -1
  185. package/docs/api/interfaces/TabsListProps.md +1 -1
  186. package/docs/api/interfaces/TabsProps.md +1 -1
  187. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  188. package/docs/api/interfaces/TextareaProps.md +1 -1
  189. package/docs/api/interfaces/ToastActionElement.md +1 -1
  190. package/docs/api/interfaces/ToastProps.md +1 -1
  191. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  192. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  193. package/docs/api/interfaces/UseFormDialogOptions.md +62 -0
  194. package/docs/api/interfaces/UseFormDialogReturn.md +117 -0
  195. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  196. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  197. package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
  198. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  199. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  200. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  201. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  202. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  203. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  204. package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
  205. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  206. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  207. package/docs/api/interfaces/UserEventAccess.md +1 -1
  208. package/docs/api/interfaces/UserMenuProps.md +1 -1
  209. package/docs/api/interfaces/UserProfile.md +1 -1
  210. package/docs/api/modules.md +746 -50
  211. package/docs/api-reference/components.md +26 -12
  212. package/docs/api-reference/hooks.md +111 -0
  213. package/docs/api-reference/rpc-functions.md +1 -1
  214. package/docs/api-reference/utilities.md +184 -0
  215. package/docs/getting-started/installation-guide.md +75 -16
  216. package/docs/getting-started/quick-start.md +61 -11
  217. package/docs/implementation-guides/authentication.md +88 -12
  218. package/docs/implementation-guides/file-reference-system.md +26 -3
  219. package/docs/implementation-guides/file-upload-storage.md +30 -1
  220. package/docs/rbac/README.md +1 -0
  221. package/docs/rbac/compliance/compliance-guide.md +544 -0
  222. package/docs/rbac/getting-started.md +158 -33
  223. package/docs/standards/pace-core-compliance.md +432 -0
  224. package/eslint-config-pace-core.cjs +93 -0
  225. package/package.json +15 -3
  226. package/scripts/analyze-bundle.js +232 -0
  227. package/scripts/build-css.js +56 -0
  228. package/scripts/build-docs-incremental.js +1015 -0
  229. package/scripts/check-pace-core-compliance.cjs +2353 -0
  230. package/scripts/check-pace-core-compliance.js +512 -0
  231. package/scripts/generate-docs.js +157 -0
  232. package/scripts/setup-build-cache.js +73 -0
  233. package/scripts/utils/command-runner.js +131 -0
  234. package/scripts/utils/env.js +33 -0
  235. package/scripts/utils/index.js +10 -0
  236. package/scripts/utils/logger.js +88 -0
  237. package/scripts/utils/path-helpers.js +37 -0
  238. package/scripts/validate-formats.js +133 -0
  239. package/scripts/validate-master.js +155 -0
  240. package/scripts/validate-pre-publish.js +140 -0
  241. package/scripts/validate-theme.js +142 -0
  242. package/src/components/Calendar/Calendar.tsx +8 -1
  243. package/src/components/Card/Card.tsx +47 -8
  244. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +314 -0
  245. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +126 -0
  246. package/src/components/DatePickerWithTimezone/README.md +135 -0
  247. package/src/components/DatePickerWithTimezone/index.ts +10 -0
  248. package/src/components/DateTimeField/DateTimeField.test.tsx +358 -0
  249. package/src/components/DateTimeField/DateTimeField.tsx +232 -0
  250. package/src/components/DateTimeField/README.md +148 -0
  251. package/src/components/DateTimeField/index.ts +10 -0
  252. package/src/components/FileUpload/FileUpload.test.tsx +2 -0
  253. package/src/components/FileUpload/FileUpload.tsx +10 -1
  254. package/src/components/Header/Header.test.tsx +47 -18
  255. package/src/components/Header/Header.tsx +22 -7
  256. package/src/components/PaceAppLayout/PaceAppLayout.tsx +29 -20
  257. package/src/components/PaceAppLayout/README.md +9 -0
  258. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +37 -8
  259. package/src/components/ProtectedRoute/ProtectedRoute.tsx +146 -5
  260. package/src/components/index.ts +8 -0
  261. package/src/eslint-rules/pace-core-compliance.cjs +406 -0
  262. package/src/eslint-rules/pace-core-compliance.js +640 -0
  263. package/src/hooks/__tests__/useFormDialog.test.ts +478 -0
  264. package/src/hooks/index.ts +5 -0
  265. package/src/hooks/useFileReference.test.ts +2 -0
  266. package/src/hooks/useFormDialog.ts +147 -0
  267. package/src/hooks/usePreventTabReload.ts +106 -0
  268. package/src/hooks/useSecureDataAccess.ts +2 -2
  269. package/src/index.ts +27 -0
  270. package/src/providers/services/OrganisationServiceProvider.tsx +6 -5
  271. package/src/providers/services/UnifiedAuthProvider.tsx +24 -3
  272. package/src/rbac/__tests__/rbac-role-isolation.test.ts +456 -0
  273. package/src/rbac/__tests__/scenarios.user-role.test.tsx +3 -0
  274. package/src/rbac/compliance/database-validator.ts +165 -0
  275. package/src/rbac/compliance/index.ts +38 -0
  276. package/src/rbac/compliance/quick-fix-suggestions.ts +209 -0
  277. package/src/rbac/compliance/runtime-compliance.ts +77 -0
  278. package/src/rbac/compliance/setup-validator.ts +131 -0
  279. package/src/rbac/components/PagePermissionGuard.tsx +8 -64
  280. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +35 -21
  281. package/src/rbac/docs/event-based-apps.md +285 -0
  282. package/src/rbac/errors.ts +11 -0
  283. package/src/rbac/hooks/useRoleManagement.ts +292 -12
  284. package/src/rbac/index.ts +30 -0
  285. package/src/services/OrganisationService.ts +4 -0
  286. package/src/styles/core.css +5 -5
  287. package/src/types/database.generated.ts +63 -9
  288. package/src/types/file-reference.ts +9 -0
  289. package/src/utils/__tests__/timezone.test.ts +345 -0
  290. package/src/utils/file-reference/__tests__/file-reference.test.ts +60 -4
  291. package/src/utils/file-reference/index.ts +13 -2
  292. package/src/utils/formatting/formatDateTimeTimezone.test.ts +167 -0
  293. package/src/utils/formatting/formatting.ts +179 -0
  294. package/src/utils/index.ts +27 -1
  295. package/src/utils/location/index.ts +16 -0
  296. package/src/utils/location/location.test.ts +286 -0
  297. package/src/utils/location/location.ts +175 -0
  298. package/src/utils/security/secureDataAccess.ts +1 -1
  299. package/src/utils/storage/helpers.ts +68 -0
  300. package/src/utils/timezone/index.ts +17 -0
  301. package/src/utils/timezone/timezone.test.ts +349 -0
  302. package/src/utils/timezone/timezone.ts +281 -0
  303. package/dist/chunk-CSOFYHAG.js.map +0 -1
  304. package/dist/chunk-FUEYYMX5.js.map +0 -1
  305. package/dist/chunk-HKIT6O7W.js +0 -198
  306. package/dist/chunk-HKIT6O7W.js.map +0 -1
  307. package/dist/chunk-KUEN3HFB.js +0 -94
  308. package/dist/chunk-KUEN3HFB.js.map +0 -1
  309. package/dist/chunk-M7W4CP3M.js.map +0 -1
  310. package/dist/chunk-MI7HBHN3.js.map +0 -1
  311. package/dist/chunk-NQPMQGS2.js.map +0 -1
  312. package/dist/chunk-PWAHJW4G.js.map +0 -1
  313. package/dist/chunk-UHNYIBXL.js.map +0 -1
  314. package/dist/chunk-W22JP75J.js.map +0 -1
  315. package/dist/formatting-5wETwiGF.d.ts +0 -162
  316. /package/dist/{DataTable-QAB34V6K.js.map → DataTable-IX2NBUTP.js.map} +0 -0
  317. /package/dist/{UnifiedAuthProvider-7F6T4B6K.js.map → UnifiedAuthProvider-A4BCQRJY.js.map} +0 -0
  318. /package/dist/{api-ROMBCNKU.js.map → api-BMFCXVQX.js.map} +0 -0
  319. /package/dist/{chunk-QCDXODCA.js.map → chunk-XAUHJD3L.js.map} +0 -0
@@ -0,0 +1,106 @@
1
+ /**
2
+ * @file usePreventTabReload Hook
3
+ * @package @jmruthers/pace-core
4
+ * @module Hooks
5
+ * @since 0.6.0
6
+ *
7
+ * Prevents full page reloads when switching browser tabs.
8
+ * Handles browser back-forward cache (bfcache) restoration and tab visibility changes.
9
+ */
10
+
11
+ import { useEffect, useRef } from 'react';
12
+
13
+ export interface UsePreventTabReloadOptions {
14
+ /**
15
+ * Whether to enable the prevention logic
16
+ * @default true
17
+ */
18
+ enabled?: boolean;
19
+
20
+ /**
21
+ * Grace period in milliseconds to wait after tab becomes visible
22
+ * before allowing any potential reloads
23
+ * @default 2000
24
+ */
25
+ gracePeriodMs?: number;
26
+ }
27
+
28
+ /**
29
+ * Hook to prevent full page reloads when switching browser tabs.
30
+ *
31
+ * This hook handles:
32
+ * - Browser back-forward cache (bfcache) restoration
33
+ * - Tab visibility changes
34
+ * - Prevents unwanted page reloads when returning to a tab
35
+ *
36
+ * @param options - Configuration options
37
+ *
38
+ * @example
39
+ * ```tsx
40
+ * import { usePreventTabReload } from '@jmruthers/pace-core';
41
+ *
42
+ * function MyComponent() {
43
+ * usePreventTabReload();
44
+ * // Component code...
45
+ * }
46
+ * ```
47
+ */
48
+ export function usePreventTabReload(options: UsePreventTabReloadOptions = {}): void {
49
+ const { enabled = true, gracePeriodMs = 2000 } = options;
50
+ const isRestoringFromCacheRef = useRef(false);
51
+ const gracePeriodTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
52
+
53
+ useEffect(() => {
54
+ if (!enabled || typeof window === 'undefined') return;
55
+
56
+ // Handle pageshow event - detects when page is restored from bfcache
57
+ const handlePageShow = (event: PageTransitionEvent) => {
58
+ // If page was restored from bfcache, prevent any reload behavior
59
+ if (event.persisted) {
60
+ isRestoringFromCacheRef.current = true;
61
+
62
+ // Clear any existing timeout
63
+ if (gracePeriodTimeoutRef.current) {
64
+ clearTimeout(gracePeriodTimeoutRef.current);
65
+ }
66
+
67
+ // Set grace period to prevent reloads
68
+ gracePeriodTimeoutRef.current = setTimeout(() => {
69
+ isRestoringFromCacheRef.current = false;
70
+ }, gracePeriodMs);
71
+ }
72
+ };
73
+
74
+ // Handle visibility changes - when tab becomes visible
75
+ const handleVisibilityChange = () => {
76
+ if (!document.hidden) {
77
+ // Tab just became visible - set flag to prevent reloads
78
+ isRestoringFromCacheRef.current = true;
79
+
80
+ // Clear any existing timeout
81
+ if (gracePeriodTimeoutRef.current) {
82
+ clearTimeout(gracePeriodTimeoutRef.current);
83
+ }
84
+
85
+ // Set grace period
86
+ gracePeriodTimeoutRef.current = setTimeout(() => {
87
+ isRestoringFromCacheRef.current = false;
88
+ }, gracePeriodMs);
89
+ }
90
+ };
91
+
92
+ // Add event listeners
93
+ window.addEventListener('pageshow', handlePageShow);
94
+ document.addEventListener('visibilitychange', handleVisibilityChange);
95
+
96
+ return () => {
97
+ window.removeEventListener('pageshow', handlePageShow);
98
+ document.removeEventListener('visibilitychange', handleVisibilityChange);
99
+
100
+ if (gracePeriodTimeoutRef.current) {
101
+ clearTimeout(gracePeriodTimeoutRef.current);
102
+ }
103
+ };
104
+ }, [enabled, gracePeriodMs]);
105
+ }
106
+
@@ -219,7 +219,7 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
219
219
  'cake_meal', 'cake_mealtype', 'pace_person', 'pace_member',
220
220
  // SECURITY: Phase 3A additions - medical and personal data
221
221
  'medi_profile', 'medi_condition', 'medi_diet', 'medi_action_plan', 'medi_profile_versions',
222
- 'pace_consent', 'pace_contact', 'pace_id_documents', 'pace_qualifications',
222
+ 'pace_consent', 'pace_contact', 'pace_identification', 'pace_identification_type', 'pace_qualification',
223
223
  'form_responses', 'form_response_values', 'forms',
224
224
  // SECURITY: Phase 3B additions - remaining critical tables
225
225
  'invoice', 'line_item', 'credit_balance', 'payment_method',
@@ -379,7 +379,7 @@ export function useSecureDataAccess(): SecureDataAccessReturn {
379
379
  'cake_meal', 'cake_mealtype', 'pace_person', 'pace_member',
380
380
  // SECURITY: Phase 3A additions - medical and personal data
381
381
  'medi_profile', 'medi_condition', 'medi_diet', 'medi_action_plan', 'medi_profile_versions',
382
- 'pace_consent', 'pace_contact', 'pace_id_documents', 'pace_qualifications',
382
+ 'pace_consent', 'pace_contact', 'pace_identification', 'pace_identification_type', 'pace_qualification',
383
383
  'form_responses', 'form_response_values', 'forms',
384
384
  // SECURITY: Phase 3B additions - remaining critical tables
385
385
  'invoice', 'line_item', 'credit_balance', 'payment_method',
package/src/index.ts CHANGED
@@ -189,6 +189,17 @@ export type { FormProps, FormFieldProps } from './components/Form/Form';
189
189
  export { LoginForm } from './components/LoginForm';
190
190
  export type { LoginFormProps } from './components/LoginForm';
191
191
 
192
+ // FORM HOOKS
193
+ export { useZodForm } from './hooks/useZodForm';
194
+ export { useFormDialog } from './hooks/useFormDialog';
195
+ export type { UseFormDialogOptions, UseFormDialogReturn } from './hooks/useFormDialog';
196
+
197
+ // VALIDATION - Re-export zod for schema creation
198
+ export { z } from 'zod';
199
+ // Common validation schemas
200
+ export { emailSchema, nameSchema, phoneSchema, urlSchema } from './utils/validation/common';
201
+ export { passwordSchema } from './utils/validation/passwordSchema';
202
+
192
203
  // LAYOUT COMPONENTS
193
204
  export { Header } from './components/Header/Header';
194
205
  export { Footer } from './components/Footer/Footer';
@@ -236,6 +247,10 @@ export { useEventTheme } from './hooks/useEventTheme';
236
247
  export { cn } from './utils/core/cn';
237
248
  export { setAppConfig, getAppConfig, getCurrentAppName, getCurrentAppId } from './utils/app/appConfig';
238
249
 
250
+ // LOGGING UTILITIES
251
+ export { Logger, logger, createLogger, LogLevel } from './utils/core/logger';
252
+ export type { LoggerConfig } from './utils/core/logger';
253
+
239
254
  // FORMATTING UTILITIES
240
255
  export {
241
256
  formatDate,
@@ -248,6 +263,18 @@ export {
248
263
  formatFileSize
249
264
  } from './utils/formatting/formatting';
250
265
 
266
+ // TIMEZONE UTILITIES
267
+ export {
268
+ formatInTimeZone,
269
+ getTimezoneAbbreviation,
270
+ formatTimeInTimeZone,
271
+ getUserTimeZone,
272
+ toZonedTime,
273
+ fromZonedTime,
274
+ roundToNearestMinutes,
275
+ getTimeZoneDifference
276
+ } from './utils/timezone';
277
+
251
278
  // STORAGE UTILITIES
252
279
  export { FileUpload } from './components/FileUpload';
253
280
  export type { FileUploadProps } from './components/FileUpload';
@@ -49,11 +49,12 @@ export function OrganisationServiceProvider({
49
49
  // Re-initialize service when user/session changes
50
50
  let isMounted = true;
51
51
 
52
- organisationService.initialize().catch(error => {
53
- if (isMounted) {
54
- logger.error('OrganisationServiceProvider', 'Failed to initialize organisation service:', error);
55
- }
56
- });
52
+ organisationService.initialize()
53
+ .catch(error => {
54
+ if (isMounted) {
55
+ logger.error('OrganisationServiceProvider', 'Failed to initialize organisation service:', error);
56
+ }
57
+ });
57
58
 
58
59
  return () => {
59
60
  isMounted = false;
@@ -8,7 +8,7 @@
8
8
  * Note: RBAC functionality is available via useRBAC() hook from '@jmruthers/pace-core/rbac'
9
9
  */
10
10
 
11
- import React, { createContext, useContext, useMemo, useCallback, useRef, useEffect, useState } from 'react';
11
+ import React, { createContext, useContext, useMemo, useCallback, useRef, useEffect, useState, useReducer } from 'react';
12
12
  import { type SupabaseClient, type User, type Session } from '@supabase/supabase-js';
13
13
  import { AuthServiceProvider } from './AuthServiceProvider';
14
14
  import { OrganisationServiceProvider } from './OrganisationServiceProvider';
@@ -114,7 +114,7 @@ export interface UnifiedAuthContextType {
114
114
  sessionRestorationTimeoutMs: number;
115
115
  }
116
116
 
117
- const UnifiedAuthContext = createContext<UnifiedAuthContextType | undefined>(undefined);
117
+ export const UnifiedAuthContext = createContext<UnifiedAuthContextType | undefined>(undefined);
118
118
 
119
119
  export const useUnifiedAuth = () => {
120
120
  const context = useContext(UnifiedAuthContext);
@@ -179,13 +179,15 @@ function UnifiedAuthContextProvider({
179
179
  eventService = useEventService();
180
180
  } catch (error) {
181
181
  // EventService not available - provide fallback implementation
182
+ // Include subscribe method to match BaseService interface
182
183
  eventService = {
183
184
  getEvents: () => [],
184
185
  getSelectedEvent: () => null,
185
186
  isLoading: () => false,
186
187
  getError: () => null,
187
188
  setSelectedEvent: () => {},
188
- refreshEvents: async () => {}
189
+ refreshEvents: async () => {},
190
+ subscribe: () => () => {} // No-op subscribe/unsubscribe for fallback
189
191
  };
190
192
  }
191
193
 
@@ -256,6 +258,25 @@ function UnifiedAuthContextProvider({
256
258
  }
257
259
  }, [isAuth, currentUser?.id, supabase, appName, appId]);
258
260
 
261
+ // Subscribe to service state changes to trigger re-renders
262
+ // Use useReducer to force updates when services notify
263
+ const [, forceUpdate] = useReducer(x => x + 1, 0);
264
+
265
+ useEffect(() => {
266
+ // Subscribe to all service changes
267
+ const unsubscribeAuth = authService.subscribe(() => forceUpdate());
268
+ const unsubscribeOrg = organisationService.subscribe(() => forceUpdate());
269
+ const unsubscribeEvent = eventService.subscribe(() => forceUpdate());
270
+ const unsubscribeInactivity = inactivityService.subscribe(() => forceUpdate());
271
+
272
+ return () => {
273
+ unsubscribeAuth();
274
+ unsubscribeOrg();
275
+ unsubscribeEvent();
276
+ unsubscribeInactivity();
277
+ };
278
+ }, [authService, organisationService, eventService, inactivityService]);
279
+
259
280
  // Get loading states - these will trigger re-renders when services change
260
281
  const authLoading = authService.isLoading();
261
282
  const orgLoading = organisationService.isLoading();