@jmruthers/pace-core 0.5.74 → 0.5.76

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 (369) hide show
  1. package/dist/DataTable-4GAVPIEG.js +120 -0
  2. package/dist/{PublicLoadingSpinner-DLpF5bbs.d.ts → PublicLoadingSpinner-BiNER8F5.d.ts} +30 -19
  3. package/dist/RBACService-C4udt_Zp.d.ts +528 -0
  4. package/dist/{UnifiedAuthProvider-K4NRGXL4.js → UnifiedAuthProvider-3NKDOSOK.js} +6 -4
  5. package/dist/UnifiedAuthProvider-Bj6YCf7c.d.ts +113 -0
  6. package/dist/chunk-5F3NDPJV.js +232 -0
  7. package/dist/chunk-5F3NDPJV.js.map +1 -0
  8. package/dist/chunk-A4FUBC7B.js +17 -0
  9. package/dist/chunk-A4FUBC7B.js.map +1 -0
  10. package/dist/{chunk-SMJZMKYN.js → chunk-A6HBIY5P.js} +2 -11
  11. package/dist/{chunk-SMJZMKYN.js.map → chunk-A6HBIY5P.js.map} +1 -1
  12. package/dist/{chunk-LVQ26TCN.js → chunk-AFGTSUAD.js} +43 -127
  13. package/dist/chunk-AFGTSUAD.js.map +1 -0
  14. package/dist/{chunk-BKVGJVUR.js → chunk-K34IM5CT.js} +497 -33
  15. package/dist/chunk-K34IM5CT.js.map +1 -0
  16. package/dist/{chunk-UJMCGBLS.js → chunk-KHJS6VIA.js} +203 -41
  17. package/dist/chunk-KHJS6VIA.js.map +1 -0
  18. package/dist/{chunk-ORSMVXO2.js → chunk-KK73ZB4E.js} +9 -14
  19. package/dist/chunk-KK73ZB4E.js.map +1 -0
  20. package/dist/{chunk-VKOCWWVY.js → chunk-L3RV2ALE.js} +1 -6
  21. package/dist/{chunk-VKOCWWVY.js.map → chunk-L3RV2ALE.js.map} +1 -1
  22. package/dist/chunk-LW7MMEAQ.js +59 -0
  23. package/dist/chunk-LW7MMEAQ.js.map +1 -0
  24. package/dist/{chunk-IHMMNKNA.js → chunk-M5IWZRBT.js} +5118 -1864
  25. package/dist/chunk-M5IWZRBT.js.map +1 -0
  26. package/dist/{chunk-DG5Z55HH.js → chunk-NTNILOBC.js} +7 -9
  27. package/dist/chunk-NTNILOBC.js.map +1 -0
  28. package/dist/chunk-PYUXFQJ3.js +11 -0
  29. package/dist/chunk-PYUXFQJ3.js.map +1 -0
  30. package/dist/chunk-URUTVZ7N.js +27 -0
  31. package/dist/chunk-URUTVZ7N.js.map +1 -0
  32. package/dist/chunk-WN6XJWOS.js +2468 -0
  33. package/dist/chunk-WN6XJWOS.js.map +1 -0
  34. package/dist/{chunk-3SP4P7NS.js → chunk-XLZ7U46Z.js} +59 -1
  35. package/dist/chunk-XLZ7U46Z.js.map +1 -0
  36. package/dist/{chunk-H2TNUICK.js → chunk-Y6TXWPJO.js} +50 -50
  37. package/dist/chunk-Y6TXWPJO.js.map +1 -0
  38. package/dist/{chunk-YNUBMSMV.js → chunk-YCKPEMJA.js} +186 -263
  39. package/dist/chunk-YCKPEMJA.js.map +1 -0
  40. package/dist/components.d.ts +4 -5
  41. package/dist/components.js +35 -41
  42. package/dist/components.js.map +1 -1
  43. package/dist/hooks.d.ts +20 -43
  44. package/dist/hooks.js +13 -12
  45. package/dist/hooks.js.map +1 -1
  46. package/dist/index.d.ts +156 -10
  47. package/dist/index.js +193 -96
  48. package/dist/index.js.map +1 -1
  49. package/dist/{organisation-t-vvQC3g.d.ts → organisation-BtshODVF.d.ts} +4 -3
  50. package/dist/providers.d.ts +27 -38
  51. package/dist/providers.js +33 -23
  52. package/dist/rbac/index.d.ts +114 -5
  53. package/dist/rbac/index.js +15 -15
  54. package/dist/styles/index.js +2 -2
  55. package/dist/theming/runtime.js +1 -3
  56. package/dist/types.d.ts +3 -3
  57. package/dist/types.js +1 -1
  58. package/dist/types.js.map +1 -1
  59. package/dist/{unified-CMPjE_fv.d.ts → unified-CM7T0aTK.d.ts} +1 -1
  60. package/dist/useInactivityTracker-MRUU55XI.js +10 -0
  61. package/dist/{usePublicRouteParams-Ua1Vz-HG.d.ts → usePublicRouteParams-B-CumWRc.d.ts} +3 -3
  62. package/dist/utils.js +7 -9
  63. package/dist/utils.js.map +1 -1
  64. package/dist/validation.d.ts +1 -1
  65. package/docs/TERMINOLOGY.md +231 -0
  66. package/docs/api/classes/ColumnFactory.md +1 -1
  67. package/docs/api/classes/ErrorBoundary.md +1 -1
  68. package/docs/api/classes/InvalidScopeError.md +1 -1
  69. package/docs/api/classes/MissingUserContextError.md +1 -1
  70. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  71. package/docs/api/classes/PermissionDeniedError.md +1 -1
  72. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  73. package/docs/api/classes/RBACAuditManager.md +1 -1
  74. package/docs/api/classes/RBACCache.md +1 -1
  75. package/docs/api/classes/RBACEngine.md +1 -1
  76. package/docs/api/classes/RBACError.md +1 -1
  77. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  78. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  79. package/docs/api/classes/StorageUtils.md +1 -1
  80. package/docs/api/enums/FileCategory.md +1 -1
  81. package/docs/api/interfaces/AggregateConfig.md +1 -1
  82. package/docs/api/interfaces/ButtonProps.md +3 -3
  83. package/docs/api/interfaces/CardProps.md +2 -2
  84. package/docs/api/interfaces/ColorPalette.md +1 -1
  85. package/docs/api/interfaces/ColorShade.md +1 -1
  86. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  87. package/docs/api/interfaces/DataTableAction.md +1 -1
  88. package/docs/api/interfaces/DataTableColumn.md +1 -1
  89. package/docs/api/interfaces/DataTableProps.md +1 -1
  90. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  91. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  92. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  93. package/docs/api/interfaces/EventLogoProps.md +2 -2
  94. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  95. package/docs/api/interfaces/FileMetadata.md +1 -1
  96. package/docs/api/interfaces/FileReference.md +1 -1
  97. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  98. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  99. package/docs/api/interfaces/FileUploadProps.md +1 -1
  100. package/docs/api/interfaces/FooterProps.md +1 -1
  101. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  102. package/docs/api/interfaces/InputProps.md +2 -2
  103. package/docs/api/interfaces/LabelProps.md +1 -1
  104. package/docs/api/interfaces/LoginFormProps.md +1 -1
  105. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  106. package/docs/api/interfaces/NavigationContextType.md +1 -1
  107. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  108. package/docs/api/interfaces/NavigationItem.md +1 -1
  109. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  110. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  111. package/docs/api/interfaces/Organisation.md +1 -1
  112. package/docs/api/interfaces/OrganisationContextType.md +28 -17
  113. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  114. package/docs/api/interfaces/OrganisationProviderProps.md +2 -2
  115. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  116. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  117. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  118. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  119. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  120. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  121. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  122. package/docs/api/interfaces/PaletteData.md +1 -1
  123. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  124. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  125. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  126. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +2 -2
  127. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  128. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  129. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  130. package/docs/api/interfaces/RBACConfig.md +1 -1
  131. package/docs/api/interfaces/RBACContextType.md +5 -11
  132. package/docs/api/interfaces/RBACLogger.md +1 -1
  133. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  134. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  135. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  136. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  137. package/docs/api/interfaces/RouteConfig.md +1 -1
  138. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  139. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  140. package/docs/api/interfaces/StorageConfig.md +1 -1
  141. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  142. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  143. package/docs/api/interfaces/StorageListOptions.md +1 -1
  144. package/docs/api/interfaces/StorageListResult.md +1 -1
  145. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  146. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  147. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  148. package/docs/api/interfaces/StyleImport.md +1 -1
  149. package/docs/api/interfaces/SwitchProps.md +1 -1
  150. package/docs/api/interfaces/ToastActionElement.md +1 -1
  151. package/docs/api/interfaces/ToastProps.md +1 -1
  152. package/docs/api/interfaces/UnifiedAuthContextType.md +524 -440
  153. package/docs/api/interfaces/UnifiedAuthProviderProps.md +14 -14
  154. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  155. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  158. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  159. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  160. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  161. package/docs/api/interfaces/UseResolvedScopeOptions.md +47 -0
  162. package/docs/api/interfaces/UseResolvedScopeReturn.md +47 -0
  163. package/docs/api/interfaces/UserEventAccess.md +11 -11
  164. package/docs/api/interfaces/UserMenuProps.md +1 -1
  165. package/docs/api/interfaces/UserProfile.md +1 -1
  166. package/docs/api/modules.md +234 -61
  167. package/docs/api-reference/providers.md +26 -7
  168. package/docs/architecture/services.md +30 -32
  169. package/docs/best-practices/README.md +20 -0
  170. package/docs/best-practices/accessibility.md +566 -0
  171. package/docs/best-practices/performance-expansion.md +473 -0
  172. package/docs/breaking-changes.md +2 -5
  173. package/docs/core-concepts/authentication.md +15 -7
  174. package/docs/documentation-index.md +1 -1
  175. package/docs/documentation-templates.md +539 -0
  176. package/docs/getting-started/quick-start.md +16 -66
  177. package/docs/implementation-guides/component-styling.md +410 -0
  178. package/docs/implementation-guides/data-tables.md +1 -1
  179. package/docs/migration/service-architecture.md +121 -260
  180. package/docs/rbac/README-rbac-rls-integration.md +48 -38
  181. package/docs/style-guide.md +39 -0
  182. package/{src/rbac/examples → examples/RBAC}/CompleteRBACExample.tsx +3 -2
  183. package/{src/rbac/examples → examples/RBAC}/EventBasedApp.tsx +5 -4
  184. package/{src/components/examples → examples/RBAC}/PermissionExample.tsx +7 -6
  185. package/examples/RBAC/__tests__/PermissionExample.test.tsx +150 -0
  186. package/examples/RBAC/index.ts +13 -0
  187. package/examples/README.md +37 -0
  188. package/examples/index.ts +22 -0
  189. package/{src/examples → examples/public-pages}/CorrectPublicPageImplementation.tsx +1 -1
  190. package/{src/examples → examples/public-pages}/PublicEventPage.tsx +1 -1
  191. package/{src/examples → examples/public-pages}/PublicPageApp.tsx +1 -1
  192. package/{src/examples → examples/public-pages}/PublicPageUsageExample.tsx +1 -1
  193. package/examples/public-pages/__tests__/PublicPageUsageExample.test.tsx +159 -0
  194. package/examples/public-pages/index.ts +14 -0
  195. package/package.json +22 -18
  196. package/src/__tests__/TEST_GUIDE_CURSOR.md +940 -9
  197. package/src/__tests__/helpers/README.md +255 -0
  198. package/src/__tests__/helpers/index.ts +62 -0
  199. package/src/__tests__/helpers/supabaseMock.ts +75 -5
  200. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -8
  201. package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +17 -6
  202. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +73 -9
  203. package/src/components/DataTable/components/DataTableCore.tsx +280 -475
  204. package/src/components/DataTable/components/UnifiedTableBody.tsx +120 -153
  205. package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +55 -0
  206. package/src/components/DataTable/components/index.ts +1 -2
  207. package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +208 -275
  208. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +254 -0
  209. package/src/components/DataTable/core/index.ts +1 -8
  210. package/src/components/DataTable/examples/__tests__/HierarchicalExample.test.tsx +45 -0
  211. package/src/components/DataTable/examples/__tests__/PerformanceExample.test.tsx +117 -0
  212. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +525 -0
  213. package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +570 -0
  214. package/src/components/DataTable/hooks/__tests__/useHierarchicalState.test.ts +214 -0
  215. package/src/components/DataTable/hooks/__tests__/useTableColumns.test.ts +224 -0
  216. package/src/components/DataTable/hooks/index.ts +6 -0
  217. package/src/components/DataTable/hooks/useColumnReordering.ts +1 -0
  218. package/src/components/DataTable/hooks/useDataTablePermissions.ts +149 -0
  219. package/src/components/DataTable/hooks/useDataTableState.ts +12 -6
  220. package/src/components/DataTable/hooks/useHierarchicalState.ts +26 -8
  221. package/src/components/DataTable/hooks/useTableColumns.ts +153 -0
  222. package/src/components/DataTable/index.ts +1 -9
  223. package/src/components/DataTable/utils/__tests__/COVERAGE_NOTE.md +89 -0
  224. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +3 -6
  225. package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +462 -0
  226. package/src/components/DataTable/utils/__tests__/hierarchicalSorting.test.ts +247 -0
  227. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +8 -6
  228. package/src/components/DataTable/utils/__tests__/performanceUtils.test.ts +466 -0
  229. package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +265 -0
  230. package/src/components/DataTable/utils/errorHandling.ts +52 -460
  231. package/src/components/DataTable/utils/exportUtils.ts +46 -15
  232. package/src/components/DataTable/utils/hierarchicalSorting.ts +50 -3
  233. package/src/components/DataTable/utils/hierarchicalUtils.ts +167 -34
  234. package/src/components/DataTable/utils/index.ts +5 -0
  235. package/src/components/DataTable/utils/rowUtils.ts +68 -0
  236. package/src/components/Dialog/examples/__tests__/HtmlDialogExample.test.tsx +71 -0
  237. package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +122 -0
  238. package/src/components/EventSelector/EventSelector.test.tsx +672 -0
  239. package/src/components/EventSelector/EventSelector.tsx +1 -1
  240. package/src/components/Header/Header.test.tsx +35 -1
  241. package/src/components/Header/Header.tsx +3 -1
  242. package/src/components/Label/__tests__/Label.test.tsx +434 -0
  243. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -3
  244. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +24 -4
  245. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +3 -2
  246. package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +190 -0
  247. package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +185 -0
  248. package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +313 -0
  249. package/src/components/Select/Select.test.tsx +143 -120
  250. package/src/components/Select/Select.tsx +47 -212
  251. package/src/components/Select/hooks.ts +36 -1
  252. package/src/components/Select/index.ts +2 -1
  253. package/src/hooks/__tests__/useFocusManagement.unit.test.ts +220 -0
  254. package/src/hooks/__tests__/useIsMobile.unit.test.ts +117 -0
  255. package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +295 -0
  256. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +29 -19
  257. package/src/hooks/__tests__/useRBAC.unit.test.ts +7 -3
  258. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +115 -19
  259. package/src/hooks/services/__tests__/useServiceHooks.test.tsx +137 -0
  260. package/src/hooks/useEventTheme.test.ts +350 -0
  261. package/src/hooks/useEventTheme.ts +1 -1
  262. package/src/hooks/useEvents.ts +61 -0
  263. package/src/hooks/useOrganisationSecurity.test.ts +4 -4
  264. package/src/hooks/useOrganisationSecurity.ts +2 -2
  265. package/src/hooks/useOrganisations.ts +64 -0
  266. package/src/hooks/useSecureDataAccess.test.ts +37 -30
  267. package/src/hooks/useSecureDataAccess.ts +2 -2
  268. package/src/index.ts +18 -3
  269. package/src/providers/AuthProvider.tsx +8 -292
  270. package/src/providers/EventProvider.tsx +15 -425
  271. package/src/providers/InactivityProvider.tsx +8 -231
  272. package/src/providers/OrganisationProvider.test.simple.tsx +3 -2
  273. package/src/providers/OrganisationProvider.tsx +11 -890
  274. package/src/providers/UnifiedAuthProvider.tsx +8 -320
  275. package/src/providers/__tests__/AuthProvider.test.tsx +18 -17
  276. package/src/providers/__tests__/EventProvider.test.tsx +253 -2
  277. package/src/providers/__tests__/InactivityProvider.test-helper.tsx +65 -0
  278. package/src/providers/__tests__/InactivityProvider.test.tsx +46 -114
  279. package/src/providers/__tests__/OrganisationProvider.test.tsx +313 -3
  280. package/src/providers/__tests__/ProviderLifecycle.test.tsx +341 -0
  281. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +383 -2
  282. package/src/providers/index.ts +8 -7
  283. package/src/providers/services/EventServiceProvider.tsx +3 -0
  284. package/src/providers/services/UnifiedAuthProvider.tsx +3 -0
  285. package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +437 -0
  286. package/src/rbac/hooks/index.ts +2 -0
  287. package/src/rbac/hooks/usePermissions.test.ts +296 -0
  288. package/src/rbac/hooks/useRBAC.test.ts +9 -5
  289. package/src/rbac/hooks/useRBAC.ts +3 -3
  290. package/src/rbac/hooks/useResolvedScope.ts +232 -0
  291. package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +688 -0
  292. package/src/rbac/providers/__tests__/RBACProvider.test.tsx +507 -0
  293. package/src/services/AuthService.ts +19 -4
  294. package/src/services/__tests__/AuthService.test.ts +288 -0
  295. package/src/services/__tests__/InactivityService.lifecycle.test.ts +411 -0
  296. package/src/services/__tests__/OrganisationService.pagination.test.ts +375 -0
  297. package/src/styles/core.css +2 -0
  298. package/src/types/__tests__/README.md +114 -0
  299. package/src/types/__tests__/guards.test.ts +246 -0
  300. package/src/types/__tests__/validation.test.ts +731 -0
  301. package/src/types/guards.ts +1 -0
  302. package/src/types/organisation.ts +3 -2
  303. package/src/utils/__tests__/file-reference.test.ts +383 -0
  304. package/src/utils/__tests__/performanceBenchmark.test.ts +175 -0
  305. package/src/utils/appNameResolver.test.ts +54 -0
  306. package/src/validation/__tests__/csrf.unit.test.ts +63 -0
  307. package/src/validation/__tests__/passwordSchema.unit.test.ts +105 -0
  308. package/src/validation/__tests__/sanitization.unit.test.ts +250 -0
  309. package/src/validation/__tests__/schemaUtils.unit.test.ts +451 -0
  310. package/src/validation/__tests__/user.unit.test.ts +440 -0
  311. package/dist/DataTable-2QR5TER5.js +0 -102
  312. package/dist/RBACProvider-BO4ilsQB.d.ts +0 -63
  313. package/dist/UnifiedAuthProvider-D02AMXgO.d.ts +0 -103
  314. package/dist/chunk-3SP4P7NS.js.map +0 -1
  315. package/dist/chunk-B5LK25HV.js +0 -953
  316. package/dist/chunk-B5LK25HV.js.map +0 -1
  317. package/dist/chunk-BKVGJVUR.js.map +0 -1
  318. package/dist/chunk-C5Q5LRU5.js +0 -5691
  319. package/dist/chunk-C5Q5LRU5.js.map +0 -1
  320. package/dist/chunk-CDDYJCYU.js +0 -79
  321. package/dist/chunk-CDDYJCYU.js.map +0 -1
  322. package/dist/chunk-DG5Z55HH.js.map +0 -1
  323. package/dist/chunk-H2TNUICK.js.map +0 -1
  324. package/dist/chunk-IHMMNKNA.js.map +0 -1
  325. package/dist/chunk-LVQ26TCN.js.map +0 -1
  326. package/dist/chunk-ORSMVXO2.js.map +0 -1
  327. package/dist/chunk-TYHR5X4W.js +0 -33
  328. package/dist/chunk-TYHR5X4W.js.map +0 -1
  329. package/dist/chunk-UJMCGBLS.js.map +0 -1
  330. package/dist/chunk-V6BHACCH.js +0 -17
  331. package/dist/chunk-V6BHACCH.js.map +0 -1
  332. package/dist/chunk-YNUBMSMV.js.map +0 -1
  333. package/dist/eventContext-BBA42P6G.js +0 -14
  334. package/dist/rbac/cli/policy-manager.js +0 -278
  335. package/dist/rbac/cli/policy-manager.js.map +0 -1
  336. package/docs/api/interfaces/EventContextType.md +0 -96
  337. package/docs/api/interfaces/EventProviderProps.md +0 -19
  338. package/docs/documentation-style-checklist.md +0 -294
  339. package/src/components/DataTable/components/DataTableBody.tsx +0 -488
  340. package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -144
  341. package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -515
  342. package/src/components/DataTable/core/ActionManager.ts +0 -235
  343. package/src/components/DataTable/core/ColumnManager.ts +0 -205
  344. package/src/components/DataTable/core/DataManager.ts +0 -188
  345. package/src/components/DataTable/core/DataTableContext.tsx +0 -181
  346. package/src/components/DataTable/core/LocalDataAdapter.ts +0 -264
  347. package/src/components/DataTable/core/PluginRegistry.ts +0 -229
  348. package/src/components/DataTable/core/StateManager.ts +0 -311
  349. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -634
  350. package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -519
  351. package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -714
  352. package/src/components/DataTable/core/interfaces.ts +0 -338
  353. package/src/components/DataTable/utils/debugTools.ts +0 -583
  354. package/src/components/Select/Select.bug-test.tsx +0 -69
  355. package/src/components/Select/Select.refactored.tsx +0 -497
  356. package/src/providers/OrganisationProvider.test.tsx +0 -164
  357. package/src/providers/UnifiedAuthProvider.test.tsx +0 -124
  358. package/src/providers/__tests__/AuthProvider.test.tsx.backup +0 -771
  359. package/src/providers/__tests__/EventProvider.test.tsx.backup +0 -824
  360. package/src/providers/__tests__/OrganisationProvider.test.tsx.backup +0 -820
  361. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup +0 -911
  362. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx.backup2 +0 -166
  363. package/src/rbac/cli/__tests__/policy-manager.test.ts +0 -339
  364. package/src/rbac/cli/policy-manager.ts +0 -443
  365. package/dist/{DataTable-2QR5TER5.js.map → DataTable-4GAVPIEG.js.map} +0 -0
  366. package/dist/{UnifiedAuthProvider-K4NRGXL4.js.map → UnifiedAuthProvider-3NKDOSOK.js.map} +0 -0
  367. package/dist/{eventContext-BBA42P6G.js.map → useInactivityTracker-MRUU55XI.js.map} +0 -0
  368. package/dist/{validation-PM_iOaTI.d.ts → validation-D8VcbTzC.d.ts} +2 -2
  369. /package/src/utils/{appNameResolver.test.ts.backup → appNameResolver.test 2.ts} +0 -0
