@jmruthers/pace-core 0.5.181 → 0.5.183

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 (756) hide show
  1. package/CHANGELOG.md +1 -1
  2. package/README.md +16 -2
  3. package/dist/{AuthService-DYuQPJj6.d.ts → AuthService-B-cd2MA4.d.ts} +9 -11
  4. package/dist/{DataTable-CWAZZcXC.d.ts → DataTable-Bz8ffqyA.d.ts} +1 -1
  5. package/dist/{DataTable-UA6CL4JI.js → DataTable-QAB34V6K.js} +14 -15
  6. package/dist/UnifiedAuthProvider-7F6T4B6K.js +13 -0
  7. package/dist/{UnifiedAuthProvider-DJxGTftH.d.ts → UnifiedAuthProvider-F86d7dSi.d.ts} +5 -6
  8. package/dist/{api-45XYYO2A.js → api-ROMBCNKU.js} +5 -5
  9. package/dist/{audit-64X3VJXB.js → audit-WRS3KJKI.js} +4 -4
  10. package/dist/auth-BZOJqrdd.d.ts +49 -0
  11. package/dist/{chunk-CX5M4ZAG.js → chunk-5DRSZLL2.js} +1 -1
  12. package/dist/chunk-5DRSZLL2.js.map +1 -0
  13. package/dist/{chunk-BESYRHQM.js → chunk-6C4YBBJM.js} +10 -7
  14. package/dist/chunk-6C4YBBJM.js.map +1 -0
  15. package/dist/{chunk-PLDDJCW6.js → chunk-7D4SUZUM.js} +2 -13
  16. package/dist/{chunk-HRO5HWN2.js → chunk-CSOFYHAG.js} +55 -162
  17. package/dist/chunk-CSOFYHAG.js.map +1 -0
  18. package/dist/{chunk-ANBQRTPX.js → chunk-E66EQZE6.js} +3 -5
  19. package/dist/{chunk-ANBQRTPX.js.map → chunk-E66EQZE6.js.map} +1 -1
  20. package/dist/{chunk-Q5QRDWKI.js → chunk-F2IMUDXZ.js} +4 -6
  21. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  22. package/dist/{chunk-SBVILCCA.js → chunk-FSFQFJCU.js} +28 -6
  23. package/dist/chunk-FSFQFJCU.js.map +1 -0
  24. package/dist/chunk-FUEYYMX5.js +2296 -0
  25. package/dist/chunk-FUEYYMX5.js.map +1 -0
  26. package/dist/{chunk-FFKNH6U5.js → chunk-HKIT6O7W.js} +3 -5
  27. package/dist/{chunk-FFKNH6U5.js.map → chunk-HKIT6O7W.js.map} +1 -1
  28. package/dist/chunk-KQCRWDSA.js +1 -0
  29. package/dist/{chunk-S5OFRT4M.js → chunk-KUEN3HFB.js} +6 -6
  30. package/dist/chunk-KUEN3HFB.js.map +1 -0
  31. package/dist/chunk-LMC26NLJ.js +84 -0
  32. package/dist/chunk-LMC26NLJ.js.map +1 -0
  33. package/dist/{chunk-BVYWGZVV.js → chunk-M7W4CP3M.js} +52 -19
  34. package/dist/chunk-M7W4CP3M.js.map +1 -0
  35. package/dist/{chunk-HZLDFOE4.js → chunk-MI7HBHN3.js} +164 -243
  36. package/dist/chunk-MI7HBHN3.js.map +1 -0
  37. package/dist/{chunk-PPMP5J6T.js → chunk-PWAHJW4G.js} +180 -29
  38. package/dist/chunk-PWAHJW4G.js.map +1 -0
  39. package/dist/chunk-PWLANIRT.js +127 -0
  40. package/dist/{chunk-XDNLUEXI.js.map → chunk-PWLANIRT.js.map} +1 -1
  41. package/dist/chunk-QCDXODCA.js +75 -0
  42. package/dist/chunk-QCDXODCA.js.map +1 -0
  43. package/dist/{chunk-D7LCGMVS.js → chunk-QETLRQI6.js} +526 -887
  44. package/dist/chunk-QETLRQI6.js.map +1 -0
  45. package/dist/{chunk-5MT24GKJ.js → chunk-QUVSNGIP.js} +264 -262
  46. package/dist/chunk-QUVSNGIP.js.map +1 -0
  47. package/dist/chunk-QXHPKYJV.js +113 -0
  48. package/dist/chunk-QXHPKYJV.js.map +1 -0
  49. package/dist/{chunk-OWAG3GSU.js → chunk-R77UEZ4E.js} +11 -1
  50. package/dist/chunk-R77UEZ4E.js.map +1 -0
  51. package/dist/{chunk-ZYTYSTO5.js → chunk-RA3JUFMW.js} +314 -161
  52. package/dist/chunk-RA3JUFMW.js.map +1 -0
  53. package/dist/{chunk-ERISIBYU.js → chunk-SQGMNID3.js} +3 -8
  54. package/dist/chunk-SQGMNID3.js.map +1 -0
  55. package/dist/{chunk-XJ2HZOBU.js → chunk-UHNYIBXL.js} +1 -1
  56. package/dist/chunk-UHNYIBXL.js.map +1 -0
  57. package/{src/utils/secureStorage.ts → dist/chunk-VBXEHIUJ.js} +113 -88
  58. package/dist/{chunk-7QCC6MCP.js.map → chunk-VBXEHIUJ.js.map} +1 -1
  59. package/dist/{chunk-VZ4VDGTB.js → chunk-W22JP75J.js} +5 -13
  60. package/dist/{chunk-VZ4VDGTB.js.map → chunk-W22JP75J.js.map} +1 -1
  61. package/dist/components.d.ts +12 -93
  62. package/dist/components.js +23 -106
  63. package/dist/components.js.map +1 -1
  64. package/dist/core-CUElvH_C.d.ts +164 -0
  65. package/dist/database.generated-CBmg2950.d.ts +8284 -0
  66. package/dist/event-CW5YB_2p.d.ts +239 -0
  67. package/dist/{file-reference-C6Gkn77H.d.ts → file-reference-D06mEEWW.d.ts} +7 -5
  68. package/dist/functions-D_kgHktt.d.ts +208 -0
  69. package/dist/hooks.d.ts +54 -7
  70. package/dist/hooks.js +204 -17
  71. package/dist/hooks.js.map +1 -1
  72. package/dist/{EventLogo-B3V3otev.d.ts → index-Bl--n7-T.d.ts} +387 -397
  73. package/dist/index.d.ts +94 -261
  74. package/dist/index.js +314 -126
  75. package/dist/index.js.map +1 -1
  76. package/dist/providers.d.ts +7 -8
  77. package/dist/providers.js +6 -13
  78. package/dist/rbac/index.d.ts +171 -101
  79. package/dist/rbac/index.js +23 -17
  80. package/dist/styles/index.d.ts +1 -3
  81. package/dist/styles/index.js +2 -17
  82. package/dist/theming/runtime.js +3 -3
  83. package/dist/types-UU913iLA.d.ts +102 -0
  84. package/dist/{types-Dfz9dmVH.d.ts → types-_x1f4QBF.d.ts} +6 -6
  85. package/dist/types.d.ts +88 -227
  86. package/dist/types.js +64 -112
  87. package/dist/types.js.map +1 -1
  88. package/dist/{usePublicRouteParams-B7PabvuH.d.ts → usePublicRouteParams-JJczomYq.d.ts} +203 -6
  89. package/dist/utils.d.ts +299 -13
  90. package/dist/utils.js +481 -55
  91. package/dist/utils.js.map +1 -1
  92. package/dist/validation-643vUDZW.d.ts +177 -0
  93. package/docs/DOCUMENTATION_REVIEW_TRACKER.md +511 -0
  94. package/docs/README.md +9 -8
  95. package/docs/api/README.md +16 -2
  96. package/docs/api/classes/ColumnFactory.md +1 -1
  97. package/docs/api/classes/ErrorBoundary.md +1 -1
  98. package/docs/api/classes/InvalidScopeError.md +4 -4
  99. package/docs/api/classes/MissingUserContextError.md +4 -4
  100. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  101. package/docs/api/classes/PermissionDeniedError.md +4 -4
  102. package/docs/api/classes/RBACAuditManager.md +14 -14
  103. package/docs/api/classes/RBACCache.md +1 -1
  104. package/docs/api/classes/RBACEngine.md +2 -2
  105. package/docs/api/classes/RBACError.md +4 -4
  106. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  107. package/docs/api/classes/SecureSupabaseClient.md +29 -9
  108. package/docs/api/classes/StorageUtils.md +1 -1
  109. package/docs/api/enums/FileCategory.md +17 -17
  110. package/docs/api/enums/RBACErrorCode.md +228 -0
  111. package/docs/api/enums/RPCFunction.md +118 -0
  112. package/docs/api/interfaces/AggregateConfig.md +1 -1
  113. package/docs/api/interfaces/BadgeProps.md +1 -1
  114. package/docs/api/interfaces/ButtonProps.md +2 -2
  115. package/docs/api/interfaces/CalendarProps.md +1 -1
  116. package/docs/api/interfaces/CardProps.md +29 -3
  117. package/docs/api/interfaces/ColorPalette.md +1 -1
  118. package/docs/api/interfaces/ColorShade.md +1 -1
  119. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  120. package/docs/api/interfaces/DataRecord.md +1 -1
  121. package/docs/api/interfaces/DataTableAction.md +2 -2
  122. package/docs/api/interfaces/DataTableColumn.md +6 -6
  123. package/docs/api/interfaces/DataTableProps.md +1 -1
  124. package/docs/api/interfaces/DataTableToolbarButton.md +2 -2
  125. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  126. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  127. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  128. package/docs/api/interfaces/ExportColumn.md +5 -5
  129. package/docs/api/interfaces/ExportOptions.md +4 -4
  130. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  131. package/docs/api/interfaces/FileMetadata.md +13 -13
  132. package/docs/api/interfaces/FileReference.md +12 -12
  133. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  134. package/docs/api/interfaces/FileUploadOptions.md +10 -10
  135. package/docs/api/interfaces/FileUploadProps.md +19 -19
  136. package/docs/api/interfaces/FooterProps.md +1 -1
  137. package/docs/api/interfaces/FormFieldProps.md +166 -0
  138. package/docs/api/interfaces/FormProps.md +113 -0
  139. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  140. package/docs/api/interfaces/InactivityWarningModalProps.md +8 -8
  141. package/docs/api/interfaces/InputProps.md +2 -2
  142. package/docs/api/interfaces/LabelProps.md +8 -8
  143. package/docs/api/interfaces/LoginFormProps.md +1 -1
  144. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  145. package/docs/api/interfaces/NavigationContextType.md +1 -1
  146. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  147. package/docs/api/interfaces/NavigationItem.md +17 -73
  148. package/docs/api/interfaces/NavigationMenuProps.md +38 -53
  149. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  150. package/docs/api/interfaces/Organisation.md +13 -13
  151. package/docs/api/interfaces/OrganisationContextType.md +21 -21
  152. package/docs/api/interfaces/OrganisationMembership.md +15 -15
  153. package/docs/api/interfaces/OrganisationProviderProps.md +59 -2
  154. package/docs/api/interfaces/OrganisationSecurityError.md +5 -5
  155. package/docs/api/interfaces/PaceAppLayoutProps.md +26 -39
  156. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  157. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  158. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  159. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  160. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  161. package/docs/api/interfaces/PaletteData.md +1 -1
  162. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  163. package/docs/api/interfaces/ProgressProps.md +50 -0
  164. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  165. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  166. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  167. package/docs/api/interfaces/PublicPageLayoutProps.md +15 -15
  168. package/docs/api/interfaces/RBACAccessValidateParams.md +52 -0
  169. package/docs/api/interfaces/RBACAccessValidateResult.md +41 -0
  170. package/docs/api/interfaces/RBACAuditLogParams.md +85 -0
  171. package/docs/api/interfaces/RBACAuditLogResult.md +52 -0
  172. package/docs/api/interfaces/RBACConfig.md +2 -2
  173. package/docs/api/interfaces/RBACContext.md +52 -0
  174. package/docs/api/interfaces/RBACLogger.md +1 -1
  175. package/docs/api/interfaces/RBACPageAccessCheckParams.md +74 -0
  176. package/docs/api/interfaces/RBACPermissionCheckParams.md +74 -0
  177. package/docs/api/interfaces/RBACPermissionCheckResult.md +52 -0
  178. package/docs/api/interfaces/RBACPermissionsGetParams.md +63 -0
  179. package/docs/api/interfaces/RBACPermissionsGetResult.md +63 -0
  180. package/docs/api/interfaces/RBACResult.md +58 -0
  181. package/docs/api/interfaces/RBACRoleGrantParams.md +63 -0
  182. package/docs/api/interfaces/RBACRoleGrantResult.md +52 -0
  183. package/docs/api/interfaces/RBACRoleRevokeParams.md +63 -0
  184. package/docs/api/interfaces/RBACRoleRevokeResult.md +52 -0
  185. package/docs/api/interfaces/RBACRoleValidateParams.md +52 -0
  186. package/docs/api/interfaces/RBACRoleValidateResult.md +63 -0
  187. package/docs/api/interfaces/RBACRolesListParams.md +52 -0
  188. package/docs/api/interfaces/RBACRolesListResult.md +74 -0
  189. package/docs/api/interfaces/RBACSessionTrackParams.md +74 -0
  190. package/docs/api/interfaces/RBACSessionTrackResult.md +52 -0
  191. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  192. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  193. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  194. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  195. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  196. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  197. package/docs/api/interfaces/RouteConfig.md +1 -1
  198. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  199. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  200. package/docs/api/interfaces/SessionRestorationLoaderProps.md +15 -2
  201. package/docs/api/interfaces/StorageConfig.md +1 -1
  202. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  203. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  204. package/docs/api/interfaces/StorageListOptions.md +1 -1
  205. package/docs/api/interfaces/StorageListResult.md +1 -1
  206. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  207. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  208. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  209. package/docs/api/interfaces/StyleImport.md +1 -1
  210. package/docs/api/interfaces/SwitchProps.md +1 -1
  211. package/docs/api/interfaces/TabsContentProps.md +1 -1
  212. package/docs/api/interfaces/TabsListProps.md +1 -1
  213. package/docs/api/interfaces/TabsProps.md +1 -1
  214. package/docs/api/interfaces/TabsTriggerProps.md +43 -2
  215. package/docs/api/interfaces/TextareaProps.md +2 -2
  216. package/docs/api/interfaces/ToastActionElement.md +1 -1
  217. package/docs/api/interfaces/ToastProps.md +1 -1
  218. package/docs/api/interfaces/UnifiedAuthContextType.md +61 -61
  219. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  220. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  221. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  222. package/docs/api/interfaces/UsePublicEventLogoOptions.md +87 -0
  223. package/docs/api/interfaces/UsePublicEventLogoReturn.md +81 -0
  224. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  225. package/docs/api/interfaces/UsePublicEventReturn.md +5 -5
  226. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  227. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  228. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  229. package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
  230. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  231. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  232. package/docs/api/interfaces/UserEventAccess.md +1 -1
  233. package/docs/api/interfaces/UserMenuProps.md +4 -4
  234. package/docs/api/interfaces/UserProfile.md +7 -7
  235. package/docs/api/modules.md +484 -462
  236. package/docs/api-reference/components.md +186 -15
  237. package/docs/api-reference/deprecated.md +376 -0
  238. package/docs/api-reference/hooks.md +149 -19
  239. package/docs/api-reference/providers.md +61 -6
  240. package/docs/api-reference/rpc-functions.md +397 -0
  241. package/docs/api-reference/types.md +135 -78
  242. package/docs/api-reference/utilities.md +51 -380
  243. package/docs/architecture/README.md +49 -3
  244. package/docs/architecture/database-schema-requirements.md +40 -3
  245. package/docs/architecture/rbac-security-architecture.md +41 -4
  246. package/docs/architecture/services.md +127 -42
  247. package/docs/best-practices/README.md +51 -5
  248. package/docs/best-practices/accessibility.md +32 -3
  249. package/docs/best-practices/common-patterns.md +50 -3
  250. package/docs/best-practices/deployment.md +50 -4
  251. package/docs/best-practices/performance.md +50 -3
  252. package/docs/best-practices/security.md +94 -41
  253. package/docs/best-practices/testing.md +33 -4
  254. package/docs/core-concepts/authentication.md +5 -5
  255. package/docs/core-concepts/events.md +3 -3
  256. package/docs/core-concepts/organisations.md +3 -3
  257. package/docs/core-concepts/permissions.md +3 -3
  258. package/docs/core-concepts/rbac-system.md +5 -5
  259. package/docs/documentation-index.md +30 -8
  260. package/docs/getting-started/documentation-index.md +1 -1
  261. package/docs/getting-started/examples/README.md +7 -5
  262. package/docs/getting-started/examples/basic-auth-app.md +3 -0
  263. package/docs/getting-started/examples/full-featured-app.md +5 -3
  264. package/docs/getting-started/faq.md +6 -6
  265. package/docs/getting-started/installation-guide.md +192 -13
  266. package/docs/getting-started/local-development.md +303 -0
  267. package/docs/getting-started/quick-reference.md +3 -3
  268. package/docs/getting-started/quick-start.md +517 -0
  269. package/docs/implementation-guides/app-layout.md +45 -3
  270. package/docs/implementation-guides/authentication.md +66 -7
  271. package/docs/implementation-guides/component-styling.md +53 -3
  272. package/docs/implementation-guides/data-tables.md +76 -7
  273. package/docs/implementation-guides/datatable-filtering.md +1 -2
  274. package/docs/implementation-guides/datatable-rbac-usage.md +0 -1
  275. package/docs/implementation-guides/dynamic-colors.md +155 -4
  276. package/docs/implementation-guides/file-reference-system.md +72 -3
  277. package/docs/implementation-guides/file-upload-storage.md +72 -3
  278. package/docs/implementation-guides/forms.md +53 -3
  279. package/docs/implementation-guides/inactivity-tracking.md +53 -3
  280. package/docs/implementation-guides/large-datasets.md +1 -1
  281. package/docs/implementation-guides/navigation.md +55 -5
  282. package/docs/implementation-guides/organisation-security.md +72 -3
  283. package/docs/implementation-guides/performance.md +57 -1
  284. package/docs/implementation-guides/permission-enforcement.md +81 -8
  285. package/docs/implementation-guides/public-pages.md +560 -14
  286. package/docs/migration/MIGRATION_GUIDE.md +409 -50
  287. package/docs/migration/README.md +37 -3
  288. package/docs/migration/organisation-context-timing-fix.md +39 -4
  289. package/docs/migration/quick-migration-guide.md +41 -5
  290. package/docs/migration/rbac-migration.md +59 -3
  291. package/docs/migration/service-architecture.md +77 -14
  292. package/docs/rbac/README.md +79 -3
  293. package/docs/rbac/advanced-patterns.md +47 -3
  294. package/docs/rbac/api-reference.md +77 -8
  295. package/docs/rbac/event-based-apps.md +50 -5
  296. package/docs/rbac/examples/rbac-rls-integration-example.md +3 -3
  297. package/docs/rbac/examples.md +39 -3
  298. package/docs/rbac/getting-started.md +63 -4
  299. package/docs/rbac/quick-start.md +57 -5
  300. package/docs/rbac/rbac-rls-integration.md +68 -6
  301. package/docs/rbac/super-admin-guide.md +47 -3
  302. package/docs/rbac/troubleshooting.md +3 -3
  303. package/docs/security/README.md +68 -3
  304. package/docs/security/checklist.md +50 -3
  305. package/docs/standards/01-architecture-standard.md +39 -0
  306. package/docs/standards/02-api-and-rpc-standard.md +39 -0
  307. package/docs/standards/03-component-standard.md +32 -0
  308. package/docs/standards/04-code-style-standard.md +32 -0
  309. package/docs/standards/05-security-standard.md +30 -0
  310. package/docs/standards/06-testing-and-docs-standard.md +29 -0
  311. package/docs/standards/README.md +35 -0
  312. package/docs/styles/README.md +89 -8
  313. package/docs/testing/README.md +175 -24
  314. package/docs/troubleshooting/README.md +50 -3
  315. package/docs/troubleshooting/common-issues.md +271 -5
  316. package/docs/troubleshooting/debugging.md +54 -1
  317. package/docs/troubleshooting/migration.md +54 -1
  318. package/docs/troubleshooting/organisation-context-setup.md +29 -3
  319. package/docs/troubleshooting/styling-issues.md +246 -4
  320. package/{src/components/DataTable/examples → examples/DataTable}/GroupingAggregationExample.tsx +1 -1
  321. package/examples/{components 2/DataTable/HierarchicalActionsExample.tsx → DataTable/HierarchicalActionsExample.tsx} +7 -6
  322. package/{src/components/DataTable/examples → examples/DataTable}/HierarchicalExample.tsx +8 -6
  323. package/examples/{components 2/DataTable/PerformanceExample.tsx → DataTable/PerformanceExample.tsx} +2 -2
  324. package/examples/{components 2/DataTable/index.ts → DataTable/index.ts} +1 -0
  325. package/{src/components/Dialog/examples → examples/Dialog}/HtmlDialogExample.tsx +3 -3
  326. package/examples/{components 2/Dialog/ScrollableDialogExample.tsx → Dialog/ScrollableDialogExample.tsx} +1 -1
  327. package/{src/components/Dialog/examples → examples/Dialog}/SmartDialogExample.tsx +1 -1
  328. package/examples/{components 2/Dialog/index.ts → Dialog/index.ts} +0 -3
  329. package/examples/{features/public-pages → PublicPages}/CorrectPublicPageImplementation.tsx +52 -17
  330. package/examples/{features/public-pages → PublicPages}/PublicEventPage.tsx +65 -35
  331. package/examples/{features/public-pages → PublicPages}/PublicPageApp.tsx +52 -18
  332. package/examples/{features/public-pages → PublicPages}/PublicPageUsageExample.tsx +28 -15
  333. package/examples/README.md +81 -33
  334. package/examples/index.ts +14 -12
  335. package/examples/{RBAC → rbac}/CompleteRBACExample.tsx +1 -1
  336. package/examples/{features/rbac → rbac}/EventBasedApp.tsx +4 -4
  337. package/examples/{features/rbac → rbac}/PermissionExample.tsx +5 -3
  338. package/package.json +21 -27
  339. package/src/__tests__/helpers/test-utils.tsx +29 -3
  340. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +7 -5
  341. package/src/components/Alert/Alert.test.tsx +2 -2
  342. package/src/components/Alert/Alert.tsx +4 -4
  343. package/src/components/Avatar/Avatar.test.tsx +17 -6
  344. package/src/components/Badge/Badge.test.tsx +1 -1
  345. package/src/components/Badge/Badge.tsx +2 -2
  346. package/src/components/Button/Button.test.tsx +2 -2
  347. package/src/components/Button/Button.tsx +11 -7
  348. package/src/components/Calendar/Calendar.test.tsx +41 -8
  349. package/src/components/Calendar/Calendar.tsx +39 -36
  350. package/src/components/Card/Card.tsx +51 -13
  351. package/src/components/Checkbox/Checkbox.test.tsx +36 -12
  352. package/src/components/DataTable/DataTable.test.tsx +1 -1
  353. package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +13 -7
  354. package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +14 -42
  355. package/src/components/DataTable/__tests__/DataTable.export.test.tsx +13 -10
  356. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +14 -11
  357. package/src/components/DataTable/__tests__/DataTable.hooks.test.tsx +4 -2
  358. package/src/components/DataTable/__tests__/DataTable.test.tsx +13 -7
  359. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +13 -10
  360. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +15 -11
  361. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +12 -6
  362. package/src/components/DataTable/__tests__/keyboard.test.tsx +12 -6
  363. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +10 -6
  364. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +1 -1
  365. package/src/components/DataTable/components/DataTableBody.tsx +10 -25
  366. package/src/components/DataTable/components/DataTableCore.tsx +1 -1
  367. package/src/components/DataTable/components/FilterRow.tsx +3 -1
  368. package/src/components/DataTable/components/ImportModal.tsx +1 -1
  369. package/src/components/DataTable/components/VirtualizedDataTable.tsx +9 -9
  370. package/src/components/DataTable/core/ColumnFactory.ts +6 -6
  371. package/src/components/DataTable/core/DataTableContext.tsx +14 -10
  372. package/src/components/DataTable/core/LocalDataAdapter.ts +2 -1
  373. package/src/components/DataTable/core/PluginRegistry.ts +3 -3
  374. package/src/components/DataTable/core/StateManager.ts +12 -11
  375. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +104 -0
  376. package/src/components/DataTable/core/__tests__/DataManager.test.ts +101 -0
  377. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +84 -0
  378. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +102 -0
  379. package/src/components/DataTable/core/__tests__/StateManager.test.ts +104 -0
  380. package/src/components/DataTable/core/interfaces.ts +17 -17
  381. package/src/components/DataTable/hooks/__tests__/useDataTableConfiguration.test.ts +124 -0
  382. package/src/components/DataTable/hooks/__tests__/useDataTableDataPipeline.test.ts +117 -0
  383. package/src/components/DataTable/hooks/__tests__/useDataTablePermissions.test.ts +102 -0
  384. package/src/components/DataTable/hooks/__tests__/useEffectiveColumnOrder.test.ts +53 -0
  385. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +0 -2
  386. package/src/components/DataTable/hooks/useDataTablePermissions.ts +9 -8
  387. package/src/components/DataTable/types.ts +5 -5
  388. package/src/components/DataTable/utils/aggregationUtils.ts +4 -4
  389. package/src/components/DataTable/utils/columnUtils.ts +3 -2
  390. package/src/components/DataTable/utils/debugTools.ts +1 -1
  391. package/src/components/DataTable/utils/exportUtils.ts +6 -6
  392. package/src/components/DataTable/utils/hierarchicalSorting.ts +6 -6
  393. package/src/components/DataTable/utils/hierarchicalUtils.ts +0 -8
  394. package/src/components/DataTable/utils/index.ts +0 -1
  395. package/src/components/DataTable/utils/performanceUtils.ts +9 -4
  396. package/src/components/Dialog/Dialog.test.tsx +49 -27
  397. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +13 -8
  398. package/src/components/EventSelector/EventSelector.test.tsx +60 -12
  399. package/src/components/EventSelector/EventSelector.tsx +38 -15
  400. package/src/components/EventSelector/index.ts +2 -2
  401. package/src/components/FileDisplay/FileDisplay.test.tsx +143 -85
  402. package/src/components/FileDisplay/FileDisplay.tsx +1 -0
  403. package/src/components/FileUpload/FileUpload.test.tsx +532 -152
  404. package/src/components/FileUpload/FileUpload.tsx +43 -8
  405. package/src/components/Footer/Footer.test.tsx +19 -14
  406. package/src/components/Form/Form.test.tsx +96 -14
  407. package/src/components/Form/Form.tsx +210 -1
  408. package/src/components/Form/index.ts +3 -7
  409. package/src/components/Header/Header.test.tsx +24 -17
  410. package/src/components/Header/Header.tsx +3 -1
  411. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -4
  412. package/src/components/Input/Input.test.tsx +61 -36
  413. package/src/components/Label/{__tests__/Label.test.tsx → Label.test.tsx} +2 -2
  414. package/src/components/Label/Label.tsx +2 -3
  415. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +6 -5
  416. package/src/components/LoadingSpinner/LoadingSpinner.tsx +6 -2
  417. package/src/components/LoginForm/LoginForm.test.tsx +14 -13
  418. package/src/components/LoginForm/LoginForm.tsx +1 -1
  419. package/src/components/LoginForm/index.ts +7 -0
  420. package/src/components/NavigationMenu/NavigationMenu.test.tsx +233 -20
  421. package/src/components/NavigationMenu/NavigationMenu.tsx +191 -55
  422. package/src/components/NavigationMenu/index.ts +1 -1
  423. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +20 -11
  424. package/src/components/OrganisationSelector/OrganisationSelector.tsx +1 -1
  425. package/src/components/PaceAppLayout/{__tests__/PaceAppLayout.integration.test.tsx → PaceAppLayout.integration.test.tsx} +272 -79
  426. package/src/components/PaceAppLayout/{__tests__/PaceAppLayout.performance.test.tsx → PaceAppLayout.performance.test.tsx} +155 -32
  427. package/src/components/PaceAppLayout/{__tests__/PaceAppLayout.security.test.tsx → PaceAppLayout.security.test.tsx} +211 -65
  428. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +498 -210
  429. package/src/components/PaceAppLayout/PaceAppLayout.tsx +63 -64
  430. package/src/components/PaceAppLayout/test-setup.tsx +192 -0
  431. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +193 -39
  432. package/src/components/{PasswordReset → PasswordChange}/PasswordChangeForm.test.tsx +2 -2
  433. package/src/components/{PasswordReset → PasswordChange}/PasswordChangeForm.tsx +10 -4
  434. package/src/components/PasswordChange/index.ts +2 -0
  435. package/src/components/Progress/Progress.test.tsx +11 -0
  436. package/src/components/Progress/Progress.tsx +1 -1
  437. package/src/components/Progress/index.ts +10 -0
  438. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +2 -1
  439. package/src/components/PublicLayout/PublicLayout.test.tsx +1210 -0
  440. package/src/components/PublicLayout/PublicPageLayout.tsx +190 -36
  441. package/src/components/PublicLayout/PublicPageProvider.tsx +8 -7
  442. package/src/components/PublicLayout/index.ts +10 -28
  443. package/src/components/Select/Select.test.tsx +7 -7
  444. package/src/components/Select/Select.tsx +277 -11
  445. package/src/components/Select/index.ts +1 -2
  446. package/src/components/SessionRestorationLoader/SessionRestorationLoader.test.tsx +232 -0
  447. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +40 -19
  448. package/src/components/Table/{__tests__/Table.test.tsx → Table.test.tsx} +94 -41
  449. package/src/components/Tabs/Tabs.test.tsx +10 -9
  450. package/src/components/Tabs/Tabs.tsx +61 -33
  451. package/src/components/Textarea/Textarea.test.tsx +31 -18
  452. package/src/components/Toast/Toast.tsx +2 -2
  453. package/src/components/Tooltip/Tooltip.test.tsx +1 -1
  454. package/src/components/UserMenu/UserMenu.test.tsx +7 -6
  455. package/src/components/UserMenu/UserMenu.tsx +2 -2
  456. package/src/components/index.ts +5 -4
  457. package/src/constants/performance.ts +19 -8
  458. package/src/hooks/__tests__/useAppConfig.unit.test.ts +21 -22
  459. package/src/hooks/__tests__/useEvents.unit.test.ts +5 -4
  460. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +2 -2
  461. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -0
  462. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +16 -11
  463. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +1 -3
  464. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +1 -3
  465. package/src/hooks/__tests__/useRBAC.unit.test.ts +24 -2
  466. package/src/hooks/index.ts +4 -0
  467. package/src/hooks/public/index.ts +2 -0
  468. package/src/hooks/public/usePublicEvent.ts +4 -6
  469. package/src/hooks/public/usePublicEventLogo.test.ts +147 -0
  470. package/src/hooks/public/usePublicRouteParams.ts +1 -1
  471. package/src/hooks/services/useAuth.ts +2 -4
  472. package/src/hooks/services/useCurrentEvent.ts +1 -1
  473. package/src/hooks/useAppConfig.ts +1 -1
  474. package/src/hooks/useDataTablePerformance.ts +2 -2
  475. package/src/hooks/useEventTheme.ts +1 -1
  476. package/src/hooks/useEvents.ts +51 -10
  477. package/src/hooks/useOrganisationPermissions.test.ts +3 -3
  478. package/src/hooks/useOrganisationPermissions.ts +1 -1
  479. package/src/hooks/useOrganisationSecurity.ts +2 -2
  480. package/src/hooks/usePermissionCache.test.ts +9 -9
  481. package/src/hooks/usePermissionCache.ts +2 -2
  482. package/src/index.ts +19 -12
  483. package/src/providers/OrganisationProvider.tsx +73 -9
  484. package/src/providers/UnifiedAuthProvider.smoke.test.tsx +113 -13
  485. package/src/providers/__tests__/AuthProvider.test.tsx +2 -1
  486. package/src/providers/__tests__/EventProvider.test.tsx +24 -15
  487. package/src/providers/__tests__/OrganisationProvider.test.tsx +87 -36
  488. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +80 -24
  489. package/src/providers/index.ts +0 -3
  490. package/src/providers/services/AuthServiceProvider.tsx +2 -17
  491. package/src/providers/services/EventServiceProvider.tsx +11 -16
  492. package/src/providers/services/InactivityServiceProvider.tsx +9 -12
  493. package/src/providers/services/OrganisationServiceProvider.tsx +9 -12
  494. package/src/providers/services/UnifiedAuthProvider.tsx +85 -18
  495. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +11 -4
  496. package/src/rbac/__tests__/scenarios.user-role.test.tsx +105 -21
  497. package/src/rbac/adapters.tsx +1 -1
  498. package/src/rbac/api.ts +20 -4
  499. package/src/rbac/audit-enhanced.ts +47 -2
  500. package/src/rbac/audit.ts +47 -2
  501. package/src/rbac/components/NavigationGuard.tsx +1 -1
  502. package/src/rbac/components/NavigationProvider.test.tsx +7 -6
  503. package/src/rbac/components/NavigationProvider.tsx +1 -1
  504. package/src/rbac/components/PagePermissionGuard.tsx +1 -1
  505. package/src/rbac/components/PagePermissionProvider.test.tsx +7 -6
  506. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  507. package/src/rbac/components/PermissionEnforcer.tsx +1 -1
  508. package/src/rbac/components/RoleBasedRouter.tsx +1 -1
  509. package/src/rbac/components/SecureDataProvider.test.tsx +7 -6
  510. package/src/rbac/components/SecureDataProvider.tsx +1 -1
  511. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +6 -6
  512. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +11 -10
  513. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +10 -11
  514. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +19 -15
  515. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +13 -12
  516. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +19 -15
  517. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +18 -18
  518. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +11 -10
  519. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +8 -7
  520. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +10 -11
  521. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +48 -19
  522. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +476 -0
  523. package/src/rbac/hooks/index.ts +3 -0
  524. package/src/rbac/hooks/usePermissions.ts +31 -85
  525. package/src/rbac/hooks/useRBAC.test.ts +13 -1
  526. package/src/rbac/hooks/useRBAC.ts +13 -67
  527. package/src/rbac/hooks/useResolvedScope.ts +11 -0
  528. package/src/rbac/hooks/useSecureSupabase.ts +308 -0
  529. package/src/rbac/index.ts +3 -0
  530. package/src/rbac/secureClient.ts +53 -6
  531. package/src/rbac/security.ts +37 -1
  532. package/src/{types/rbac-functions.ts → rbac/types/functions.ts} +30 -30
  533. package/src/rbac/types.ts +3 -2
  534. package/src/services/AuthService.ts +33 -25
  535. package/src/services/EventService.ts +56 -44
  536. package/src/services/InactivityService.ts +33 -53
  537. package/src/services/OrganisationService.ts +36 -40
  538. package/src/services/__tests__/AuthService.restoreSession.test.ts +6 -2
  539. package/src/services/__tests__/EventService.test.ts +67 -33
  540. package/src/services/interfaces/IEventService.ts +1 -1
  541. package/src/styles/core.css +2 -2
  542. package/src/styles/index.test.ts +21 -0
  543. package/src/styles/index.ts +1 -5
  544. package/src/types/__tests__/guards.test.ts +1 -1
  545. package/src/types/__tests__/organisation.roles.test.ts +55 -0
  546. package/src/types/__tests__/type-validation.test.ts +0 -1
  547. package/src/types/auth.ts +42 -2
  548. package/src/types/core.ts +251 -0
  549. package/src/types/database.ts +11 -496
  550. package/src/types/event.ts +102 -0
  551. package/src/types/file-reference.ts +6 -4
  552. package/src/types/guards.ts +2 -1
  553. package/src/types/index.ts +48 -14
  554. package/src/types/lodash.debounce.d.ts +15 -0
  555. package/src/types/organisation.ts +14 -10
  556. package/src/types/supabase.ts +15 -17
  557. package/src/utils/__tests__/secureErrors.unit.test.ts +1 -1
  558. package/src/utils/__tests__/validationUtils.unit.test.ts +0 -29
  559. package/src/utils/app/appNameResolver.ts +1 -1
  560. package/src/utils/audit/audit.test.ts +65 -0
  561. package/src/utils/device/deviceFingerprint.test.ts +171 -0
  562. package/src/utils/dynamic/dynamicUtils.ts +3 -2
  563. package/src/utils/file-reference/index.ts +25 -6
  564. package/src/utils/security/secureErrors.ts +1 -1
  565. package/src/utils/validation/__tests__/validationUtils.test.ts +72 -0
  566. package/src/utils/validation/index.ts +6 -12
  567. package/src/utils/validation/validationUtils.ts +0 -13
  568. package/dist/UnifiedAuthProvider-B37ATQHE.js +0 -16
  569. package/dist/auth-DReDSLq9.d.ts +0 -16
  570. package/dist/chunk-3JI76CYK.js +0 -2444
  571. package/dist/chunk-3JI76CYK.js.map +0 -1
  572. package/dist/chunk-56XJ3TU6.js +0 -11
  573. package/dist/chunk-56XJ3TU6.js.map +0 -1
  574. package/dist/chunk-5MT24GKJ.js.map +0 -1
  575. package/dist/chunk-7QCC6MCP.js +0 -288
  576. package/dist/chunk-BESYRHQM.js.map +0 -1
  577. package/dist/chunk-BJPBT3CU.js +0 -21
  578. package/dist/chunk-BJPBT3CU.js.map +0 -1
  579. package/dist/chunk-BVYWGZVV.js.map +0 -1
  580. package/dist/chunk-CX5M4ZAG.js.map +0 -1
  581. package/dist/chunk-D7LCGMVS.js.map +0 -1
  582. package/dist/chunk-EGI6MUL6.js +0 -27
  583. package/dist/chunk-EGI6MUL6.js.map +0 -1
  584. package/dist/chunk-ERISIBYU.js.map +0 -1
  585. package/dist/chunk-HRO5HWN2.js.map +0 -1
  586. package/dist/chunk-HZLDFOE4.js.map +0 -1
  587. package/dist/chunk-JISYG63F.js +0 -70
  588. package/dist/chunk-JISYG63F.js.map +0 -1
  589. package/dist/chunk-LIMSTKYD.js +0 -61
  590. package/dist/chunk-LIMSTKYD.js.map +0 -1
  591. package/dist/chunk-OWAG3GSU.js.map +0 -1
  592. package/dist/chunk-PPMP5J6T.js.map +0 -1
  593. package/dist/chunk-Q5QRDWKI.js.map +0 -1
  594. package/dist/chunk-S5OFRT4M.js.map +0 -1
  595. package/dist/chunk-SBVILCCA.js.map +0 -1
  596. package/dist/chunk-TUMEWN34.js +0 -15
  597. package/dist/chunk-TUMEWN34.js.map +0 -1
  598. package/dist/chunk-XDNLUEXI.js +0 -138
  599. package/dist/chunk-XJ2HZOBU.js.map +0 -1
  600. package/dist/chunk-ZYTYSTO5.js.map +0 -1
  601. package/dist/chunk-ZZ2SS7NI.js +0 -237
  602. package/dist/chunk-ZZ2SS7NI.js.map +0 -1
  603. package/dist/database-C6jy7EOu.d.ts +0 -500
  604. package/dist/organisation-D6qRDtbF.d.ts +0 -93
  605. package/dist/schema-DTDZQe2u.d.ts +0 -28
  606. package/dist/unified-DQ4VcT7H.d.ts +0 -198
  607. package/dist/useInactivityTracker-TO6ZOF35.js +0 -11
  608. package/dist/validation.d.ts +0 -47
  609. package/dist/validation.js +0 -24
  610. package/dist/validation.js.map +0 -1
  611. package/docs/DOCUMENTATION_AUDIT.md +0 -172
  612. package/docs/DOCUMENTATION_STANDARD.md +0 -137
  613. package/docs/api/classes/PublicErrorBoundary.md +0 -132
  614. package/docs/api/interfaces/EventLogoProps.md +0 -152
  615. package/docs/api/interfaces/PublicErrorBoundaryProps.md +0 -94
  616. package/docs/api/interfaces/PublicErrorBoundaryState.md +0 -68
  617. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +0 -86
  618. package/docs/architecture/rpc-function-standards.md +0 -1106
  619. package/docs/getting-started/consuming-app-vite-config.md +0 -239
  620. package/docs/implementation-guides/event-theming-summary.md +0 -226
  621. package/docs/implementation-guides/public-pages-advanced.md +0 -1038
  622. package/docs/migration/v0.4.15-tailwind-scanning.md +0 -278
  623. package/docs/migration/v0.4.16-css-first-approach.md +0 -312
  624. package/docs/migration/v0.4.17-source-path-fix.md +0 -235
  625. package/docs/rbac/RBAC_EVENT_CONTEXT_LOADING.md +0 -222
  626. package/docs/rbac/RBAC_LOGIN_SAFETY_FIX.md +0 -95
  627. package/docs/rbac/RBAC_V0.5.147_FIX.md +0 -117
  628. package/docs/rbac/README-rbac-rls-integration.md +0 -374
  629. package/docs/styles/usage.md +0 -227
  630. package/docs/testing/visual-testing.md +0 -120
  631. package/docs/troubleshooting/DEBUG_NETWORK_ERROR.md +0 -152
  632. package/docs/troubleshooting/FIX_SUPABASE_CORS.md +0 -184
  633. package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +0 -193
  634. package/docs/troubleshooting/database-view-compatibility.md +0 -125
  635. package/docs/troubleshooting/react-hooks-issue-analysis.md +0 -172
  636. package/docs/troubleshooting/tailwind-content-scanning.md +0 -219
  637. package/examples/RBAC/EventBasedApp.tsx +0 -239
  638. package/examples/RBAC/PermissionExample.tsx +0 -151
  639. package/examples/STRUCTURE.md +0 -125
  640. package/examples/components 2/DataTable/HierarchicalExample.tsx +0 -475
  641. package/examples/components 2/Dialog/BasicHtmlTest.tsx +0 -55
  642. package/examples/components 2/Dialog/DebugHtmlExample.tsx +0 -68
  643. package/examples/components 2/Dialog/HtmlDialogExample.tsx +0 -202
  644. package/examples/components 2/Dialog/SimpleHtmlTest.tsx +0 -61
  645. package/examples/components 2/Dialog/SmartDialogExample.tsx +0 -322
  646. package/examples/components 2/index.ts +0 -11
  647. package/examples/features/index.ts +0 -12
  648. package/examples/features/rbac/CompleteRBACExample.tsx +0 -324
  649. package/examples/features/rbac/index.ts +0 -13
  650. package/examples/public-pages/CorrectPublicPageImplementation.tsx +0 -301
  651. package/examples/public-pages/PublicEventPage.tsx +0 -274
  652. package/examples/public-pages/PublicPageApp.tsx +0 -308
  653. package/examples/public-pages/PublicPageUsageExample.tsx +0 -216
  654. package/examples/public-pages/index.ts +0 -14
  655. package/src/__tests__/TEST_STANDARD.md +0 -1008
  656. package/src/components/Checkbox/__mocks__/Checkbox.tsx +0 -2
  657. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +0 -421
  658. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +0 -177
  659. package/src/components/DataTable/examples/PerformanceExample.tsx +0 -506
  660. package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +0 -316
  661. package/src/components/DataTable/examples/__tests__/HierarchicalExample.test.tsx +0 -45
  662. package/src/components/DataTable/examples/__tests__/InitialPageSizeExample.test.tsx +0 -211
  663. package/src/components/DataTable/examples/__tests__/PerformanceExample.test.tsx +0 -126
  664. package/src/components/Dialog/README.md +0 -804
  665. package/src/components/Dialog/examples/BasicHtmlTest.tsx +0 -55
  666. package/src/components/Dialog/examples/DebugHtmlExample.tsx +0 -68
  667. package/src/components/Dialog/examples/ScrollableDialogExample.tsx +0 -290
  668. package/src/components/Dialog/examples/SimpleHtmlTest.tsx +0 -61
  669. package/src/components/Dialog/examples/__tests__/HtmlDialogExample.test.tsx +0 -71
  670. package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +0 -122
  671. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +0 -147
  672. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +0 -611
  673. package/src/components/Dialog/utils/safeHtml.ts +0 -185
  674. package/src/components/EventSelector/types.ts +0 -79
  675. package/src/components/Form/FormErrorSummary.tsx +0 -113
  676. package/src/components/Form/FormField.tsx +0 -249
  677. package/src/components/Form/FormFieldset.tsx +0 -127
  678. package/src/components/Form/FormLiveRegion.tsx +0 -198
  679. package/src/components/Input/__mocks__/Input.tsx +0 -2
  680. package/src/components/NavigationMenu/types.ts +0 -85
  681. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +0 -326
  682. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -1078
  683. package/src/components/PasswordReset/PasswordResetForm.test.tsx +0 -597
  684. package/src/components/PasswordReset/PasswordResetForm.tsx +0 -201
  685. package/src/components/PasswordReset/index.ts +0 -2
  686. package/src/components/ProtectedRoute/README.md +0 -164
  687. package/src/components/PublicLayout/EventLogo.tsx +0 -175
  688. package/src/components/PublicLayout/PublicErrorBoundary.tsx +0 -282
  689. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +0 -216
  690. package/src/components/PublicLayout/PublicPageContextChecker.tsx +0 -131
  691. package/src/components/PublicLayout/PublicPageDebugger.tsx +0 -104
  692. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +0 -162
  693. package/src/components/PublicLayout/PublicPageFooter.tsx +0 -124
  694. package/src/components/PublicLayout/PublicPageHeader.tsx +0 -209
  695. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +0 -449
  696. package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +0 -393
  697. package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +0 -192
  698. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +0 -351
  699. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +0 -402
  700. package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +0 -460
  701. package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +0 -313
  702. package/src/components/Select/hooks.ts +0 -289
  703. package/src/hooks/useCounter.test.ts +0 -131
  704. package/src/hooks/useDebounce.test.ts +0 -375
  705. package/src/providers/AuthProvider.tsx +0 -15
  706. package/src/providers/EventProvider.tsx +0 -16
  707. package/src/providers/InactivityProvider.tsx +0 -15
  708. package/src/providers/OrganisationProvider.context.test.tsx +0 -169
  709. package/src/providers/UnifiedAuthProvider.tsx +0 -15
  710. package/src/types/theme.ts +0 -6
  711. package/src/types/unified.ts +0 -265
  712. package/src/utils/appConfig.ts +0 -47
  713. package/src/utils/appIdResolver.test.ts +0 -499
  714. package/src/utils/appIdResolver.ts +0 -130
  715. package/src/utils/appNameResolver.simple.test.ts +0 -212
  716. package/src/utils/appNameResolver.test.ts +0 -121
  717. package/src/utils/appNameResolver.ts +0 -191
  718. package/src/utils/audit.ts +0 -127
  719. package/src/utils/auth-utils.ts +0 -96
  720. package/src/utils/bundleAnalysis.ts +0 -129
  721. package/src/utils/debugLogger.ts +0 -67
  722. package/src/utils/deviceFingerprint.ts +0 -215
  723. package/src/utils/dynamicUtils.ts +0 -105
  724. package/src/utils/file-reference.test.ts +0 -788
  725. package/src/utils/file-reference.ts +0 -519
  726. package/src/utils/formatDate.test.ts +0 -237
  727. package/src/utils/formatting.ts +0 -170
  728. package/src/utils/lazyLoad.tsx +0 -44
  729. package/src/utils/logger.ts +0 -179
  730. package/src/utils/organisationContext.test.ts +0 -322
  731. package/src/utils/organisationContext.ts +0 -153
  732. package/src/utils/performanceBenchmark.ts +0 -64
  733. package/src/utils/performanceBudgets.ts +0 -110
  734. package/src/utils/permissionTypes.ts +0 -37
  735. package/src/utils/permissionUtils.test.ts +0 -393
  736. package/src/utils/permissionUtils.ts +0 -34
  737. package/src/utils/sanitization.ts +0 -264
  738. package/src/utils/schemaUtils.ts +0 -37
  739. package/src/utils/secureDataAccess.test.ts +0 -711
  740. package/src/utils/secureDataAccess.ts +0 -377
  741. package/src/utils/secureErrors.ts +0 -79
  742. package/src/utils/security.ts +0 -156
  743. package/src/utils/securityMonitor.ts +0 -45
  744. package/src/utils/sessionTracking.ts +0 -126
  745. package/src/utils/validation.ts +0 -111
  746. package/src/utils/validationUtils.ts +0 -120
  747. package/src/validation/index.ts +0 -12
  748. /package/dist/{DataTable-UA6CL4JI.js.map → DataTable-QAB34V6K.js.map} +0 -0
  749. /package/dist/{UnifiedAuthProvider-B37ATQHE.js.map → UnifiedAuthProvider-7F6T4B6K.js.map} +0 -0
  750. /package/dist/{api-45XYYO2A.js.map → api-ROMBCNKU.js.map} +0 -0
  751. /package/dist/{audit-64X3VJXB.js.map → audit-WRS3KJKI.js.map} +0 -0
  752. /package/dist/{chunk-PLDDJCW6.js.map → chunk-7D4SUZUM.js.map} +0 -0
  753. /package/dist/{useInactivityTracker-TO6ZOF35.js.map → chunk-KQCRWDSA.js.map} +0 -0
  754. /package/examples/{components 2/DataTable → DataTable}/InitialPageSizeExample.tsx +0 -0
  755. /package/examples/{features/public-pages → PublicPages}/index.ts +0 -0
  756. /package/examples/{RBAC → rbac}/index.ts +0 -0