@@ -1,426 +1,16 @@
1
- import React, {
2
- createContext,
3
- useContext,
4
- useState,
5
- useEffect,
6
- useLayoutEffect,
7
- useCallback,
8
- useRef,
9
- useMemo,
10
- } from 'react';
11
- import { useUnifiedAuth } from './UnifiedAuthProvider';
12
- import { useOrganisations } from './OrganisationProvider';
13
- import { setOrganisationContext } from '../utils/organisationContext';
14
- import { DebugLogger } from '../utils/debugLogger';
15
- import { applyPalette, clearPalette } from '../theming/runtime';
16
- import type { PaletteData, ColorPalette } from '../theming/runtime';
1
+ /**
2
+ * @file Re-export for EventProvider
3
+ * @package @jmruthers/pace-core
4
+ * @module Providers
5
+ * @since 0.1.0
6
+ *
7
+ * Re-exports the service-based EventProvider for backward compatibility.
8
+ */
9
+
10
+ export { EventServiceProvider as EventProvider } from './services/EventServiceProvider';
11
+ export type { EventServiceProviderProps as EventProviderProps } from './services/EventServiceProvider';
12
+
13
+ // Re-export context and hook
14
+ export { EventServiceContext, useEventService } from './services/EventServiceProvider';
15
+ export type { EventServiceContextType, EventContextType } from './services/EventServiceProvider';
17
16
 
18
- import { Event } from '../types/unified';
19
-
20
- export interface EventContextType {
21
- events: Event[];
22
- selectedEvent: Event | null;
23
- isLoading: boolean;
24
- error: Error | null;
25
- setSelectedEvent: (event: Event | null) => void;
26
- refreshEvents: () => Promise<void>;
27
- }
28
-
29
- const EventContext = createContext<EventContextType | undefined>(undefined);
30
-
31
- export const useEvents = () => {
32
- const context = useContext(EventContext);
33
- if (context === undefined) {
34
- throw new Error('useEvents must be used within an EventProvider');
35
- }
36
- return context;
37
- };
38
-
39
- export interface EventProviderProps {
40
- children: React.ReactNode;
41
- }
42
-
43
- // Helper function to get the next event by date
44
- function getNextEventByDate(events: Event[]): Event | null {
45
- if (!events || events.length === 0) {
46
- return null;
47
- }
48
-
49
- const now = new Date();
50
- const futureEvents = events.filter(event => {
51
- if (!event.event_date) return false;
52
- const eventDate = new Date(event.event_date);
53
- return eventDate >= now;
54
- });
55
-
56
- if (futureEvents.length === 0) {
57
- return null;
58
- }
59
-
60
- // Sort by date (ascending) to get the next event
61
- const sortedFutureEvents = futureEvents.sort((a, b) => {
62
- const dateA = new Date(a.event_date!);
63
- const dateB = new Date(b.event_date!);
64
- return dateA.getTime() - dateB.getTime();
65
- });
66
-
67
- return sortedFutureEvents[0];
68
- }
69
-
70
- export function EventProvider({ children }: EventProviderProps) {
71
- const [events, setEvents] = useState<Event[]>([]);
72
- const [selectedEvent, setSelectedEventState] = useState<Event | null>(null);
73
- const [isLoading, setIsLoading] = useState(true);
74
- const [error, setError] = useState<Error | null>(null);
75
- const { user, session, supabase, appName, setSelectedEventId } = useUnifiedAuth();
76
-
77
- // Refs to prevent infinite loops
78
- const isInitializedRef = useRef(false);
79
- const isFetchingRef = useRef(false);
80
- const hasAutoSelectedRef = useRef(false);
81
- const userClearedEventRef = useRef(false);
82
- const setSelectedEventIdRef = useRef(setSelectedEventId);
83
-
84
- // Try to get organisation context, but don't fail if not available
85
- let selectedOrganisation = null;
86
- let ensureOrganisationContext = null;
87
-
88
- try {
89
- const orgContext = useOrganisations();
90
- selectedOrganisation = orgContext.selectedOrganisation;
91
- ensureOrganisationContext = orgContext.ensureOrganisationContext;
92
- } catch (error) {
93
- console.warn('[EventProvider] Organisation context not available:', error);
94
- }
95
-
96
- // Load persisted event selection with tab-scoped storage
97
- const loadPersistedEvent = useCallback(async (events: Event[]) => {
98
- try {
99
- // Try sessionStorage first (tab-specific)
100
- let persistedEventId = sessionStorage.getItem('pace-core-selected-event');
101
-
102
- // Fallback to localStorage if no sessionStorage value (for new tabs)
103
- if (!persistedEventId) {
104
- persistedEventId = localStorage.getItem('pace-core-selected-event');
105
- // If we found a value in localStorage, also store it in sessionStorage for this tab
106
- if (persistedEventId) {
107
- sessionStorage.setItem('pace-core-selected-event', persistedEventId);
108
- }
109
- }
110
-
111
- if (persistedEventId && events.length > 0) {
112
- const persistedEvent = events.find(event => event.event_id === persistedEventId);
113
- if (persistedEvent) {
114
- DebugLogger.log('EventProvider', 'Restoring persisted event:', persistedEvent.event_name);
115
- setSelectedEventState(persistedEvent);
116
- setSelectedEventId(persistedEventId);
117
- return true;
118
- } else {
119
- DebugLogger.log('EventProvider', 'Persisted event not found in current events, clearing storage');
120
- // Clear invalid persisted event
121
- sessionStorage.removeItem('pace-core-selected-event');
122
- localStorage.removeItem('pace-core-selected-event');
123
- }
124
- }
125
- } catch (error) {
126
- console.warn('[EventProvider] Failed to load persisted event:', error);
127
- }
128
- return false;
129
- }, [setSelectedEventId]);
130
-
131
- // Persist event selection with tab-scoped storage
132
- const persistEventSelection = useCallback((eventId: string) => {
133
- try {
134
- // Store in sessionStorage for tab-specific persistence
135
- sessionStorage.setItem('pace-core-selected-event', eventId);
136
- // Also store in localStorage as fallback for new tabs
137
- localStorage.setItem('pace-core-selected-event', eventId);
138
- } catch (error) {
139
- console.warn('[EventProvider] Failed to persist event selection:', error);
140
- }
141
- }, []);
142
-
143
- // Auto-select next event
144
- const autoSelectNextEvent = useCallback((events: Event[]) => {
145
- const nextEvent = getNextEventByDate(events);
146
- if (nextEvent) {
147
- DebugLogger.log('EventProvider', 'Auto-selecting next event:', nextEvent.event_name);
148
- setSelectedEventState(nextEvent);
149
- setSelectedEventId(nextEvent.event_id);
150
- persistEventSelection(nextEvent.event_id);
151
- }
152
- }, [setSelectedEventId, persistEventSelection]);
153
-
154
- // Main fetch function
155
- const fetchEvents = useCallback(async () => {
156
- if (!user || !session || !supabase || !appName || !selectedOrganisation) {
157
- DebugLogger.log('EventProvider', 'Missing required dependencies, skipping fetch');
158
- setIsLoading(false);
159
- return;
160
- }
161
-
162
- // Prevent multiple simultaneous fetches
163
- if (isFetchingRef.current) {
164
- DebugLogger.log('EventProvider', 'Already fetching events, skipping');
165
- return;
166
- }
167
-
168
- DebugLogger.log('EventProvider', 'User and organisation found, fetching events for:', {
169
- userId: user.id,
170
- appName: appName,
171
- organisationId: selectedOrganisation.id,
172
- organisationName: selectedOrganisation.display_name
173
- });
174
-
175
- isFetchingRef.current = true;
176
- let isMounted = true;
177
-
178
- try {
179
- // Ensure organisation context is set
180
- if (ensureOrganisationContext) {
181
- await ensureOrganisationContext();
182
- await setOrganisationContext(supabase, selectedOrganisation.id);
183
- }
184
-
185
- // Call the RPC function following the established pattern
186
- DebugLogger.log('EventProvider', 'Calling data_user_events_get RPC with:', {
187
- user_id: user.id,
188
- organisation_id: selectedOrganisation.id,
189
- app_name: appName
190
- });
191
-
192
- const { data, error: rpcError } = await supabase.rpc('data_user_events_get', {
193
- p_user_id: user.id,
194
- p_organisation_id: selectedOrganisation.id,
195
- p_app_name: appName
196
- });
197
-
198
- DebugLogger.log('EventProvider', 'RPC response:', {
199
- data,
200
- error: rpcError,
201
- dataLength: data?.length || 0,
202
- organisationId: selectedOrganisation.id
203
- });
204
-
205
- if (rpcError) {
206
- throw new Error(rpcError.message || 'Failed to fetch events');
207
- }
208
-
209
- if (isMounted) {
210
- const eventsData = data || [];
211
- console.log('[EventProvider] Loaded events:', eventsData.map((event: any) => ({
212
- eventId: event.event_id,
213
- eventName: event.event_name,
214
- organisationId: event.organisation_id,
215
- selectedOrganisationId: selectedOrganisation?.id
216
- })));
217
-
218
- // Transform the data to match our Event interface
219
- const transformedEvents: Event[] = eventsData.map((event: any) => ({
220
- id: event.event_id, // Use event_id as the primary id
221
- event_id: event.event_id,
222
- event_name: event.event_name,
223
- event_date: event.event_date,
224
- event_venue: event.event_venue,
225
- event_participants: event.event_participants,
226
- event_colours: event.event_colours,
227
- event_logo: '', // No logo field in event table
228
- organisation_id: event.organisation_id,
229
- is_visible: event.is_visible,
230
- // Legacy compatibility
231
- name: event.event_name,
232
- start_date: event.event_date
233
- }));
234
-
235
- setEvents(transformedEvents);
236
- setError(null);
237
-
238
- // Note: Event colors are automatically applied when selectedEvent changes (see useEffect below)
239
-
240
- // Reset auto-selection ref for new events
241
- hasAutoSelectedRef.current = false;
242
-
243
- // Try to restore persisted event first
244
- const persistedEventLoaded = await loadPersistedEvent(transformedEvents);
245
-
246
- // If no persisted event was loaded, auto-select the next event
247
- if (!persistedEventLoaded) {
248
- const nextEvent = getNextEventByDate(transformedEvents);
249
- if (nextEvent) {
250
- DebugLogger.log('EventProvider', 'Auto-selecting next event after no persisted event found:', nextEvent.event_name);
251
- hasAutoSelectedRef.current = true;
252
- setSelectedEventState(nextEvent);
253
- setSelectedEventIdRef.current(nextEvent.event_id);
254
- persistEventSelection(nextEvent.event_id);
255
- }
256
- }
257
- }
258
- } catch (err) {
259
- console.error('[EventProvider] Error fetching events:', err);
260
- const _error = err instanceof Error ? err : new Error('Unknown error occurred');
261
-
262
- if (isMounted) {
263
- setError(_error);
264
- setEvents([]);
265
- }
266
- } finally {
267
- if (isMounted) {
268
- setIsLoading(false);
269
- }
270
- isFetchingRef.current = false;
271
- }
272
-
273
- return () => {
274
- isMounted = false;
275
- };
276
- }, [user, session, supabase, appName, selectedOrganisation, ensureOrganisationContext, loadPersistedEvent, autoSelectNextEvent]);
277
-
278
- // Initialize events only once
279
- useEffect(() => {
280
- if (!isInitializedRef.current) {
281
- isInitializedRef.current = true;
282
- fetchEvents();
283
- }
284
- }, [fetchEvents]);
285
-
286
- // Update ref when setSelectedEventId changes
287
- useEffect(() => {
288
- setSelectedEventIdRef.current = setSelectedEventId;
289
- }, [setSelectedEventId]);
290
-
291
- // Auto-select next event when events are loaded and no event is selected
292
- useLayoutEffect(() => {
293
- if (events.length > 0 && !selectedEvent && !hasAutoSelectedRef.current && !userClearedEventRef.current) {
294
- const nextEvent = getNextEventByDate(events);
295
- if (nextEvent) {
296
- DebugLogger.log('EventProvider', 'Auto-selecting next event:', nextEvent.event_name);
297
- hasAutoSelectedRef.current = true;
298
- setSelectedEventState(nextEvent);
299
- setSelectedEventIdRef.current(nextEvent.event_id);
300
- persistEventSelection(nextEvent.event_id);
301
- }
302
- }
303
- }, [events, selectedEvent]);
304
-
305
- // Apply event theming when selected event changes
306
- useEffect(() => {
307
- console.log('[EventProvider] Event theming useEffect triggered, selectedEvent:', selectedEvent?.event_name, selectedEvent?.event_colours);
308
-
309
- if (!selectedEvent) {
310
- console.log('[EventProvider] No selected event, clearing palette');
311
- clearPalette();
312
- return;
313
- }
314
-
315
- const eventColours = selectedEvent.event_colours;
316
- console.log('[EventProvider] Event colours:', eventColours);
317
- console.log('[EventProvider] Event colours keys:', Object.keys(eventColours as object || {}));
318
-
319
- if (!eventColours || typeof eventColours !== 'object') {
320
- console.log('[EventProvider] No valid event_colours, clearing palette');
321
- clearPalette();
322
- return;
323
- }
324
-
325
- // Map event palette keys (ev-main, ev-sec, ev-acc) to app palette keys (main, sec, acc)
326
- // This matches the format used in pace-admin's eventColorManager
327
- const evMainPalette = ((eventColours as any)['ev-main'] as ColorPalette) || ((eventColours as any).main as ColorPalette) || {};
328
- const evSecPalette = ((eventColours as any)['ev-sec'] as ColorPalette) || ((eventColours as any).sec as ColorPalette) || {};
329
- const evAccPalette = ((eventColours as any)['ev-acc'] as ColorPalette) || ((eventColours as any).acc as ColorPalette) || {};
330
-
331
- console.log('[EventProvider] Mapped palettes:', {
332
- 'ev-main': Object.keys(evMainPalette),
333
- 'ev-sec': Object.keys(evSecPalette),
334
- 'ev-acc': Object.keys(evAccPalette),
335
- });
336
-
337
- const fullPalette: PaletteData = {
338
- main: evMainPalette,
339
- sec: evSecPalette,
340
- acc: evAccPalette,
341
- };
342
-
343
- // Check if we have at least one valid palette
344
- if (!fullPalette.main && !fullPalette.sec && !fullPalette.acc) {
345
- console.log('[EventProvider] No valid palettes found in event_colours, clearing palette');
346
- clearPalette();
347
- return;
348
- }
349
-
350
- console.log('[EventProvider] Applying full palette:', fullPalette);
351
-
352
- try {
353
- applyPalette(fullPalette);
354
- console.log('[EventProvider] Palette applied successfully');
355
- } catch (error) {
356
- console.error('[EventProvider] Failed to apply event palette:', error);
357
- }
358
- }, [selectedEvent]);
359
-
360
- const setSelectedEvent = useCallback((event: Event | null) => {
361
- if (event) {
362
- // SECURITY: Validate event belongs to current organisation
363
- try {
364
- console.log('[EventProvider] Event selection validation:', {
365
- eventId: event.event_id,
366
- eventName: event.event_name,
367
- eventOrganisationId: event.organisation_id,
368
- selectedOrganisationId: selectedOrganisation?.id,
369
- selectedOrganisationName: selectedOrganisation?.display_name,
370
- match: event.organisation_id === selectedOrganisation?.id
371
- });
372
-
373
- if (selectedOrganisation && event.organisation_id !== selectedOrganisation.id) {
374
- console.error('[EventProvider] Event organisation_id does not match selected organisation', {
375
- eventOrganisationId: event.organisation_id,
376
- selectedOrganisationId: selectedOrganisation.id,
377
- eventName: event.event_name
378
- });
379
- return;
380
- }
381
- } catch (error) {
382
- console.error('[EventProvider] Error during event validation:', error);
383
- }
384
-
385
- setSelectedEventState(event);
386
- setSelectedEventId(event.event_id);
387
- persistEventSelection(event.event_id);
388
- // Reset the user cleared flag when selecting an event
389
- userClearedEventRef.current = false;
390
- } else {
391
- setSelectedEventState(null);
392
- setSelectedEventId(null);
393
- // Clear both sessionStorage and localStorage
394
- sessionStorage.removeItem('pace-core-selected-event');
395
- localStorage.removeItem('pace-core-selected-event');
396
- // Reset the auto-selection flag when clearing the event
397
- hasAutoSelectedRef.current = false;
398
- // Mark that user explicitly cleared the event to prevent auto-selection
399
- userClearedEventRef.current = true;
400
- }
401
- }, [selectedOrganisation, setSelectedEventId, persistEventSelection]);
402
-
403
- const refreshEvents = useCallback(async () => {
404
- isInitializedRef.current = false;
405
- isFetchingRef.current = false;
406
- // Reset the user cleared flag when refreshing events
407
- userClearedEventRef.current = false;
408
- await fetchEvents();
409
- }, [fetchEvents]);
410
-
411
- // Memoize the context value to prevent unnecessary re-renders
412
- const contextValue: EventContextType = useMemo(() => ({
413
- events,
414
- selectedEvent,
415
- isLoading,
416
- error,
417
- setSelectedEvent,
418
- refreshEvents,
419
- }), [events, selectedEvent, isLoading, error, setSelectedEvent, refreshEvents]);
420
-
421
- return (
422
- <EventContext.Provider value={contextValue}>
423
- {children}
424
- </EventContext.Provider>
425
- );
426
- }
@@ -1,238 +1,15 @@
1
1
  /**
2
- * @file Inactivity Provider
2
+ * @file Re-export for InactivityProvider
3
3
  * @package @jmruthers/pace-core
4
- * @module Providers/Inactivity
4
+ * @module Providers
5
5
  * @since 0.1.0
6
- *
7
- * Handles inactivity tracking, auto-logout, and warning modals.
8
- * Separated from UnifiedAuthProvider for better maintainability.
6
+ *
7
+ * Re-exports the service-based InactivityProvider for backward compatibility.
9
8
  */