@@ -1,2444 +0,0 @@
1
- import {
2
- init_organisationContext,
3
- init_secureStorage,
4
- secureStorage,
5
- setOrganisationContext
6
- } from "./chunk-7QCC6MCP.js";
7
- import {
8
- createLogger,
9
- init_logger,
10
- logger
11
- } from "./chunk-XDNLUEXI.js";
12
- import {
13
- __esm
14
- } from "./chunk-PLDDJCW6.js";
15
-
16
- // src/services/base/BaseService.ts
17
- var BaseService;
18
- var init_BaseService = __esm({
19
- "src/services/base/BaseService.ts"() {
20
- "use strict";
21
- init_logger();
22
- BaseService = class {
23
- constructor() {
24
- this.subscribers = [];
25
- this.isInitialized = false;
26
- }
27
- /**
28
- * Subscribe to state changes
29
- * @param callback Function to call when state changes
30
- * @returns Unsubscribe function
31
- */
32
- subscribe(callback) {
33
- this.subscribers.push(callback);
34
- return () => {
35
- const index = this.subscribers.indexOf(callback);
36
- if (index > -1) {
37
- this.subscribers.splice(index, 1);
38
- }
39
- };
40
- }
41
- /**
42
- * Notify all subscribers of state changes
43
- * This triggers React re-renders
44
- */
45
- notify() {
46
- this.subscribers.forEach((callback) => {
47
- try {
48
- callback();
49
- } catch (error) {
50
- logger.error("BaseService", "Error in subscriber callback:", error);
51
- }
52
- });
53
- }
54
- /**
55
- * Initialize the service
56
- * Override in subclasses to implement initialization logic
57
- */
58
- async initialize() {
59
- if (this.isInitialized) {
60
- return;
61
- }
62
- await this.doInitialize();
63
- this.isInitialized = true;
64
- }
65
- /**
66
- * Cleanup the service
67
- * Override in subclasses to implement cleanup logic
68
- */
69
- cleanup() {
70
- this.subscribers = [];
71
- this.doCleanup();
72
- this.isInitialized = false;
73
- }
74
- /**
75
- * Check if service is initialized
76
- */
77
- getInitialized() {
78
- return this.isInitialized;
79
- }
80
- /**
81
- * Reset initialization state (allows re-initialization)
82
- * Use when dependencies change and service needs to re-initialize
83
- */
84
- resetInitialization() {
85
- this.isInitialized = false;
86
- }
87
- };
88
- }
89
- });
90
-
91
- // src/services/AuthService.ts
92
- import { AuthError } from "@supabase/supabase-js";
93
- var AuthService;
94
- var init_AuthService = __esm({
95
- "src/services/AuthService.ts"() {
96
- "use strict";
97
- init_BaseService();
98
- init_logger();
99
- AuthService = class extends BaseService {
100
- constructor(supabaseClient, appName) {
101
- super();
102
- this.user = null;
103
- this.session = null;
104
- this.authLoading = false;
105
- this.authError = null;
106
- this.supabaseClient = null;
107
- this.authStateSubscription = null;
108
- this.sessionRestorationState = {
109
- isRestoring: false,
110
- restorationComplete: false,
111
- restorationError: null
112
- };
113
- this.restorationTimeoutId = null;
114
- this.restorationTimeoutMs = 5e3;
115
- this.restorationStartTime = null;
116
- this.appName = void 0;
117
- this.supabaseClient = supabaseClient;
118
- this.appName = appName;
119
- }
120
- // Auth state getters
121
- getUser() {
122
- return this.user;
123
- }
124
- getSession() {
125
- return this.session;
126
- }
127
- isAuthenticated() {
128
- return !!(this.user && this.session);
129
- }
130
- isLoading() {
131
- return this.authLoading;
132
- }
133
- getError() {
134
- return this.authError;
135
- }
136
- getSupabaseClient() {
137
- return this.supabaseClient;
138
- }
139
- getSessionRestorationState() {
140
- return { ...this.sessionRestorationState };
141
- }
142
- // Auth methods
143
- async signIn(email, password) {
144
- if (!this.supabaseClient) {
145
- const error = new AuthError("Supabase client not available");
146
- this.authError = error;
147
- this.notify();
148
- return { user: null, session: null, error };
149
- }
150
- try {
151
- const { data, error } = await this.supabaseClient.auth.signInWithPassword({
152
- email,
153
- password: password || ""
154
- });
155
- if (error) {
156
- this.authError = error;
157
- this.user = null;
158
- this.session = null;
159
- } else {
160
- this.authError = null;
161
- this.user = data.user;
162
- this.session = data.session;
163
- }
164
- this.notify();
165
- return { user: data.user, session: data.session, error };
166
- } catch (error) {
167
- const authError = error instanceof AuthError ? error : new AuthError(error instanceof Error ? error.message : "Authentication failed");
168
- this.authError = authError;
169
- this.user = null;
170
- this.session = null;
171
- this.notify();
172
- return { user: null, session: null, error: authError };
173
- }
174
- }
175
- async signUp(email, password) {
176
- if (!this.supabaseClient) {
177
- const error = new AuthError("Supabase client not available");
178
- this.authError = error;
179
- this.notify();
180
- return { user: null, session: null, error };
181
- }
182
- try {
183
- const { data, error } = await this.supabaseClient.auth.signUp({
184
- email,
185
- password
186
- });
187
- if (error) {
188
- this.authError = error;
189
- this.user = null;
190
- this.session = null;
191
- } else {
192
- this.authError = null;
193
- this.user = data.user;
194
- this.session = data.session;
195
- }
196
- this.notify();
197
- return { user: data.user, session: data.session, error };
198
- } catch (error) {
199
- const authError = error instanceof AuthError ? error : new AuthError(error instanceof Error ? error.message : "Authentication failed");
200
- this.authError = authError;
201
- this.user = null;
202
- this.session = null;
203
- this.notify();
204
- return { user: null, session: null, error: authError };
205
- }
206
- }
207
- async signOut() {
208
- if (!this.supabaseClient) {
209
- const error = new AuthError("Supabase client not available");
210
- this.authError = error;
211
- this.notify();
212
- return { user: null, session: null, error };
213
- }
214
- try {
215
- const { error } = await this.supabaseClient.auth.signOut();
216
- if (error) {
217
- this.authError = error;
218
- } else {
219
- this.authError = null;
220
- this.user = null;
221
- this.session = null;
222
- }
223
- this.notify();
224
- return { user: null, session: null, error };
225
- } catch (error) {
226
- const authError = error instanceof AuthError ? error : new AuthError(error instanceof Error ? error.message : "Authentication failed");
227
- this.authError = authError;
228
- this.user = null;
229
- this.session = null;
230
- this.notify();
231
- return { user: null, session: null, error: authError };
232
- }
233
- }
234
- async resetPassword(email) {
235
- if (!this.supabaseClient) {
236
- const error = new AuthError("Supabase client not available");
237
- this.authError = error;
238
- this.notify();
239
- return { user: null, session: null, error };
240
- }
241
- try {
242
- const { error } = await this.supabaseClient.auth.resetPasswordForEmail(email);
243
- if (error) {
244
- this.authError = error;
245
- } else {
246
- this.authError = null;
247
- }
248
- this.notify();
249
- return { user: null, session: null, error };
250
- } catch (error) {
251
- const authError = error instanceof AuthError ? error : new AuthError(error instanceof Error ? error.message : "Authentication failed");
252
- this.authError = authError;
253
- this.notify();
254
- return { user: null, session: null, error: authError };
255
- }
256
- }
257
- async updatePassword(password) {
258
- if (!this.supabaseClient) {
259
- const error = new AuthError("Supabase client not available");
260
- this.authError = error;
261
- this.notify();
262
- return { user: null, session: null, error };
263
- }
264
- try {
265
- const { error } = await this.supabaseClient.auth.updateUser({
266
- password
267
- });
268
- if (error) {
269
- this.authError = error;
270
- } else {
271
- this.authError = null;
272
- }
273
- this.notify();
274
- return { user: null, session: null, error };
275
- } catch (error) {
276
- const authError = error;
277
- this.authError = authError;
278
- this.notify();
279
- return { user: null, session: null, error: authError };
280
- }
281
- }
282
- async refreshSession() {
283
- if (!this.supabaseClient) {
284
- const error = new AuthError("Supabase client not available");
285
- this.authError = error;
286
- this.notify();
287
- return { user: null, session: null, error };
288
- }
289
- try {
290
- const { data, error } = await this.supabaseClient.auth.refreshSession();
291
- if (error) {
292
- this.authError = error;
293
- this.user = null;
294
- this.session = null;
295
- } else {
296
- this.authError = null;
297
- if (data?.user && data?.session) {
298
- this.user = data.user;
299
- this.session = data.session;
300
- } else {
301
- this.user = null;
302
- this.session = null;
303
- }
304
- }
305
- this.notify();
306
- return {
307
- user: data?.user && data?.session ? data.user : null,
308
- session: data?.session ?? null,
309
- error
310
- };
311
- } catch (error) {
312
- const authError = error instanceof AuthError ? error : new AuthError(error instanceof Error ? error.message : "Authentication failed");
313
- this.authError = authError;
314
- this.user = null;
315
- this.session = null;
316
- this.notify();
317
- return { user: null, session: null, error: authError };
318
- }
319
- }
320
- // Lifecycle methods
321
- async initialize() {
322
- await super.initialize();
323
- await this.setupAuthStateListener();
324
- await this.restoreSession();
325
- }
326
- cleanup() {
327
- if (this.authStateSubscription && typeof this.authStateSubscription.unsubscribe === "function") {
328
- this.authStateSubscription.unsubscribe();
329
- this.authStateSubscription = null;
330
- }
331
- this.clearRestorationTimeout();
332
- this.restorationStartTime = null;
333
- this.sessionRestorationState = {
334
- isRestoring: false,
335
- restorationComplete: false,
336
- restorationError: null
337
- };
338
- this.authLoading = false;
339
- super.cleanup();
340
- }
341
- async doInitialize() {
342
- this.setupErrorHandlers();
343
- }
344
- doCleanup() {
345
- this.removeErrorHandlers();
346
- }
347
- startSessionRestoration() {
348
- this.clearRestorationTimeout();
349
- this.sessionRestorationState = {
350
- isRestoring: true,
351
- restorationComplete: false,
352
- restorationError: null
353
- };
354
- this.authLoading = true;
355
- this.restorationStartTime = Date.now();
356
- logger.debug("AuthService", "Starting session restoration at", this.restorationStartTime);
357
- this.notify();
358
- this.restorationTimeoutId = setTimeout(() => {
359
- logger.warn("AuthService", "Session restoration timed out after", this.restorationTimeoutMs, "ms");
360
- const timeoutError = new Error(`Session restoration timed out after ${this.restorationTimeoutMs}ms`);
361
- timeoutError.name = "SessionRestorationTimeoutError";
362
- this.finishSessionRestoration(timeoutError);
363
- }, this.restorationTimeoutMs);
364
- }
365
- finishSessionRestoration(error) {
366
- if (!this.sessionRestorationState.isRestoring && !error) {
367
- return;
368
- }
369
- this.clearRestorationTimeout();
370
- const completedAt = Date.now();
371
- const duration = this.restorationStartTime ? completedAt - this.restorationStartTime : null;
372
- this.restorationStartTime = null;
373
- const restorationComplete = !error;
374
- this.sessionRestorationState = {
375
- isRestoring: false,
376
- restorationComplete,
377
- restorationError: error ?? null
378
- };
379
- this.authLoading = false;
380
- if (error) {
381
- logger.warn("AuthService", "Session restoration finished with error:", error, "duration(ms):", duration ?? "unknown");
382
- } else {
383
- logger.debug("AuthService", "Session restoration completed successfully in", duration ?? "unknown", "ms");
384
- }
385
- this.notify();
386
- }
387
- clearRestorationTimeout() {
388
- if (this.restorationTimeoutId) {
389
- clearTimeout(this.restorationTimeoutId);
390
- this.restorationTimeoutId = null;
391
- }
392
- }
393
- async setupAuthStateListener() {
394
- if (!this.supabaseClient) {
395
- this.authLoading = false;
396
- this.notify();
397
- return;
398
- }
399
- try {
400
- this.authStateSubscription = this.supabaseClient.auth.onAuthStateChange(
401
- (event, session) => {
402
- try {
403
- logger.debug("AuthService", "Auth state change event received:", event);
404
- if (event === "SIGNED_OUT") {
405
- this.session = null;
406
- this.user = null;
407
- this.authError = null;
408
- if (session?.user) {
409
- this.trackSession("logout", session).catch((err) => {
410
- logger.warn("AuthService", "Failed to track logout session:", err);
411
- });
412
- }
413
- } else if (event === "SIGNED_IN" || event === "TOKEN_REFRESHED") {
414
- this.session = session;
415
- this.user = session?.user ?? null;
416
- if (session) {
417
- this.authError = null;
418
- }
419
- if (event === "SIGNED_IN" && session?.user) {
420
- this.trackSession("login", session).catch((err) => {
421
- logger.warn("AuthService", "Failed to track login session:", err);
422
- });
423
- }
424
- } else if (event === "INITIAL_SESSION") {
425
- if (session) {
426
- this.session = session;
427
- this.user = session.user ?? null;
428
- this.authError = null;
429
- const hasTimeoutError = this.sessionRestorationState.restorationError?.name === "SessionRestorationTimeoutError";
430
- if (this.sessionRestorationState.isRestoring || this.sessionRestorationState.restorationError || hasTimeoutError && session) {
431
- this.finishSessionRestoration();
432
- return;
433
- }
434
- }
435
- if (this.sessionRestorationState.isRestoring) {
436
- this.finishSessionRestoration();
437
- return;
438
- }
439
- }
440
- this.authLoading = false;
441
- this.notify();
442
- } catch (error) {
443
- logger.warn("AuthService", "Error in auth state change handler:", error);
444
- this.authLoading = false;
445
- this.notify();
446
- }
447
- }
448
- );
449
- } catch (error) {
450
- logger.error("AuthService", "Failed to setup auth state listener:", error);
451
- throw error;
452
- }
453
- }
454
- async restoreSession() {
455
- if (!this.supabaseClient) {
456
- const error = new Error("Supabase client not available during session restoration");
457
- logger.error("AuthService", "Unable to restore session:", error);
458
- this.finishSessionRestoration(error);
459
- return;
460
- }
461
- this.startSessionRestoration();
462
- try {
463
- logger.debug("AuthService", "Fetching existing session from Supabase");
464
- let currentSession = null;
465
- let sessionError = null;
466
- try {
467
- const { data, error } = await this.supabaseClient.auth.getSession();
468
- currentSession = data?.session ?? null;
469
- sessionError = error ?? null;
470
- } catch (error) {
471
- logger.debug("AuthService", "getSession unavailable, treating as no active session");
472
- currentSession = null;
473
- sessionError = null;
474
- }
475
- if (sessionError) {
476
- logger.debug("AuthService", "getSession returned error, attempting to fetch user anyway");
477
- this.authError = sessionError;
478
- try {
479
- const { data, error } = await this.supabaseClient.auth.getUser();
480
- const currentUser = data?.user ?? null;
481
- const userError = error ?? null;
482
- if (currentUser) {
483
- this.user = currentUser;
484
- this.session = null;
485
- }
486
- if (userError && !this.authError) {
487
- this.authError = userError;
488
- }
489
- } catch (getUserError) {
490
- logger.debug("AuthService", "getUser also failed:", getUserError);
491
- }
492
- }
493
- if (currentSession) {
494
- this.session = currentSession;
495
- this.user = currentSession.user;
496
- this.authError = null;
497
- } else if (!sessionError) {
498
- logger.debug("AuthService", "No active session found; treating as normal unauthenticated state");
499
- this.session = null;
500
- this.user = null;
501
- this.authError = null;
502
- }
503
- this.finishSessionRestoration();
504
- } catch (error) {
505
- const restorationError = error instanceof Error ? error : new Error("Unknown error during auth initialization");
506
- logger.error("AuthService", "Error during auth initialization:", restorationError);
507
- if (restorationError instanceof AuthError) {
508
- this.authError = restorationError;
509
- }
510
- this.finishSessionRestoration(restorationError);
511
- }
512
- }
513
- /**
514
- * Automatically track user session using rbac_session_track
515
- * This method is called automatically on SIGNED_IN and SIGNED_OUT events.
516
- * It's non-blocking and failures are logged as warnings.
517
- */
518
- async trackSession(sessionType, session) {
519
- if (!this.supabaseClient || !session?.user) {
520
- return;
521
- }
522
- try {
523
- let appId = void 0;
524
- if (this.appName) {
525
- const { data, error: error2 } = await this.supabaseClient.from("rbac_apps").select("id").eq("name", this.appName).eq("is_active", true).single();
526
- if (!error2 && data) {
527
- appId = data.id;
528
- }
529
- }
530
- const ipAddress = void 0;
531
- const userAgent = typeof navigator !== "undefined" ? navigator.userAgent : void 0;
532
- const deviceFingerprint = void 0;
533
- const { error } = await this.supabaseClient.rpc("rbac_session_track", {
534
- p_user_id: session.user.id,
535
- p_session_type: sessionType,
536
- p_event_id: null,
537
- // Event ID should come from context, not auth service
538
- p_app_id: appId,
539
- p_ip_address: ipAddress,
540
- p_user_agent: userAgent,
541
- p_device_fingerprint: deviceFingerprint
542
- });
543
- if (error) {
544
- logger.warn("AuthService", `Failed to track ${sessionType} session:`, error);
545
- } else {
546
- logger.debug("AuthService", `Successfully tracked ${sessionType} session`);
547
- }
548
- } catch (error) {
549
- logger.warn("AuthService", `Error tracking ${sessionType} session:`, error);
550
- }
551
- }
552
- setupErrorHandlers() {
553
- if (typeof window === "undefined") return;
554
- const handleError = (event) => {
555
- if (event.error?.message?.includes("AuthSessionMissingError") || event.error?.message?.includes("Auth session missing")) {
556
- logger.warn("AuthService", "Suppressing AuthSessionMissingError during logout");
557
- event.preventDefault();
558
- return false;
559
- }
560
- };
561
- const handleUnhandledRejection = (event) => {
562
- if (event.reason?.message?.includes("AuthSessionMissingError") || event.reason?.message?.includes("Auth session missing")) {
563
- logger.warn("AuthService", "Suppressing unhandled AuthSessionMissingError");
564
- event.preventDefault();
565
- return false;
566
- }
567
- };
568
- window.addEventListener("error", handleError);
569
- window.addEventListener("unhandledrejection", handleUnhandledRejection);
570
- }
571
- removeErrorHandlers() {
572
- if (typeof window === "undefined") return;
573
- }
574
- };
575
- }
576
- });
577
-
578
- // src/providers/services/AuthServiceProvider.tsx
579
- import { createContext, useContext, useMemo, useEffect, useState } from "react";
580
- import { jsx } from "react/jsx-runtime";
581
- function AuthServiceProvider({ children, supabaseClient, appName }) {
582
- const authService = useMemo(
583
- () => new AuthService(supabaseClient, appName),
584
- [supabaseClient, appName]
585
- );
586
- const [sessionRestoration, setSessionRestoration] = useState(
587
- () => authService.getSessionRestorationState()
588
- );
589
- useEffect(() => {
590
- const unsubscribe = authService.subscribe(() => {
591
- const restorationState = authService.getSessionRestorationState();
592
- setSessionRestoration(restorationState);
593
- const isDev = typeof import.meta !== "undefined" && (import.meta.env.DEV || import.meta.env.MODE === "development");
594
- if (isDev) {
595
- logger.debug("AuthServiceProvider", "Session restoration state updated", restorationState);
596
- }
597
- });
598
- return () => {
599
- unsubscribe();
600
- };
601
- }, [authService]);
602
- useEffect(() => {
603
- authService.initialize().catch((error) => {
604
- logger.error("AuthServiceProvider", "Failed to initialize auth service:", error);
605
- });
606
- return () => {
607
- authService.cleanup();
608
- };
609
- }, [authService]);
610
- const contextValue = useMemo(() => ({
611
- authService,
612
- sessionRestoration
613
- }), [authService, sessionRestoration]);
614
- return /* @__PURE__ */ jsx(AuthServiceContext.Provider, { value: contextValue, children });
615
- }
616
- var AuthServiceContext, useAuthService;
617
- var init_AuthServiceProvider = __esm({
618
- "src/providers/services/AuthServiceProvider.tsx"() {
619
- "use strict";
620
- init_AuthService();
621
- init_logger();
622
- AuthServiceContext = createContext(null);
623
- useAuthService = () => {
624
- const context = useContext(AuthServiceContext);
625
- if (!context) {
626
- throw new Error("useAuthService must be used within AuthServiceProvider");
627
- }
628
- return context.authService;
629
- };
630
- }
631
- });
632
-
633
- // src/services/OrganisationService.ts
634
- var OrganisationService;
635
- var init_OrganisationService = __esm({
636
- "src/services/OrganisationService.ts"() {
637
- "use strict";
638
- init_BaseService();
639
- init_organisationContext();
640
- init_logger();
641
- OrganisationService = class extends BaseService {
642
- constructor(supabaseClient, user, session) {
643
- super();
644
- this._selectedOrganisation = null;
645
- this._organisations = [];
646
- this._userMemberships = [];
647
- this._roleMapState = /* @__PURE__ */ new Map();
648
- this._isLoading = false;
649
- this._error = null;
650
- this._isContextReady = false;
651
- this.retryCount = 0;
652
- // Dependencies
653
- this.supabaseClient = null;
654
- this.user = null;
655
- this.session = null;
656
- // Internal state management
657
- this.isLoadingRef = false;
658
- this.lastLoadTimeRef = 0;
659
- this.hasFailedRef = false;
660
- this.abortControllerRef = null;
661
- this.supabaseClient = supabaseClient;
662
- this.user = user;
663
- this.session = session;
664
- }
665
- // Interface implementation
666
- getSelectedOrganisation() {
667
- return this._selectedOrganisation;
668
- }
669
- getOrganisations() {
670
- return this._organisations;
671
- }
672
- getUserMemberships() {
673
- return this._userMemberships;
674
- }
675
- isLoading() {
676
- return this._isLoading;
677
- }
678
- getError() {
679
- return this._error;
680
- }
681
- hasValidOrganisationContext() {
682
- return !!(this._selectedOrganisation && !this._isLoading && !this._error && this._isContextReady);
683
- }
684
- isContextReady() {
685
- return this._isContextReady;
686
- }
687
- // Additional methods for testing
688
- setSelectedOrganisation(organisation) {
689
- this._selectedOrganisation = organisation;
690
- if (organisation) {
691
- localStorage.setItem("pace-core-selected-organisation", JSON.stringify(organisation));
692
- this.setDatabaseOrganisationContext(organisation);
693
- } else {
694
- localStorage.removeItem("pace-core-selected-organisation");
695
- this._isContextReady = false;
696
- }
697
- this.notify();
698
- }
699
- // For testing: expose dependencies
700
- getDependencies() {
701
- return {
702
- user: this.user,
703
- session: this.session,
704
- supabaseClient: this.supabaseClient
705
- };
706
- }
707
- // For testing: manually set state
708
- setTestState(organisations, memberships, roleMap, selectedOrg = null) {
709
- this._organisations = organisations;
710
- this._userMemberships = memberships;
711
- this._roleMapState = roleMap;
712
- if (selectedOrg) {
713
- this._selectedOrganisation = selectedOrg;
714
- } else if (organisations.length > 0) {
715
- this._selectedOrganisation = organisations[0];
716
- }
717
- this._isLoading = false;
718
- this._error = null;
719
- this.notify();
720
- }
721
- // Update dependencies
722
- updateDependencies(user, session) {
723
- const wasAuthenticated = !!(this.user && this.session);
724
- const isAuthenticated = !!(user && session);
725
- this.user = user;
726
- this.session = session;
727
- if (wasAuthenticated && !isAuthenticated) {
728
- this.isInitialized = false;
729
- }
730
- this.notify();
731
- }
732
- // Organisation methods
733
- async switchOrganisation(orgId) {
734
- if (!this.validateOrganisationAccess(orgId)) {
735
- throw new Error(`User does not have access to organisation ${orgId}`);
736
- }
737
- const targetOrg = this._organisations.find((org) => org.id === orgId);
738
- if (!targetOrg) {
739
- throw new Error(`Organisation ${orgId} not found in user's organisations`);
740
- }
741
- this._selectedOrganisation = targetOrg;
742
- localStorage.setItem("pace-core-selected-organisation", JSON.stringify(targetOrg));
743
- await this.setDatabaseOrganisationContext(targetOrg);
744
- this.notify();
745
- }
746
- getUserRole(orgId) {
747
- const targetOrgId = orgId || this._selectedOrganisation?.id;
748
- if (!targetOrgId) return "no_access";
749
- return this._roleMapState.get(targetOrgId) || "no_access";
750
- }
751
- validateOrganisationAccess(orgId) {
752
- return this._userMemberships.some(
753
- (m) => m.organisation_id === orgId && m.status === "active" && m.revoked_at === null
754
- );
755
- }
756
- async refreshOrganisations() {
757
- if (!this.user || !this.session || !this.supabaseClient) return;
758
- this._isLoading = true;
759
- this.notify();
760
- await this.loadUserOrganisations();
761
- }
762
- ensureOrganisationContext() {
763
- if (!this._selectedOrganisation) {
764
- throw new Error("Organisation context is required but not available");
765
- }
766
- return this._selectedOrganisation;
767
- }
768
- isOrganisationSecure() {
769
- return !!(this._selectedOrganisation && this.user);
770
- }
771
- getPrimaryOrganisation() {
772
- const rolePriority = ["org_admin", "leader", "member"];
773
- for (const role of rolePriority) {
774
- const membership = this._userMemberships.find((m) => m.role === role);
775
- if (membership) {
776
- return this._organisations.find((org) => org.id === membership.organisation_id) || null;
777
- }
778
- }
779
- return null;
780
- }
781
- buildOrganisationHierarchy(orgs) {
782
- const orgMap = /* @__PURE__ */ new Map();
783
- orgs.forEach((org) => orgMap.set(org.id, org));
784
- const roots = [];
785
- orgs.forEach((org) => {
786
- if (!org.parent_id) {
787
- roots.push({
788
- organisation: org,
789
- children: [],
790
- depth: 0
791
- });
792
- }
793
- });
794
- return roots;
795
- }
796
- // Lifecycle methods
797
- async initialize() {
798
- await super.initialize();
799
- if (!this.isLoadingRef) {
800
- await this.loadUserOrganisations();
801
- }
802
- }
803
- cleanup() {
804
- this.isLoadingRef = false;
805
- this.hasFailedRef = false;
806
- this.lastLoadTimeRef = 0;
807
- if (this.abortControllerRef) {
808
- this.abortControllerRef = null;
809
- }
810
- this._selectedOrganisation = null;
811
- this._organisations = [];
812
- this._userMemberships = [];
813
- this._roleMapState = /* @__PURE__ */ new Map();
814
- this._isLoading = false;
815
- this._error = null;
816
- this._isContextReady = false;
817
- super.cleanup();
818
- }
819
- async doInitialize() {
820
- }
821
- doCleanup() {
822
- }
823
- async setDatabaseOrganisationContext(organisation) {
824
- if (!this.supabaseClient || !this.session) {
825
- logger.warn("OrganisationService", "No Supabase client or session available for setting organisation context");
826
- this._isContextReady = false;
827
- this.notify();
828
- return;
829
- }
830
- try {
831
- logger.debug("OrganisationService", "Setting database organisation context for:", organisation.id);
832
- const timeoutPromise = new Promise((_, reject) => {
833
- setTimeout(() => reject(new Error("Context setting timeout after 5 seconds")), 5e3);
834
- });
835
- const contextPromise = setOrganisationContext(this.supabaseClient, organisation.id);
836
- await Promise.race([contextPromise, timeoutPromise]);
837
- logger.debug("OrganisationService", "Database organisation context set successfully");
838
- this._isContextReady = true;
839
- this.notify();
840
- } catch (error) {
841
- logger.error("OrganisationService", "Failed to set database organisation context:", error);
842
- this._isContextReady = true;
843
- this.notify();
844
- }
845
- }
846
- async loadUserOrganisations() {
847
- const callId = Math.random().toString(36).substr(2, 9);
848
- logger.debug("OrganisationService", `Starting loadUserOrganisations call ${callId}`);
849
- if (!this.user || !this.session || !this.supabaseClient) {
850
- this._selectedOrganisation = null;
851
- this._organisations = [];
852
- this._userMemberships = [];
853
- this._isLoading = false;
854
- this._error = null;
855
- this.notify();
856
- return;
857
- }
858
- if (this.isLoadingRef) {
859
- logger.debug("OrganisationService", "Already loading, skipping duplicate load");
860
- this._isLoading = true;
861
- this.notify();
862
- return;
863
- }
864
- const now = Date.now();
865
- if (now - this.lastLoadTimeRef < 2e3) {
866
- logger.debug("OrganisationService", "Too soon since last load, skipping");
867
- if (this._organisations.length > 0 || this._selectedOrganisation) {
868
- this._isLoading = false;
869
- } else {
870
- this._isLoading = true;
871
- }
872
- this.notify();
873
- return;
874
- }
875
- if (this.abortControllerRef) {
876
- this.abortControllerRef.abort();
877
- }
878
- this.abortControllerRef = new AbortController();
879
- const abortSignal = this.abortControllerRef.signal;
880
- this.lastLoadTimeRef = now;
881
- this.isLoadingRef = true;
882
- this._isLoading = true;
883
- this._error = null;
884
- this.notify();
885
- try {
886
- logger.debug("OrganisationService", "Supabase client ready:", {
887
- isConnected: !!this.supabaseClient,
888
- hasAuth: !!this.supabaseClient.auth,
889
- hasRpc: !!this.supabaseClient.rpc
890
- });
891
- let memberships, membershipError;
892
- try {
893
- logger.debug("OrganisationService", "Making RPC call to data_user_organisation_roles_get...");
894
- const timeoutPromise = new Promise((_, reject) => {
895
- const timeoutId = setTimeout(() => reject(new Error("RPC call timeout after 10 seconds")), 1e4);
896
- abortSignal.addEventListener("abort", () => {
897
- clearTimeout(timeoutId);
898
- reject(new Error("Request aborted"));
899
- });
900
- });
901
- const rpcPromise = this.supabaseClient.rpc("data_user_organisation_roles_get", {
902
- p_user_id: this.user.id,
903
- p_organisation_id: null
904
- });
905
- if (abortSignal.aborted) {
906
- throw new Error("Request aborted");
907
- }
908
- const result = await Promise.race([rpcPromise, timeoutPromise]);
909
- logger.debug("OrganisationService", "RPC call completed:", {
910
- hasData: !!result.data,
911
- hasError: !!result.error,
912
- dataLength: result.data?.length || 0,
913
- errorMessage: result.error?.message || "No error"
914
- });
915
- memberships = result.data?.filter(
916
- (role) => ["org_admin", "leader", "member"].includes(role.role)
917
- ) || [];
918
- membershipError = result.error;
919
- } catch (queryError) {
920
- membershipError = queryError;
921
- }
922
- if (membershipError) {
923
- logger.error("OrganisationService", "Error loading memberships:", membershipError);
924
- if (membershipError.message?.includes("timeout")) {
925
- logger.debug("OrganisationService", "RPC timed out, trying direct database query as fallback...");
926
- try {
927
- if (abortSignal.aborted) {
928
- throw new Error("Request aborted");
929
- }
930
- const { data: fallbackData, error: fallbackError } = await this.supabaseClient.from("rbac_organisation_roles").select(`
931
- id,
932
- user_id,
933
- organisation_id,
934
- role,
935
- status,
936
- granted_at,
937
- granted_by,
938
- revoked_at,
939
- revoked_by,
940
- notes,
941
- created_at,
942
- updated_at,
943
- organisations!inner(
944
- id,
945
- name,
946
- display_name,
947
- subscription_tier,
948
- settings,
949
- is_active,
950
- parent_id,
951
- created_at,
952
- updated_at
953
- )
954
- `).eq("user_id", this.user.id).eq("status", "active").is("revoked_at", null).in("role", ["org_admin", "leader", "member"]);
955
- if (fallbackError) {
956
- logger.error("OrganisationService", "Fallback query also failed:", fallbackError);
957
- throw membershipError;
958
- }
959
- logger.debug("OrganisationService", "Fallback query successful, got", fallbackData?.length || 0, "memberships");
960
- memberships = fallbackData || [];
961
- membershipError = null;
962
- } catch (fallbackErr) {
963
- logger.error("OrganisationService", "Fallback query failed:", fallbackErr);
964
- throw membershipError;
965
- }
966
- } else {
967
- throw membershipError;
968
- }
969
- }
970
- if (!memberships || memberships.length === 0) {
971
- throw new Error("User has no active organisation memberships");
972
- }
973
- const organisationIds = memberships.map((m) => m.organisation_id).filter((id) => {
974
- if (!id || typeof id !== "string") {
975
- logger.warn("OrganisationService", "Invalid organisation ID (not string):", id);
976
- return false;
977
- }
978
- const trimmedId = id.trim();
979
- if (trimmedId === "") {
980
- logger.warn("OrganisationService", "Empty organisation ID found");
981
- return false;
982
- }
983
- const isValidUuid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(trimmedId);
984
- if (!isValidUuid) {
985
- logger.warn("OrganisationService", "Invalid UUID format:", trimmedId);
986
- }
987
- return isValidUuid;
988
- });
989
- if (organisationIds.length === 0) {
990
- logger.warn("OrganisationService", "No valid organisation IDs found in memberships:", memberships);
991
- throw new Error("No valid organisation IDs found in memberships");
992
- }
993
- if (abortSignal.aborted) {
994
- throw new Error("Request aborted");
995
- }
996
- const { data: allOrganisations, error: orgError } = await this.supabaseClient.from("organisations").select("id, name, display_name, subscription_tier, settings, is_active, parent_id, created_at, updated_at");
997
- if (orgError) {
998
- logger.error("OrganisationService", "Error loading organisations:", orgError);
999
- throw orgError;
1000
- }
1001
- const organisations = allOrganisations?.filter(
1002
- (org) => organisationIds.includes(org.id)
1003
- ) || [];
1004
- const roleMap = /* @__PURE__ */ new Map();
1005
- memberships?.forEach((membership) => {
1006
- roleMap.set(membership.organisation_id, membership.role);
1007
- });
1008
- const orgs = organisations;
1009
- const activeOrgs = orgs.filter((org) => org.is_active);
1010
- if (activeOrgs.length === 0) {
1011
- throw new Error("User has no access to active organisations");
1012
- }
1013
- this._organisations = activeOrgs;
1014
- this._userMemberships = memberships;
1015
- this._roleMapState = roleMap;
1016
- let initialOrg = null;
1017
- try {
1018
- const persistedOrgString = localStorage.getItem("pace-core-selected-organisation");
1019
- if (persistedOrgString) {
1020
- const persistedOrg = JSON.parse(persistedOrgString);
1021
- if (persistedOrg.id && typeof persistedOrg.id === "string" && persistedOrg.id.trim() !== "") {
1022
- const validPersistedOrg = activeOrgs.find((org) => org.id === persistedOrg.id);
1023
- if (validPersistedOrg) {
1024
- initialOrg = validPersistedOrg;
1025
- } else {
1026
- logger.warn("OrganisationService", "Persisted organisation not found in active orgs, clearing cache");
1027
- localStorage.removeItem("pace-core-selected-organisation");
1028
- }
1029
- } else {
1030
- logger.warn("OrganisationService", "Invalid persisted organisation ID, clearing cache");
1031
- localStorage.removeItem("pace-core-selected-organisation");
1032
- }
1033
- }
1034
- } catch (storageError) {
1035
- logger.warn("OrganisationService", "Failed to restore persisted organisation:", storageError);
1036
- localStorage.removeItem("pace-core-selected-organisation");
1037
- }
1038
- if (!initialOrg) {
1039
- const adminMembership = memberships.find((m) => m.role === "org_admin");
1040
- if (adminMembership) {
1041
- const foundOrg = organisations.find((org) => org.id === adminMembership.organisation_id);
1042
- if (foundOrg) {
1043
- initialOrg = foundOrg;
1044
- }
1045
- }
1046
- }
1047
- if (!initialOrg) {
1048
- initialOrg = activeOrgs[0];
1049
- }
1050
- if (!initialOrg) {
1051
- throw new Error("No valid organisation found for user");
1052
- }
1053
- this._selectedOrganisation = initialOrg;
1054
- localStorage.setItem("pace-core-selected-organisation", JSON.stringify(initialOrg));
1055
- await this.setDatabaseOrganisationContext(initialOrg);
1056
- this.retryCount = 0;
1057
- this.hasFailedRef = false;
1058
- } catch (err) {
1059
- logger.error("OrganisationService", "Failed to load organisations:", err);
1060
- this._error = err;
1061
- this.retryCount = this.retryCount + 1;
1062
- this.hasFailedRef = true;
1063
- this.clearAllCachedData();
1064
- } finally {
1065
- this.isLoadingRef = false;
1066
- this._isLoading = false;
1067
- this.abortControllerRef = null;
1068
- this.notify();
1069
- }
1070
- }
1071
- clearAllCachedData() {
1072
- localStorage.removeItem("pace-core-selected-organisation");
1073
- localStorage.removeItem("pace-core-organisation-context");
1074
- this._selectedOrganisation = null;
1075
- this._organisations = [];
1076
- this._userMemberships = [];
1077
- this._roleMapState = /* @__PURE__ */ new Map();
1078
- this.retryCount = 0;
1079
- this._isContextReady = false;
1080
- }
1081
- };
1082
- }
1083
- });
1084
-
1085
- // src/providers/services/OrganisationServiceProvider.tsx
1086
- import { createContext as createContext2, useContext as useContext2, useMemo as useMemo2, useEffect as useEffect2, useRef } from "react";
1087
- import { jsx as jsx2 } from "react/jsx-runtime";
1088
- function OrganisationServiceProvider({
1089
- children,
1090
- supabaseClient,
1091
- user,
1092
- session
1093
- }) {
1094
- const organisationServiceRef = useRef(null);
1095
- if (!organisationServiceRef.current) {
1096
- organisationServiceRef.current = new OrganisationService(supabaseClient, user, session);
1097
- }
1098
- const organisationService = organisationServiceRef.current;
1099
- useEffect2(() => {
1100
- organisationService.updateDependencies(user, session);
1101
- let isMounted = true;
1102
- organisationService.initialize().catch((error) => {
1103
- if (isMounted) {
1104
- logger.error("OrganisationServiceProvider", "Failed to initialize organisation service:", error);
1105
- }
1106
- });
1107
- return () => {
1108
- isMounted = false;
1109
- };
1110
- }, [organisationService, user, session]);
1111
- const contextValue = useMemo2(() => ({
1112
- organisationService
1113
- }), [organisationService]);
1114
- return /* @__PURE__ */ jsx2(OrganisationServiceContext.Provider, { value: contextValue, children });
1115
- }
1116
- var OrganisationServiceContext, useOrganisationService;
1117
- var init_OrganisationServiceProvider = __esm({
1118
- "src/providers/services/OrganisationServiceProvider.tsx"() {
1119
- "use strict";
1120
- init_OrganisationService();
1121
- init_logger();
1122
- OrganisationServiceContext = createContext2(null);
1123
- useOrganisationService = () => {
1124
- const context = useContext2(OrganisationServiceContext);
1125
- if (!context) {
1126
- throw new Error("useOrganisationService must be used within OrganisationServiceProvider");
1127
- }
1128
- return context.organisationService;
1129
- };
1130
- }
1131
- });
1132
-
1133
- // src/services/EventService.ts
1134
- var EventService;
1135
- var init_EventService = __esm({
1136
- "src/services/EventService.ts"() {
1137
- "use strict";
1138
- init_BaseService();
1139
- init_logger();
1140
- init_secureStorage();
1141
- EventService = class extends BaseService {
1142
- constructor(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId) {
1143
- super();
1144
- this.events = [];
1145
- this.selectedEvent = null;
1146
- this._isLoading = false;
1147
- // Start as false to avoid blocking UI
1148
- this.error = null;
1149
- // Dependencies
1150
- this.supabaseClient = null;
1151
- this.user = null;
1152
- this.session = null;
1153
- this.appName = "";
1154
- this.selectedOrganisation = null;
1155
- this.setSelectedEventId = null;
1156
- // Internal state management
1157
- this.isInitializedRef = false;
1158
- this.isFetchingRef = false;
1159
- this.hasAutoSelectedRef = false;
1160
- this.userClearedEventRef = false;
1161
- this.supabaseClient = supabaseClient;
1162
- this.user = user;
1163
- this.session = session;
1164
- this.appName = appName;
1165
- this.selectedOrganisation = selectedOrganisation;
1166
- this.setSelectedEventId = setSelectedEventId;
1167
- }
1168
- // Helper method to get user-scoped storage key
1169
- getStorageKey(userId) {
1170
- if (!userId) {
1171
- return "pace-core-selected-event-no-user";
1172
- }
1173
- return `pace-core-selected-event-${userId}`;
1174
- }
1175
- // Update dependencies
1176
- async updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId) {
1177
- const previousOrgId = this.selectedOrganisation?.id;
1178
- const newOrgId = selectedOrganisation?.id;
1179
- const previousUserId = this.user?.id || null;
1180
- const newUserId = user?.id || null;
1181
- if (previousUserId !== newUserId) {
1182
- if (previousUserId !== null) {
1183
- await this.clearEventSelectionForUser(previousUserId);
1184
- }
1185
- if (newUserId === null) {
1186
- this.selectedEvent = null;
1187
- this.setSelectedEventId?.(null);
1188
- }
1189
- }
1190
- this.supabaseClient = supabaseClient;
1191
- this.user = user;
1192
- this.session = session;
1193
- this.appName = appName;
1194
- this.selectedOrganisation = selectedOrganisation;
1195
- this.setSelectedEventId = setSelectedEventId;
1196
- if (previousOrgId !== newOrgId) {
1197
- this.resetInitialization();
1198
- this.isInitializedRef = false;
1199
- this.isFetchingRef = false;
1200
- if (previousOrgId !== null && newOrgId !== previousOrgId) {
1201
- this.events = [];
1202
- this.selectedEvent = null;
1203
- }
1204
- }
1205
- this.notify();
1206
- }
1207
- // Event state getters
1208
- getEvents() {
1209
- return this.events;
1210
- }
1211
- getSelectedEvent() {
1212
- return this.selectedEvent;
1213
- }
1214
- isLoading() {
1215
- return this._isLoading;
1216
- }
1217
- getError() {
1218
- return this.error;
1219
- }
1220
- // Event methods
1221
- setSelectedEvent(event) {
1222
- if (event) {
1223
- try {
1224
- if (this.selectedOrganisation && event.organisation_id !== this.selectedOrganisation.id) {
1225
- logger.error("EventService", "Event organisation_id does not match selected organisation", {
1226
- eventOrganisationId: event.organisation_id,
1227
- selectedOrganisationId: this.selectedOrganisation.id,
1228
- eventName: event.event_name
1229
- });
1230
- return;
1231
- }
1232
- } catch (error) {
1233
- logger.error("EventService", "Error during event validation:", error);
1234
- }
1235
- this.selectedEvent = event;
1236
- this.setSelectedEventId?.(event.event_id);
1237
- this.persistEventSelection(event.event_id).catch((error) => {
1238
- logger.warn("EventService", "Failed to persist event selection:", error);
1239
- });
1240
- this.userClearedEventRef = false;
1241
- } else {
1242
- this.selectedEvent = null;
1243
- this.setSelectedEventId?.(null);
1244
- this.clearEventSelection().catch((error) => {
1245
- logger.warn("EventService", "Failed to clear event selection:", error);
1246
- });
1247
- this.hasAutoSelectedRef = false;
1248
- this.userClearedEventRef = true;
1249
- }
1250
- this.notify();
1251
- }
1252
- async refreshEvents() {
1253
- this.isInitializedRef = false;
1254
- this.isFetchingRef = false;
1255
- await this.fetchEvents();
1256
- }
1257
- async loadPersistedEvent(events) {
1258
- try {
1259
- const userId = this.user?.id || null;
1260
- if (!userId) {
1261
- return false;
1262
- }
1263
- const storageKey = this.getStorageKey(userId);
1264
- const persistedEventId = await secureStorage.getItem(storageKey);
1265
- if (persistedEventId && events.length > 0) {
1266
- const persistedEvent = events.find((event) => event.event_id === persistedEventId);
1267
- if (persistedEvent) {
1268
- this.setSelectedEvent(persistedEvent);
1269
- return true;
1270
- } else {
1271
- await secureStorage.removeItem(storageKey);
1272
- }
1273
- }
1274
- } catch (error) {
1275
- logger.warn("EventService", "Failed to load persisted event:", error);
1276
- }
1277
- return false;
1278
- }
1279
- /**
1280
- * Restore persisted event after login screen has rendered
1281
- * This should be called explicitly from login page component
1282
- *
1283
- * @returns Promise<boolean> - true if event was successfully restored, false otherwise
1284
- */
1285
- async restorePersistedEvent() {
1286
- if (this.events.length === 0) {
1287
- return false;
1288
- }
1289
- return await this.loadPersistedEvent(this.events);
1290
- }
1291
- async persistEventSelection(eventId) {
1292
- try {
1293
- const userId = this.user?.id || null;
1294
- const storageKey = this.getStorageKey(userId);
1295
- await secureStorage.setItem(storageKey, eventId, { encrypt: true });
1296
- } catch (error) {
1297
- logger.warn("EventService", "Failed to persist event selection:", error);
1298
- }
1299
- }
1300
- async clearEventSelection() {
1301
- try {
1302
- const userId = this.user?.id || null;
1303
- const storageKey = this.getStorageKey(userId);
1304
- await secureStorage.removeItem(storageKey);
1305
- this.selectedEvent = null;
1306
- this.setSelectedEventId?.(null);
1307
- } catch (error) {
1308
- logger.warn("EventService", "Failed to clear event selection:", error);
1309
- }
1310
- }
1311
- /**
1312
- * Clear event selection for a specific user (used when user logs out or changes)
1313
- */
1314
- async clearEventSelectionForUser(userId) {
1315
- try {
1316
- if (!userId) return;
1317
- const storageKey = this.getStorageKey(userId);
1318
- await secureStorage.removeItem(storageKey);
1319
- } catch (error) {
1320
- logger.warn("EventService", "Failed to clear event selection for user:", error);
1321
- }
1322
- }
1323
- autoSelectNextEvent(events) {
1324
- const nextEvent = this.getNextEventByDate(events);
1325
- if (nextEvent) {
1326
- this.setSelectedEvent(nextEvent);
1327
- }
1328
- }
1329
- // Lifecycle methods
1330
- async initialize() {
1331
- await super.initialize();
1332
- try {
1333
- if (typeof sessionStorage !== "undefined") {
1334
- sessionStorage.removeItem("pace-core-selected-event");
1335
- }
1336
- if (typeof localStorage !== "undefined") {
1337
- localStorage.removeItem("pace-core-selected-event");
1338
- localStorage.removeItem("_sec_pace-core-selected-event");
1339
- }
1340
- } catch (error) {
1341
- logger.warn("EventService", "Failed to clean up old storage keys:", error);
1342
- }
1343
- await this.fetchEvents(false);
1344
- }
1345
- cleanup() {
1346
- super.cleanup();
1347
- }
1348
- async doInitialize() {
1349
- await this.fetchEvents();
1350
- }
1351
- doCleanup() {
1352
- }
1353
- async fetchEvents(skipLoadPersisted = false) {
1354
- if (!this.user || !this.session || !this.supabaseClient || !this.appName || !this.selectedOrganisation) {
1355
- this.notify();
1356
- return;
1357
- }
1358
- this._isLoading = true;
1359
- this.notify();
1360
- if (this.isFetchingRef) {
1361
- return;
1362
- }
1363
- this.isFetchingRef = true;
1364
- let isMounted = true;
1365
- try {
1366
- logger.debug("EventService", "Fetching events with params:", {
1367
- p_user_id: this.user.id,
1368
- p_organisation_id: this.selectedOrganisation.id,
1369
- p_app_name: this.appName
1370
- });
1371
- const { data, error: rpcError } = await this.supabaseClient.rpc("data_user_events_get", {
1372
- p_user_id: this.user.id,
1373
- p_organisation_id: this.selectedOrganisation.id,
1374
- p_app_name: this.appName
1375
- });
1376
- logger.debug("EventService", "RPC call completed:", {
1377
- hasData: !!data,
1378
- dataLength: Array.isArray(data) ? data.length : 0,
1379
- hasError: !!rpcError,
1380
- errorMessage: rpcError?.message || "No error"
1381
- });
1382
- if (rpcError) {
1383
- logger.error("EventService", "RPC error fetching events:", rpcError);
1384
- throw new Error(rpcError.message || "Failed to fetch events");
1385
- }
1386
- if (isMounted) {
1387
- const eventsData = data || [];
1388
- const transformedEvents = eventsData.map((event) => ({
1389
- id: event.event_id,
1390
- // Use event_id as the primary id
1391
- event_id: event.event_id,
1392
- event_name: event.event_name,
1393
- event_code: event.event_code,
1394
- event_date: event.event_date,
1395
- event_venue: event.event_venue,
1396
- event_participants: event.event_participants,
1397
- event_colours: event.event_colours,
1398
- event_logo: "",
1399
- // No logo field in event table
1400
- organisation_id: event.organisation_id,
1401
- is_visible: event.is_visible,
1402
- // Legacy compatibility
1403
- name: event.event_name,
1404
- start_date: event.event_date
1405
- }));
1406
- this.events = transformedEvents;
1407
- this.error = null;
1408
- this.hasAutoSelectedRef = false;
1409
- if (!skipLoadPersisted) {
1410
- const persistedEventLoaded = await this.loadPersistedEvent(transformedEvents);
1411
- if (!persistedEventLoaded && !this.userClearedEventRef) {
1412
- const nextEvent = this.getNextEventByDate(transformedEvents);
1413
- if (nextEvent) {
1414
- this.hasAutoSelectedRef = true;
1415
- this.setSelectedEvent(nextEvent);
1416
- }
1417
- }
1418
- } else {
1419
- if (!this.userClearedEventRef) {
1420
- const nextEvent = this.getNextEventByDate(transformedEvents);
1421
- if (nextEvent) {
1422
- this.hasAutoSelectedRef = true;
1423
- this.setSelectedEvent(nextEvent);
1424
- }
1425
- }
1426
- }
1427
- }
1428
- } catch (err) {
1429
- logger.error("EventService", "Error fetching events:", err);
1430
- const _error = err instanceof Error ? err : new Error("Unknown error occurred");
1431
- if (isMounted) {
1432
- this.error = _error;
1433
- this.events = [];
1434
- }
1435
- } finally {
1436
- if (isMounted) {
1437
- this._isLoading = false;
1438
- }
1439
- this.isFetchingRef = false;
1440
- this.notify();
1441
- }
1442
- }
1443
- getNextEventByDate(events) {
1444
- const eventsToUse = events || this.events;
1445
- if (!eventsToUse || eventsToUse.length === 0) {
1446
- return null;
1447
- }
1448
- const now = /* @__PURE__ */ new Date();
1449
- const startOfToday = new Date(now.getFullYear(), now.getMonth(), now.getDate()).getTime();
1450
- const futureEvents = eventsToUse.filter((event) => {
1451
- if (!event.event_date) return false;
1452
- const eventDate = new Date(event.event_date);
1453
- const startOfEventDate = new Date(eventDate.getFullYear(), eventDate.getMonth(), eventDate.getDate()).getTime();
1454
- return startOfEventDate >= startOfToday;
1455
- });
1456
- if (futureEvents.length > 0) {
1457
- const sortedFutureEvents = futureEvents.sort((a, b) => {
1458
- const dateA = new Date(a.event_date);
1459
- const dateB = new Date(b.event_date);
1460
- return dateA.getTime() - dateB.getTime();
1461
- });
1462
- return sortedFutureEvents[0];
1463
- }
1464
- const pastEvents = eventsToUse.filter((event) => {
1465
- if (!event.event_date) return false;
1466
- const eventDate = new Date(event.event_date);
1467
- const startOfEventDate = new Date(eventDate.getFullYear(), eventDate.getMonth(), eventDate.getDate()).getTime();
1468
- return startOfEventDate < startOfToday;
1469
- });
1470
- if (pastEvents.length > 0) {
1471
- const sortedPastEvents = pastEvents.sort((a, b) => {
1472
- const dateA = new Date(a.event_date);
1473
- const dateB = new Date(b.event_date);
1474
- return dateB.getTime() - dateA.getTime();
1475
- });
1476
- return sortedPastEvents[0];
1477
- }
1478
- return null;
1479
- }
1480
- };
1481
- }
1482
- });
1483
-
1484
- // src/providers/services/EventServiceProvider.tsx
1485
- import { createContext as createContext3, useContext as useContext3, useMemo as useMemo3, useEffect as useEffect3, useRef as useRef2 } from "react";
1486
- import { jsx as jsx3 } from "react/jsx-runtime";
1487
- function EventServiceProvider({
1488
- children,
1489
- supabaseClient,
1490
- user,
1491
- session,
1492
- appName,
1493
- selectedOrganisation,
1494
- setSelectedEventId
1495
- }) {
1496
- const eventServiceRef = useRef2(null);
1497
- if (!eventServiceRef.current) {
1498
- eventServiceRef.current = new EventService(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
1499
- }
1500
- const eventService = eventServiceRef.current;
1501
- useEffect3(() => {
1502
- let isMounted = true;
1503
- const updateAndInitialize = async () => {
1504
- await eventService.updateDependencies(supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId);
1505
- if (!isMounted) return;
1506
- await eventService.initialize().catch((error) => {
1507
- if (isMounted) {
1508
- logger.error("EventServiceProvider", "Failed to initialize event service:", error);
1509
- }
1510
- });
1511
- };
1512
- updateAndInitialize();
1513
- return () => {
1514
- isMounted = false;
1515
- };
1516
- }, [eventService, supabaseClient, user, session, appName, selectedOrganisation, setSelectedEventId]);
1517
- const contextValue = useMemo3(() => ({
1518
- eventService
1519
- }), [eventService]);
1520
- return /* @__PURE__ */ jsx3(EventServiceContext.Provider, { value: contextValue, children });
1521
- }
1522
- var EventServiceContext, useEventService;
1523
- var init_EventServiceProvider = __esm({
1524
- "src/providers/services/EventServiceProvider.tsx"() {
1525
- "use strict";
1526
- init_EventService();
1527
- init_logger();
1528
- EventServiceContext = createContext3(null);
1529
- useEventService = () => {
1530
- const context = useContext3(EventServiceContext);
1531
- if (!context) {
1532
- throw new Error("useEventService must be used within EventServiceProvider");
1533
- }
1534
- return context.eventService;
1535
- };
1536
- }
1537
- });
1538
-
1539
- // src/services/InactivityService.ts
1540
- var InactivityService;
1541
- var init_InactivityService = __esm({
1542
- "src/services/InactivityService.ts"() {
1543
- "use strict";
1544
- init_BaseService();
1545
- init_logger();
1546
- InactivityService = class extends BaseService {
1547
- constructor(supabaseClient, user, session, idleTimeoutMs = 30 * 60 * 1e3, warnBeforeMs = 60 * 1e3, onIdleLogout) {
1548
- super();
1549
- this._showInactivityWarning = false;
1550
- this._inactivityTimeRemaining = 0;
1551
- this._isIdle = false;
1552
- this._timeRemaining = 0;
1553
- this._showWarning = false;
1554
- this._isTracking = false;
1555
- // Dependencies
1556
- this.supabaseClient = null;
1557
- this.user = null;
1558
- this.session = null;
1559
- this.idleTimeoutMs = 30 * 60 * 1e3;
1560
- // 30 minutes
1561
- this.warnBeforeMs = 60 * 1e3;
1562
- // 60 seconds
1563
- this.onIdleLogout = null;
1564
- // Internal state management
1565
- this.inactivityTracker = null;
1566
- this.isInactivityEnabled = true;
1567
- this.supabaseClient = supabaseClient;
1568
- this.user = user;
1569
- this.session = session;
1570
- this.idleTimeoutMs = idleTimeoutMs;
1571
- this.warnBeforeMs = warnBeforeMs;
1572
- this.onIdleLogout = onIdleLogout;
1573
- this._timeRemaining = idleTimeoutMs;
1574
- }
1575
- // Interface implementation
1576
- isIdle() {
1577
- return this._isIdle;
1578
- }
1579
- getTimeRemaining() {
1580
- return this._timeRemaining;
1581
- }
1582
- isWarningShown() {
1583
- return this._showWarning;
1584
- }
1585
- isTracking() {
1586
- return this._isTracking;
1587
- }
1588
- getShowInactivityWarning() {
1589
- return this._showInactivityWarning;
1590
- }
1591
- getInactivityTimeRemaining() {
1592
- return this._inactivityTimeRemaining;
1593
- }
1594
- // Additional getter methods that tests expect
1595
- getIsIdle() {
1596
- return this._isIdle;
1597
- }
1598
- getIsTracking() {
1599
- return this._isTracking;
1600
- }
1601
- getShowWarning() {
1602
- return this._showWarning;
1603
- }
1604
- // Additional methods for testing
1605
- setShowInactivityWarning(value) {
1606
- this._showInactivityWarning = value;
1607
- this.notify();
1608
- }
1609
- setInactivityTimeRemaining(value) {
1610
- this._inactivityTimeRemaining = value;
1611
- this.notify();
1612
- }
1613
- setIsIdle(value) {
1614
- this._isIdle = value;
1615
- this.notify();
1616
- }
1617
- setTimeRemaining(value) {
1618
- this._timeRemaining = value;
1619
- this.notify();
1620
- }
1621
- setShowWarning(value) {
1622
- this._showWarning = value;
1623
- this.notify();
1624
- }
1625
- setIsTracking(value) {
1626
- this._isTracking = value;
1627
- this.notify();
1628
- }
1629
- triggerWarning(timeRemaining) {
1630
- this._showInactivityWarning = true;
1631
- this._inactivityTimeRemaining = Math.ceil(timeRemaining / 1e3);
1632
- this._showWarning = true;
1633
- this.notify();
1634
- }
1635
- triggerIdle() {
1636
- this._isIdle = true;
1637
- this.handleIdleLogout();
1638
- this.notify();
1639
- }
1640
- // Update dependencies
1641
- updateDependencies(supabaseClient, user, session, idleTimeoutMs, warnBeforeMs, onIdleLogout) {
1642
- this.supabaseClient = supabaseClient;
1643
- this.user = user;
1644
- this.session = session;
1645
- if (idleTimeoutMs !== void 0) this.idleTimeoutMs = idleTimeoutMs;
1646
- if (warnBeforeMs !== void 0) this.warnBeforeMs = warnBeforeMs;
1647
- if (onIdleLogout !== void 0) this.onIdleLogout = onIdleLogout;
1648
- this.notify();
1649
- }
1650
- // Inactivity methods
1651
- resetActivity() {
1652
- if (this.inactivityTracker) {
1653
- this.inactivityTracker.resetActivity();
1654
- }
1655
- this._isIdle = false;
1656
- this._showWarning = false;
1657
- this._showInactivityWarning = false;
1658
- this._inactivityTimeRemaining = 0;
1659
- this._timeRemaining = this.idleTimeoutMs;
1660
- this.notify();
1661
- }
1662
- startTracking() {
1663
- if (this.inactivityTracker) {
1664
- this.inactivityTracker.startTracking();
1665
- }
1666
- this._isTracking = true;
1667
- this.notify();
1668
- }
1669
- stopTracking() {
1670
- if (this.inactivityTracker) {
1671
- this.inactivityTracker.stopTracking();
1672
- }
1673
- this._isTracking = false;
1674
- this.notify();
1675
- }
1676
- async handleIdleLogout() {
1677
- this._showInactivityWarning = false;
1678
- this._inactivityTimeRemaining = 0;
1679
- this.stopTracking();
1680
- try {
1681
- if (this.supabaseClient) {
1682
- await this.supabaseClient.auth.signOut();
1683
- }
1684
- } catch (error) {
1685
- logger.error("InactivityService", "Error during idle logout:", error);
1686
- }
1687
- this.onIdleLogout?.("inactivity");
1688
- this.notify();
1689
- }
1690
- handleStaySignedIn() {
1691
- this._showInactivityWarning = false;
1692
- this._inactivityTimeRemaining = 0;
1693
- this.resetActivity();
1694
- this.notify();
1695
- }
1696
- async handleSignOutNow() {
1697
- this._showInactivityWarning = false;
1698
- this._inactivityTimeRemaining = 0;
1699
- this.stopTracking();
1700
- try {
1701
- if (this.supabaseClient) {
1702
- await this.supabaseClient.auth.signOut();
1703
- }
1704
- } catch (error) {
1705
- logger.error("InactivityService", "Error during manual sign out:", error);
1706
- }
1707
- this.onIdleLogout?.("inactivity");
1708
- this.notify();
1709
- }
1710
- // Lifecycle methods
1711
- async initialize() {
1712
- await super.initialize();
1713
- await this.setupInactivityTracker();
1714
- }
1715
- cleanup() {
1716
- if (this.inactivityTracker) {
1717
- this.inactivityTracker.cleanup?.();
1718
- this.inactivityTracker = null;
1719
- }
1720
- this._isTracking = false;
1721
- this._isIdle = false;
1722
- this._showWarning = false;
1723
- this._showInactivityWarning = false;
1724
- this._timeRemaining = 0;
1725
- this._inactivityTimeRemaining = 0;
1726
- super.cleanup();
1727
- }
1728
- async doInitialize() {
1729
- if (typeof window !== "undefined") {
1730
- const isProduction = import.meta.env.MODE === "production";
1731
- if (isProduction) {
1732
- logger.warn("InactivityService", "Inactivity feature enabled in production");
1733
- }
1734
- }
1735
- }
1736
- doCleanup() {
1737
- }
1738
- async setupInactivityTracker() {
1739
- if (typeof window === "undefined") return;
1740
- this.isInactivityEnabled = this.user && this.session;
1741
- if (!this.isInactivityEnabled) {
1742
- return;
1743
- }
1744
- try {
1745
- const { useInactivityTracker } = await import("./useInactivityTracker-TO6ZOF35.js");
1746
- this.inactivityTracker = {
1747
- isIdle: false,
1748
- timeRemaining: 0,
1749
- showWarning: false,
1750
- isTracking: false,
1751
- resetActivity: () => {
1752
- this._isIdle = false;
1753
- this._timeRemaining = 0;
1754
- this._showWarning = false;
1755
- this.notify();
1756
- },
1757
- startTracking: () => {
1758
- this._isTracking = true;
1759
- this.notify();
1760
- },
1761
- stopTracking: () => {
1762
- this._isTracking = false;
1763
- this.notify();
1764
- },
1765
- cleanup: () => {
1766
- this._isTracking = false;
1767
- this._isIdle = false;
1768
- this._showWarning = false;
1769
- this._timeRemaining = 0;
1770
- }
1771
- };
1772
- this.setupEventHandlers();
1773
- } catch (error) {
1774
- logger.error("InactivityService", "Failed to setup inactivity tracker:", error);
1775
- }
1776
- }
1777
- setupEventHandlers() {
1778
- if (typeof window === "undefined") return;
1779
- let idleTimer = null;
1780
- let warningTimer = null;
1781
- let lastActivity = Date.now();
1782
- const resetTimers = () => {
1783
- lastActivity = Date.now();
1784
- if (idleTimer) {
1785
- clearTimeout(idleTimer);
1786
- idleTimer = null;
1787
- }
1788
- if (warningTimer) {
1789
- clearTimeout(warningTimer);
1790
- warningTimer = null;
1791
- }
1792
- this._showInactivityWarning = false;
1793
- this._inactivityTimeRemaining = 0;
1794
- this._isIdle = false;
1795
- this._showWarning = false;
1796
- this.notify();
1797
- };
1798
- const startIdleTimer = () => {
1799
- if (idleTimer) {
1800
- clearTimeout(idleTimer);
1801
- }
1802
- idleTimer = setTimeout(() => {
1803
- this._isIdle = true;
1804
- this._showWarning = true;
1805
- this.notify();
1806
- warningTimer = setTimeout(() => {
1807
- this.handleIdleLogout();
1808
- }, this.warnBeforeMs);
1809
- }, this.idleTimeoutMs - this.warnBeforeMs);
1810
- };
1811
- const startWarningTimer = () => {
1812
- if (warningTimer) {
1813
- clearTimeout(warningTimer);
1814
- }
1815
- warningTimer = setTimeout(() => {
1816
- this.handleIdleLogout();
1817
- }, this.warnBeforeMs);
1818
- };
1819
- const activityEvents = ["mousedown", "mousemove", "keypress", "scroll", "touchstart", "click"];
1820
- const handleActivity = () => {
1821
- resetTimers();
1822
- startIdleTimer();
1823
- };
1824
- activityEvents.forEach((event) => {
1825
- document.addEventListener(event, handleActivity, true);
1826
- });
1827
- startIdleTimer();
1828
- this.inactivityTracker.cleanup = () => {
1829
- if (idleTimer) {
1830
- clearTimeout(idleTimer);
1831
- idleTimer = null;
1832
- }
1833
- if (warningTimer) {
1834
- clearTimeout(warningTimer);
1835
- warningTimer = null;
1836
- }
1837
- activityEvents.forEach((event) => {
1838
- document.removeEventListener(event, handleActivity, true);
1839
- });
1840
- this._isTracking = false;
1841
- this._isIdle = false;
1842
- this._showWarning = false;
1843
- this._timeRemaining = 0;
1844
- this._showInactivityWarning = false;
1845
- this._inactivityTimeRemaining = 0;
1846
- };
1847
- this._isTracking = true;
1848
- this.notify();
1849
- }
1850
- };
1851
- }
1852
- });
1853
-
1854
- // src/providers/services/InactivityServiceProvider.tsx
1855
- import { createContext as createContext4, useContext as useContext4, useMemo as useMemo4, useEffect as useEffect4, useRef as useRef3 } from "react";
1856
- import { jsx as jsx4 } from "react/jsx-runtime";
1857
- function InactivityServiceProvider({
1858
- children,
1859
- supabaseClient,
1860
- user,
1861
- session,
1862
- idleTimeoutMs = 30 * 60 * 1e3,
1863
- warnBeforeMs = 60 * 1e3,
1864
- onIdleLogout
1865
- }) {
1866
- const inactivityServiceRef = useRef3(null);
1867
- if (!inactivityServiceRef.current) {
1868
- inactivityServiceRef.current = new InactivityService(supabaseClient, user, session, idleTimeoutMs, warnBeforeMs, onIdleLogout);
1869
- }
1870
- const inactivityService = inactivityServiceRef.current;
1871
- useEffect4(() => {
1872
- inactivityService.updateDependencies(supabaseClient, user, session, idleTimeoutMs, warnBeforeMs, onIdleLogout);
1873
- let isMounted = true;
1874
- inactivityService.initialize().catch((error) => {
1875
- if (isMounted) {
1876
- logger.error("InactivityServiceProvider", "Failed to initialize inactivity service:", error);
1877
- }
1878
- });
1879
- return () => {
1880
- isMounted = false;
1881
- };
1882
- }, [inactivityService, supabaseClient, user, session, idleTimeoutMs, warnBeforeMs, onIdleLogout]);
1883
- const contextValue = useMemo4(() => ({
1884
- inactivityService
1885
- }), [inactivityService]);
1886
- return /* @__PURE__ */ jsx4(InactivityServiceContext.Provider, { value: contextValue, children });
1887
- }
1888
- var InactivityServiceContext, useInactivityService;
1889
- var init_InactivityServiceProvider = __esm({
1890
- "src/providers/services/InactivityServiceProvider.tsx"() {
1891
- "use strict";
1892
- init_InactivityService();
1893
- init_logger();
1894
- InactivityServiceContext = createContext4(null);
1895
- useInactivityService = () => {
1896
- const context = useContext4(InactivityServiceContext);
1897
- if (!context) {
1898
- throw new Error("useInactivityService must be used within InactivityServiceProvider");
1899
- }
1900
- return context.inactivityService;
1901
- };
1902
- }
1903
- });
1904
-
1905
- // src/hooks/services/useAuthService.ts
1906
- import { useContext as useContext5, useReducer, useEffect as useEffect5 } from "react";
1907
- function useAuthService2() {
1908
- const context = useContext5(AuthServiceContext);
1909
- if (!context) {
1910
- throw new Error("useAuthService must be used within AuthServiceProvider");
1911
- }
1912
- const [, forceUpdate] = useReducer((x) => x + 1, 0);
1913
- useEffect5(() => {
1914
- return context.authService.subscribe(() => forceUpdate());
1915
- }, [context.authService]);
1916
- return context.authService;
1917
- }
1918
- var init_useAuthService = __esm({
1919
- "src/hooks/services/useAuthService.ts"() {
1920
- "use strict";
1921
- init_AuthServiceProvider();
1922
- }
1923
- });
1924
-
1925
- // src/hooks/services/useOrganisationService.ts
1926
- import { useContext as useContext6, useReducer as useReducer2, useEffect as useEffect6 } from "react";
1927
- function useOrganisationService2() {
1928
- const context = useContext6(OrganisationServiceContext);
1929
- if (!context) {
1930
- throw new Error("useOrganisationService must be used within OrganisationServiceProvider");
1931
- }
1932
- const [, forceUpdate] = useReducer2((x) => x + 1, 0);
1933
- useEffect6(() => {
1934
- return context.organisationService.subscribe(() => forceUpdate());
1935
- }, [context.organisationService]);
1936
- return context.organisationService;
1937
- }
1938
- var init_useOrganisationService = __esm({
1939
- "src/hooks/services/useOrganisationService.ts"() {
1940
- "use strict";
1941
- init_OrganisationServiceProvider();
1942
- }
1943
- });
1944
-
1945
- // src/hooks/services/useEventService.ts
1946
- import { useContext as useContext7, useReducer as useReducer3, useEffect as useEffect7 } from "react";
1947
- function useEventService2() {
1948
- const context = useContext7(EventServiceContext);
1949
- if (!context) {
1950
- throw new Error("useEventService must be used within EventServiceProvider");
1951
- }
1952
- const [, forceUpdate] = useReducer3((x) => x + 1, 0);
1953
- useEffect7(() => {
1954
- return context.eventService.subscribe(() => forceUpdate());
1955
- }, [context.eventService]);
1956
- return context.eventService;
1957
- }
1958
- var init_useEventService = __esm({
1959
- "src/hooks/services/useEventService.ts"() {
1960
- "use strict";
1961
- init_EventServiceProvider();
1962
- }
1963
- });
1964
-
1965
- // src/hooks/services/useInactivityService.ts
1966
- import { useContext as useContext8, useReducer as useReducer4, useEffect as useEffect8 } from "react";
1967
- function useInactivityService2() {
1968
- const context = useContext8(InactivityServiceContext);
1969
- if (!context) {
1970
- throw new Error("useInactivityService must be used within InactivityServiceProvider");
1971
- }
1972
- const [, forceUpdate] = useReducer4((x) => x + 1, 0);
1973
- useEffect8(() => {
1974
- return context.inactivityService.subscribe(() => forceUpdate());
1975
- }, [context.inactivityService]);
1976
- return context.inactivityService;
1977
- }
1978
- var init_useInactivityService = __esm({
1979
- "src/hooks/services/useInactivityService.ts"() {
1980
- "use strict";
1981
- init_InactivityServiceProvider();
1982
- }
1983
- });
1984
-
1985
- // src/hooks/useSessionRestoration.ts
1986
- import { useContext as useContext9, useMemo as useMemo5, useEffect as useEffect9, useState as useState2 } from "react";
1987
- function useSessionRestoration() {
1988
- const context = useContext9(AuthServiceContext);
1989
- if (!context) {
1990
- throw new Error("useSessionRestoration must be used within AuthServiceProvider");
1991
- }
1992
- const { sessionRestoration } = context;
1993
- const [hasTimedOut, setHasTimedOut] = useState2(false);
1994
- useEffect9(() => {
1995
- let timeoutHandle = null;
1996
- if (sessionRestoration.isRestoring && !sessionRestoration.restorationComplete && !sessionRestoration.restorationError) {
1997
- setHasTimedOut(false);
1998
- timeoutHandle = setTimeout(() => {
1999
- log.warn("Session restoration timed out");
2000
- setHasTimedOut(true);
2001
- }, SESSION_RESTORATION_TIMEOUT_MS);
2002
- } else {
2003
- setHasTimedOut(false);
2004
- }
2005
- return () => {
2006
- if (timeoutHandle) {
2007
- clearTimeout(timeoutHandle);
2008
- }
2009
- };
2010
- }, [
2011
- sessionRestoration.isRestoring,
2012
- sessionRestoration.restorationComplete,
2013
- sessionRestoration.restorationError
2014
- ]);
2015
- return useMemo5(() => ({
2016
- ...sessionRestoration,
2017
- hasTimedOut,
2018
- timeoutMs: SESSION_RESTORATION_TIMEOUT_MS
2019
- }), [sessionRestoration, hasTimedOut]);
2020
- }
2021
- var log, SESSION_RESTORATION_TIMEOUT_MS;
2022
- var init_useSessionRestoration = __esm({
2023
- "src/hooks/useSessionRestoration.ts"() {
2024
- "use strict";
2025
- init_AuthServiceProvider();
2026
- init_logger();
2027
- log = createLogger("useSessionRestoration");
2028
- SESSION_RESTORATION_TIMEOUT_MS = 5e3;
2029
- }
2030
- });
2031
-
2032
- // src/providers/services/UnifiedAuthProvider.tsx
2033
- import { createContext as createContext5, useContext as useContext10, useMemo as useMemo6, useCallback, useRef as useRef4 } from "react";
2034
- import { jsx as jsx5 } from "react/jsx-runtime";
2035
- function UnifiedAuthContextProvider({
2036
- children,
2037
- appName,
2038
- appConfig = { requires_event: true },
2039
- // Default to requiring events
2040
- ...props
2041
- }) {
2042
- const authService = useAuthService2();
2043
- const organisationService = useOrganisationService2();
2044
- const inactivityService = useInactivityService2();
2045
- const sessionRestorationState = useSessionRestoration();
2046
- const {
2047
- hasTimedOut: sessionRestorationTimedOut,
2048
- timeoutMs: sessionRestorationTimeoutMs,
2049
- isRestoring,
2050
- restorationComplete,
2051
- restorationError
2052
- } = sessionRestorationState;
2053
- const sessionRestoration = useMemo6(() => ({
2054
- isRestoring,
2055
- restorationComplete,
2056
- restorationError
2057
- }), [isRestoring, restorationComplete, restorationError]);
2058
- let eventService;
2059
- try {
2060
- eventService = useEventService2();
2061
- } catch (error) {
2062
- eventService = {
2063
- getEvents: () => [],
2064
- getSelectedEvent: () => null,
2065
- isLoading: () => false,
2066
- getError: () => null,
2067
- setSelectedEvent: () => {
2068
- },
2069
- refreshEvents: async () => {
2070
- }
2071
- };
2072
- }
2073
- const currentUser = authService.getUser();
2074
- const currentSession = authService.getSession();
2075
- const isAuth = !!(currentUser && currentSession);
2076
- const authLoading = authService.isLoading();
2077
- const orgLoading = organisationService.isLoading();
2078
- const eventLoading = eventService.isLoading();
2079
- const restorationLoading = sessionRestoration.isRestoring && !sessionRestorationTimedOut && !sessionRestoration.restorationError;
2080
- const totalLoading = restorationLoading || authLoading || orgLoading || eventLoading;
2081
- const authError = authService.getError();
2082
- const supabase = authService.getSupabaseClient();
2083
- const selectedOrganisation = organisationService.getSelectedOrganisation();
2084
- const organisations = organisationService.getOrganisations();
2085
- const userMemberships = organisationService.getUserMemberships();
2086
- const organisationError = organisationService.getError();
2087
- const hasValidOrganisationContext = organisationService.hasValidOrganisationContext();
2088
- const isContextReady = organisationService.isContextReady();
2089
- const events = eventService.getEvents();
2090
- const selectedEvent = eventService.getSelectedEvent();
2091
- const eventError = eventService.getError();
2092
- const showInactivityWarning = inactivityService.getShowInactivityWarning();
2093
- const inactivityTimeRemaining = inactivityService.getInactivityTimeRemaining();
2094
- const isIdle = inactivityService.isIdle();
2095
- const timeRemaining = inactivityService.getTimeRemaining();
2096
- const showWarning = inactivityService.isWarningShown();
2097
- const isTracking = inactivityService.isTracking();
2098
- const hasErrors = !!(authError || organisationError || eventError || sessionRestoration.restorationError);
2099
- const signIn = useCallback((email, password) => authService.signIn(email, password), [authService]);
2100
- const signUp = useCallback((email, password) => authService.signUp(email, password), [authService]);
2101
- const signOut = useCallback(() => authService.signOut(), [authService]);
2102
- const resetPassword = useCallback((email) => authService.resetPassword(email), [authService]);
2103
- const updatePassword = useCallback((password) => authService.updatePassword(password), [authService]);
2104
- const refreshSession = useCallback(() => authService.refreshSession(), [authService]);
2105
- const switchOrganisation = useCallback((orgId) => organisationService.switchOrganisation(orgId), [organisationService]);
2106
- const getUserRole = useCallback((orgId) => organisationService.getUserRole(orgId), [organisationService]);
2107
- const validateOrganisationAccess = useCallback((orgId) => organisationService.validateOrganisationAccess(orgId), [organisationService]);
2108
- const refreshOrganisations = useCallback(() => organisationService.refreshOrganisations(), [organisationService]);
2109
- const ensureOrganisationContext = useCallback(() => organisationService.ensureOrganisationContext(), [organisationService]);
2110
- const isOrganisationSecure = useCallback(() => organisationService.isOrganisationSecure(), [organisationService]);
2111
- const getPrimaryOrganisation = useCallback(() => organisationService.getPrimaryOrganisation(), [organisationService]);
2112
- const setSelectedEvent = useCallback((event) => eventService.setSelectedEvent(event), [eventService]);
2113
- const refreshEvents = useCallback(() => eventService.refreshEvents(), [eventService]);
2114
- const resetActivity = useCallback(() => inactivityService.resetActivity(), [inactivityService]);
2115
- const startTracking = useCallback(() => inactivityService.startTracking(), [inactivityService]);
2116
- const stopTracking = useCallback(() => inactivityService.stopTracking(), [inactivityService]);
2117
- const handleIdleLogout = useCallback(() => inactivityService.handleIdleLogout(), [inactivityService]);
2118
- const handleStaySignedIn = useCallback(() => inactivityService.handleStaySignedIn(), [inactivityService]);
2119
- const handleSignOutNow = useCallback(() => inactivityService.handleSignOutNow(), [inactivityService]);
2120
- const prevStateRef = useRef4(null);
2121
- const isDev = import.meta.env.DEV || import.meta.env.MODE === "development";
2122
- if (isDev) {
2123
- const currentState = {
2124
- isAuthenticated: isAuth,
2125
- userEmail: currentUser?.email,
2126
- totalLoading
2127
- };
2128
- const prevState = prevStateRef.current;
2129
- if (!prevState || prevState.isAuthenticated !== currentState.isAuthenticated || prevState.userEmail !== currentState.userEmail || prevState.totalLoading !== currentState.totalLoading) {
2130
- logger.debug("UnifiedAuthContext", "Auth state changed:", {
2131
- isAuthenticated: isAuth,
2132
- user: currentUser?.email,
2133
- session: currentSession ? "exists" : "null",
2134
- totalLoading,
2135
- authLoading,
2136
- orgLoading,
2137
- eventLoading,
2138
- orgContextReady: isContextReady,
2139
- sessionRestoration,
2140
- sessionRestorationTimedOut
2141
- });
2142
- prevStateRef.current = currentState;
2143
- }
2144
- }
2145
- const contextValue = useMemo6(() => {
2146
- return {
2147
- // Auth state
2148
- user: currentUser,
2149
- session: currentSession,
2150
- isAuthenticated: isAuth,
2151
- authLoading,
2152
- authError,
2153
- error: authError,
2154
- // Alias for backward compatibility
2155
- supabase,
2156
- // Auth methods
2157
- signIn,
2158
- signUp,
2159
- signOut,
2160
- resetPassword,
2161
- updatePassword,
2162
- refreshSession,
2163
- // Organisation state
2164
- selectedOrganisation,
2165
- organisations,
2166
- userMemberships,
2167
- organisationLoading: orgLoading,
2168
- organisationError,
2169
- hasValidOrganisationContext,
2170
- isContextReady,
2171
- // Organisation methods
2172
- switchOrganisation,
2173
- getUserRole,
2174
- validateOrganisationAccess,
2175
- refreshOrganisations,
2176
- ensureOrganisationContext,
2177
- isOrganisationSecure,
2178
- getPrimaryOrganisation,
2179
- // Event state
2180
- events,
2181
- selectedEvent,
2182
- eventLoading,
2183
- eventError,
2184
- // Event methods
2185
- setSelectedEvent,
2186
- refreshEvents,
2187
- // Inactivity state
2188
- showInactivityWarning,
2189
- inactivityTimeRemaining,
2190
- isIdle,
2191
- timeRemaining,
2192
- showWarning,
2193
- isTracking,
2194
- // Inactivity methods
2195
- resetActivity,
2196
- startTracking,
2197
- stopTracking,
2198
- handleIdleLogout,
2199
- handleStaySignedIn,
2200
- handleSignOutNow,
2201
- // Additional unified properties
2202
- appName,
2203
- appConfig,
2204
- isLoading: totalLoading,
2205
- hasErrors,
2206
- sessionRestoration,
2207
- sessionRestorationTimedOut,
2208
- sessionRestorationTimeoutMs
2209
- };
2210
- }, [
2211
- // All primitive values extracted from services
2212
- // Note: Arrays/objects from services are stable references (same reference unless data changes)
2213
- currentUser,
2214
- currentSession,
2215
- isAuth,
2216
- authLoading,
2217
- authError,
2218
- supabase,
2219
- selectedOrganisation,
2220
- organisations,
2221
- userMemberships,
2222
- orgLoading,
2223
- organisationError,
2224
- hasValidOrganisationContext,
2225
- isContextReady,
2226
- events,
2227
- selectedEvent,
2228
- eventLoading,
2229
- eventError,
2230
- showInactivityWarning,
2231
- inactivityTimeRemaining,
2232
- isIdle,
2233
- timeRemaining,
2234
- showWarning,
2235
- isTracking,
2236
- totalLoading,
2237
- hasErrors,
2238
- appName,
2239
- appConfig,
2240
- sessionRestoration,
2241
- sessionRestorationTimedOut,
2242
- sessionRestorationTimeoutMs,
2243
- // Stable function references from useCallback (services are stable, so callbacks are too)
2244
- signIn,
2245
- signUp,
2246
- signOut,
2247
- resetPassword,
2248
- updatePassword,
2249
- refreshSession,
2250
- switchOrganisation,
2251
- getUserRole,
2252
- validateOrganisationAccess,
2253
- refreshOrganisations,
2254
- ensureOrganisationContext,
2255
- isOrganisationSecure,
2256
- getPrimaryOrganisation,
2257
- setSelectedEvent,
2258
- refreshEvents,
2259
- resetActivity,
2260
- startTracking,
2261
- stopTracking,
2262
- handleIdleLogout,
2263
- handleStaySignedIn,
2264
- handleSignOutNow
2265
- ]);
2266
- return /* @__PURE__ */ jsx5(UnifiedAuthContext.Provider, { value: contextValue, children });
2267
- }
2268
- function EventServiceProviderWrapper({
2269
- children,
2270
- supabaseClient,
2271
- user,
2272
- session,
2273
- appName
2274
- }) {
2275
- const organisationService = useOrganisationService2();
2276
- const selectedOrganisation = organisationService.getSelectedOrganisation();
2277
- return /* @__PURE__ */ jsx5(
2278
- EventServiceProvider,
2279
- {
2280
- supabaseClient,
2281
- user,
2282
- session,
2283
- appName,
2284
- selectedOrganisation,
2285
- setSelectedEventId: () => {
2286
- },
2287
- children
2288
- }
2289
- );
2290
- }
2291
- function ServiceAwareProviders({
2292
- children,
2293
- supabaseClient,
2294
- appName,
2295
- appConfig,
2296
- persistState,
2297
- enablePersistence,
2298
- requireOrganisationContext,
2299
- idleTimeoutMs,
2300
- warnBeforeMs,
2301
- onIdleLogout,
2302
- renderInactivityWarning,
2303
- dangerouslyDisableInactivity
2304
- }) {
2305
- const authService = useAuthService2();
2306
- return /* @__PURE__ */ jsx5(
2307
- OrganisationServiceProvider,
2308
- {
2309
- supabaseClient,
2310
- user: authService.getUser(),
2311
- session: authService.getSession(),
2312
- children: /* @__PURE__ */ jsx5(
2313
- EventServiceProviderWrapper,
2314
- {
2315
- supabaseClient,
2316
- user: authService.getUser(),
2317
- session: authService.getSession(),
2318
- appName,
2319
- children: /* @__PURE__ */ jsx5(
2320
- InactivityServiceProvider,
2321
- {
2322
- supabaseClient,
2323
- user: authService.getUser(),
2324
- session: authService.getSession(),
2325
- idleTimeoutMs,
2326
- warnBeforeMs,
2327
- onIdleLogout,
2328
- children: /* @__PURE__ */ jsx5(
2329
- UnifiedAuthContextProvider,
2330
- {
2331
- appName,
2332
- appConfig,
2333
- supabaseClient,
2334
- persistState,
2335
- enablePersistence,
2336
- requireOrganisationContext,
2337
- idleTimeoutMs,
2338
- warnBeforeMs,
2339
- onIdleLogout,
2340
- renderInactivityWarning,
2341
- dangerouslyDisableInactivity,
2342
- children
2343
- }
2344
- )
2345
- }
2346
- )
2347
- }
2348
- )
2349
- }
2350
- );
2351
- }
2352
- function UnifiedAuthProvider({
2353
- children,
2354
- supabaseClient,
2355
- appName,
2356
- appConfig = { requires_event: true },
2357
- // Default to requiring events
2358
- persistState = true,
2359
- enablePersistence,
2360
- requireOrganisationContext = true,
2361
- idleTimeoutMs = 30 * 60 * 1e3,
2362
- // 30 minutes
2363
- warnBeforeMs = 60 * 1e3,
2364
- // 60 seconds
2365
- onIdleLogout,
2366
- renderInactivityWarning,
2367
- dangerouslyDisableInactivity = false
2368
- }) {
2369
- return /* @__PURE__ */ jsx5(AuthServiceProvider, { supabaseClient, appName, children: /* @__PURE__ */ jsx5(
2370
- ServiceAwareProviders,
2371
- {
2372
- supabaseClient,
2373
- appName,
2374
- appConfig,
2375
- persistState,
2376
- enablePersistence,
2377
- requireOrganisationContext,
2378
- idleTimeoutMs,
2379
- warnBeforeMs,
2380
- onIdleLogout,
2381
- renderInactivityWarning,
2382
- dangerouslyDisableInactivity,
2383
- children
2384
- }
2385
- ) });
2386
- }
2387
- var UnifiedAuthContext, useUnifiedAuth;
2388
- var init_UnifiedAuthProvider = __esm({
2389
- "src/providers/services/UnifiedAuthProvider.tsx"() {
2390
- "use strict";
2391
- init_AuthServiceProvider();
2392
- init_OrganisationServiceProvider();
2393
- init_EventServiceProvider();
2394
- init_InactivityServiceProvider();
2395
- init_useAuthService();
2396
- init_useOrganisationService();
2397
- init_useEventService();
2398
- init_useInactivityService();
2399
- init_useSessionRestoration();
2400
- init_logger();
2401
- UnifiedAuthContext = createContext5(void 0);
2402
- useUnifiedAuth = () => {
2403
- const context = useContext10(UnifiedAuthContext);
2404
- if (!context) {
2405
- logger.error("useUnifiedAuth", "useUnifiedAuth must be used within a UnifiedAuthProvider");
2406
- throw new Error("useUnifiedAuth must be used within a UnifiedAuthProvider");
2407
- }
2408
- return context;
2409
- };
2410
- }
2411
- });
2412
-
2413
- export {
2414
- AuthServiceContext,
2415
- AuthServiceProvider,
2416
- useAuthService,
2417
- init_AuthServiceProvider,
2418
- OrganisationServiceContext,
2419
- OrganisationServiceProvider,
2420
- useOrganisationService,
2421
- init_OrganisationServiceProvider,
2422
- EventServiceContext,
2423
- EventServiceProvider,
2424
- useEventService,
2425
- init_EventServiceProvider,
2426
- InactivityServiceContext,
2427
- InactivityServiceProvider,
2428
- useInactivityService,
2429
- init_InactivityServiceProvider,
2430
- useAuthService2,
2431
- init_useAuthService,
2432
- useOrganisationService2,
2433
- init_useOrganisationService,
2434
- useEventService2,
2435
- init_useEventService,
2436
- useInactivityService2,
2437
- init_useInactivityService,
2438
- useSessionRestoration,
2439
- init_useSessionRestoration,
2440
- useUnifiedAuth,
2441
- UnifiedAuthProvider,
2442
- init_UnifiedAuthProvider
2443
- };
2444
- //# sourceMappingURL=chunk-3JI76CYK.js.map