10
9
 
11
- import React, { createContext, useContext, useState, useEffect, useCallback, useMemo } from 'react';
12
- import { useInactivityTracker } from '../hooks/useInactivityTracker';
13
- import { InactivityWarningModal } from '../components/InactivityWarningModal/InactivityWarningModal';
10
+ export { InactivityServiceProvider as InactivityProvider } from './services/InactivityServiceProvider';
11
+ export type { InactivityServiceProviderProps as InactivityProviderProps, InactivityServiceContextType as InactivityContextType } from './services/InactivityServiceProvider';
14
12
 
15
- // Inactivity context type
16
- export interface InactivityContextType {
17
- // Inactivity state
18
- showInactivityWarning: boolean;
19
- inactivityTimeRemaining: number;
20
- isIdle: boolean;
21
- timeRemaining: number;
22
- showWarning: boolean;
23
- isTracking: boolean;
24
-
25
- // Inactivity methods
26
- resetActivity: () => void;
27
- startTracking: () => void;
28
- stopTracking: () => void;
29
- handleIdleLogout: () => Promise<void>;
30
- handleStaySignedIn: () => void;
31
- handleSignOutNow: () => Promise<void>;
32
- }
13
+ // Re-export hook
14
+ export { useInactivityService as useInactivity } from '../hooks/services/useInactivityService';
33
15
 
34
- const InactivityContext = createContext<InactivityContextType | undefined>(undefined);
35
-
36
- export const useInactivity = () => {
37
- const context = useContext(InactivityContext);
38
- if (!context) {
39
- throw new Error('useInactivity must be used within an InactivityProvider');
40
- }
41
- return context;
42
- };
43
-
44
- export interface InactivityProviderProps {
45
- children: React.ReactNode;
46
- user: any; // User from auth context
47
- session: any; // Session from auth context
48
- supabaseClient: any; // Supabase client
49
- idleTimeoutMs?: number; // Default: 30 minutes
50
- warnBeforeMs?: number; // Default: 60 seconds
51
- onIdleLogout?: (reason: 'inactivity') => void; // App handles redirect/navigation
52
- renderInactivityWarning?: (args: {
53
- timeRemaining: number;
54
- onStaySignedIn: () => void;
55
- onSignOutNow: () => void;
56
- }) => React.ReactNode; // Optional custom warning UI
57
- dangerouslyDisableInactivity?: boolean; // Dev-only; must not disable in production
58
- }
59
-
60
- export function InactivityProvider({
61
- children,
62
- user,
63
- session,
64
- supabaseClient,
65
- idleTimeoutMs = 30 * 60 * 1000, // 30 minutes
66
- warnBeforeMs = 60 * 1000, // 60 seconds
67
- onIdleLogout,
68
- renderInactivityWarning,
69
- dangerouslyDisableInactivity = false
70
- }: InactivityProviderProps) {
71
- // Inactivity state
72
- const [showInactivityWarning, setShowInactivityWarning] = useState(false);
73
- const [inactivityTimeRemaining, setInactivityTimeRemaining] = useState(0);
74
-
75
- // Production safety check for inactivity feature
76
- useEffect(() => {
77
- if (typeof window !== 'undefined') {
78
- const isProduction = import.meta.env.MODE === 'production';
79
-
80
- if (isProduction && dangerouslyDisableInactivity) {
81
- console.error('[InactivityProvider] CRITICAL: dangerouslyDisableInactivity is not allowed in production! Auto-enabling inactivity feature.');
82
- }
83
-
84
- if (!isProduction && dangerouslyDisableInactivity) {
85
- console.warn('[InactivityProvider] Inactivity feature disabled for development. This will NOT work in production.');
86
- }
87
- }
88
- }, [dangerouslyDisableInactivity]);
89
-
90
- // Inactivity tracking
91
- const isInactivityEnabled = typeof window !== 'undefined' &&
92
- (import.meta.env.MODE !== 'production' ? !dangerouslyDisableInactivity : true);
93
-
94
- const {
95
- isIdle,
96
- timeRemaining,
97
- showWarning,
98
- resetActivity,
99
- startTracking,
100
- stopTracking,
101
- isTracking
102
- } = useInactivityTracker({
103
- idleTimeoutMs,
104
- warnBeforeMs,
105
- enabled: isInactivityEnabled && !!user && !!session,
106
- onIdle: useCallback(() => {
107
- // Handle idle logout inline to avoid circular dependency
108
- setShowInactivityWarning(false);
109
- setInactivityTimeRemaining(0);
110
-
111
- // Sign out via Supabase
112
- if (supabaseClient) {
113
- supabaseClient.auth.signOut().catch((error: any) => {
114
- console.error('[InactivityProvider] Error during idle logout:', error);
115
- });
116
- }
117
-
118
- // Call app callback for navigation/redirect
119
- onIdleLogout?.('inactivity');
120
- }, [supabaseClient, onIdleLogout]),
121
- onWarning: useCallback(() => {
122
- setShowInactivityWarning(true);
123
- setInactivityTimeRemaining(warnBeforeMs);
124
- }, [warnBeforeMs]),
125
- onActivity: useCallback(() => {
126
- setShowInactivityWarning(false);
127
- setInactivityTimeRemaining(0);
128
- }, [])
129
- });
130
-
131
- // Handle idle logout (for manual calls)
132
- const handleIdleLogout = useCallback(async () => {
133
- // Hide warning
134
- setShowInactivityWarning(false);
135
- setInactivityTimeRemaining(0);
136
-
137
- // Stop tracking
138
- stopTracking();
139
-
140
- // Sign out via Supabase
141
- try {
142
- if (supabaseClient) {
143
- await supabaseClient.auth.signOut();
144
- }
145
- } catch (error: any) {
146
- console.error('[InactivityProvider] Error during idle logout:', error);
147
- }
148
-
149
- // Call app callback for navigation/redirect
150
- onIdleLogout?.('inactivity');
151
- }, [supabaseClient, onIdleLogout, stopTracking]);
152
-
153
- // Handle stay signed in
154
- const handleStaySignedIn = useCallback(() => {
155
- setShowInactivityWarning(false);
156
- setInactivityTimeRemaining(0);
157
- resetActivity();
158
- }, [resetActivity]);
159
-
160
- // Handle sign out now
161
- const handleSignOutNow = useCallback(async () => {
162
- setShowInactivityWarning(false);
163
- setInactivityTimeRemaining(0);
164
- stopTracking();
165
-
166
- // Sign out via Supabase
167
- try {
168
- if (supabaseClient) {
169
- await supabaseClient.auth.signOut();
170
- }
171
- } catch (error: any) {
172
- console.error('[InactivityProvider] Error during manual sign out:', error);
173
- }
174
-
175
- // Call app callback for navigation/redirect
176
- onIdleLogout?.('inactivity');
177
- }, [supabaseClient, onIdleLogout, stopTracking]);
178
-
179
- // Update inactivity time remaining
180
- useEffect(() => {
181
- if (showWarning && timeRemaining > 0) {
182
- setInactivityTimeRemaining(Math.ceil(timeRemaining / 1000)); // Convert to seconds
183
- }
184
- }, [showWarning, timeRemaining]);
185
-
186
- // Memoized context value
187
- const contextValue = useMemo<InactivityContextType>(() => ({
188
- showInactivityWarning,
189
- inactivityTimeRemaining,
190
- isIdle,
191
- timeRemaining,
192
- showWarning,
193
- isTracking,
194
- resetActivity,
195
- startTracking,
196
- stopTracking,
197
- handleIdleLogout,
198
- handleStaySignedIn,
199
- handleSignOutNow,
200
- }), [
201
- showInactivityWarning,
202
- inactivityTimeRemaining,
203
- isIdle,
204
- timeRemaining,
205
- showWarning,
206
- isTracking,
207
- resetActivity,
208
- startTracking,
209
- stopTracking,
210
- handleIdleLogout,
211
- handleStaySignedIn,
212
- handleSignOutNow,
213
- ]);
214
-
215
- return (
216
- <InactivityContext.Provider value={contextValue}>
217
- {children}
218
-
219
- {/* Inactivity Warning Modal */}
220
- {showInactivityWarning && (
221
- renderInactivityWarning ? (
222
- renderInactivityWarning({
223
- timeRemaining: inactivityTimeRemaining,
224
- onStaySignedIn: handleStaySignedIn,
225
- onSignOutNow: handleSignOutNow
226
- })
227
- ) : (
228
- <InactivityWarningModal
229
- isOpen={showInactivityWarning}
230
- timeRemaining={inactivityTimeRemaining}
231
- onStaySignedIn={handleStaySignedIn}
232
- onSignOutNow={handleSignOutNow}
233
- />
234
- )
235
- )}
236
- </InactivityContext.Provider>
237
- );
238
- }