@jmruthers/pace-core 0.5.54 → 0.5.56

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 (396) hide show
  1. package/README.md +0 -4
  2. package/dist/{DataTable-7FMFXA7A.js → DataTable-DJQTKX33.js} +11 -11
  3. package/dist/{PublicLoadingSpinner-Bq_-BeK-.d.ts → PublicLoadingSpinner-SL8WaQN7.d.ts} +2 -21
  4. package/dist/{api-H5A3H4IR.js → api-LUNF5O6M.js} +3 -3
  5. package/dist/{appConfig-BVGyuvI7.d.ts → appConfig-DjpeG6P-.d.ts} +9 -1
  6. package/dist/{appNameResolver-7GHF5ED2.js → appNameResolver-UURKN7NF.js} +2 -2
  7. package/dist/{audit-BUW3LMJB.js → audit-6TOCAMKO.js} +2 -2
  8. package/dist/{chunk-NRK4AIHQ.js → chunk-2DFCT6D3.js} +3 -3
  9. package/dist/{chunk-GIO7BFE7.js → chunk-3JKVVLD3.js} +66 -169
  10. package/dist/{chunk-GIO7BFE7.js.map → chunk-3JKVVLD3.js.map} +1 -1
  11. package/dist/{chunk-MZBUOP4P.js → chunk-5BSLGBYI.js} +4 -3
  12. package/dist/chunk-5BSLGBYI.js.map +1 -0
  13. package/dist/{chunk-I5Z3QH5X.js → chunk-66C4BSAY.js} +2 -2
  14. package/dist/{chunk-I5Z3QH5X.js.map → chunk-66C4BSAY.js.map} +1 -1
  15. package/dist/{chunk-EL2O4IUX.js → chunk-ASXSJGPW.js} +20 -24
  16. package/dist/{chunk-EL2O4IUX.js.map → chunk-ASXSJGPW.js.map} +1 -1
  17. package/dist/{chunk-7BNPOCLL.js → chunk-B2WTCLCV.js} +6 -2
  18. package/dist/chunk-B2WTCLCV.js.map +1 -0
  19. package/dist/{chunk-WJARTBCT.js → chunk-D7ARGIA3.js} +16 -7
  20. package/dist/chunk-D7ARGIA3.js.map +1 -0
  21. package/dist/{chunk-MYP2EGHX.js → chunk-GIDCWCHF.js} +21 -14
  22. package/dist/chunk-GIDCWCHF.js.map +1 -0
  23. package/dist/{chunk-MSFACPQQ.js → chunk-HYNGIE5T.js} +11 -11
  24. package/dist/{chunk-MSFACPQQ.js.map → chunk-HYNGIE5T.js.map} +1 -1
  25. package/dist/{chunk-TRIZ7IB7.js → chunk-I5GID3EX.js} +148 -288
  26. package/dist/chunk-I5GID3EX.js.map +1 -0
  27. package/dist/{chunk-GWSBHC4J.js → chunk-KLPVOPRI.js} +261 -38
  28. package/dist/chunk-KLPVOPRI.js.map +1 -0
  29. package/dist/{chunk-BC3S53OZ.js → chunk-N6XMGSGD.js} +30 -14
  30. package/dist/chunk-N6XMGSGD.js.map +1 -0
  31. package/dist/{chunk-6MTY77WU.js → chunk-QB4GXDUM.js} +3 -3
  32. package/dist/{chunk-YDJW5XTN.js → chunk-STT7INZR.js} +25 -1
  33. package/dist/chunk-STT7INZR.js.map +1 -0
  34. package/dist/{chunk-NYUJ4FJR.js → chunk-UETTVYKU.js} +7 -7
  35. package/dist/chunk-UETTVYKU.js.map +1 -0
  36. package/dist/{chunk-22KLBHPS.js → chunk-W66AZIOH.js} +2 -2
  37. package/dist/chunk-W66AZIOH.js.map +1 -0
  38. package/dist/{chunk-NZ655MWE.js → chunk-YEHO6FDW.js} +5 -4
  39. package/dist/chunk-YEHO6FDW.js.map +1 -0
  40. package/dist/{chunk-SS3E6QLB.js → chunk-YNUBMSMV.js} +2 -2
  41. package/dist/chunk-YNUBMSMV.js.map +1 -0
  42. package/dist/{chunk-74C6SNEC.js → chunk-ZPK5656W.js} +3 -3
  43. package/dist/{chunk-74C6SNEC.js.map → chunk-ZPK5656W.js.map} +1 -1
  44. package/dist/components.d.ts +22 -899
  45. package/dist/components.js +436 -3118
  46. package/dist/components.js.map +1 -1
  47. package/dist/file-reference-9xUOnwyt.d.ts +70 -0
  48. package/dist/hooks.d.ts +2 -2
  49. package/dist/hooks.js +10 -10
  50. package/dist/hooks.js.map +1 -1
  51. package/dist/index.d.ts +49 -9
  52. package/dist/index.js +190 -25
  53. package/dist/index.js.map +1 -1
  54. package/dist/{organisation-CO3Sh3_D.d.ts → organisation-t-vvQC3g.d.ts} +1 -8
  55. package/dist/providers.d.ts +2 -2
  56. package/dist/providers.js +5 -5
  57. package/dist/rbac/index.d.ts +65 -46
  58. package/dist/rbac/index.js +10 -12
  59. package/dist/styles/core.css +0 -125
  60. package/dist/types.d.ts +2 -1
  61. package/dist/types.js +3 -1
  62. package/dist/types.js.map +1 -1
  63. package/dist/{usePublicRouteParams-B2OcAsur.d.ts → usePublicRouteParams-CdoFxnJK.d.ts} +1 -1
  64. package/dist/utils.d.ts +3 -4
  65. package/dist/utils.js +44 -13
  66. package/dist/utils.js.map +1 -1
  67. package/docs/FILE_REFERENCE_SYSTEM.md +440 -0
  68. package/docs/INDEX.md +7 -5
  69. package/docs/README.md +0 -1
  70. package/docs/api/README.md +0 -4
  71. package/docs/api/classes/ErrorBoundary.md +1 -1
  72. package/docs/api/classes/InvalidScopeError.md +1 -1
  73. package/docs/api/classes/MissingUserContextError.md +1 -1
  74. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  75. package/docs/api/classes/PermissionDeniedError.md +2 -2
  76. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  77. package/docs/api/classes/RBACAuditManager.md +12 -12
  78. package/docs/api/classes/RBACCache.md +1 -1
  79. package/docs/api/classes/RBACEngine.md +6 -6
  80. package/docs/api/classes/RBACError.md +1 -1
  81. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  82. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  83. package/docs/api/classes/StorageUtils.md +281 -0
  84. package/docs/api/interfaces/AggregateConfig.md +1 -1
  85. package/docs/api/interfaces/ButtonProps.md +1 -1
  86. package/docs/api/interfaces/CardProps.md +1 -1
  87. package/docs/api/interfaces/ColorPalette.md +1 -1
  88. package/docs/api/interfaces/ColorShade.md +1 -1
  89. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  90. package/docs/api/interfaces/DataTableAction.md +1 -1
  91. package/docs/api/interfaces/DataTableColumn.md +1 -1
  92. package/docs/api/interfaces/DataTableProps.md +1 -1
  93. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  94. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  95. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  96. package/docs/api/interfaces/EventContextType.md +1 -1
  97. package/docs/api/interfaces/EventLogoProps.md +1 -1
  98. package/docs/api/interfaces/EventProviderProps.md +1 -1
  99. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  100. package/docs/api/interfaces/FileUploadProps.md +1 -1
  101. package/docs/api/interfaces/FooterProps.md +1 -1
  102. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  103. package/docs/api/interfaces/InputProps.md +1 -1
  104. package/docs/api/interfaces/LabelProps.md +1 -1
  105. package/docs/api/interfaces/LoginFormProps.md +1 -1
  106. package/docs/api/interfaces/NavigationAccessRecord.md +2 -2
  107. package/docs/api/interfaces/NavigationContextType.md +1 -1
  108. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  109. package/docs/api/interfaces/NavigationItem.md +1 -1
  110. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  111. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  112. package/docs/api/interfaces/Organisation.md +1 -1
  113. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  114. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  115. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  116. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  117. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  118. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  119. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  120. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  121. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  122. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  123. package/docs/api/interfaces/PaletteData.md +1 -1
  124. package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
  125. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  126. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  127. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  128. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  129. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  130. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  131. package/docs/api/interfaces/RBACConfig.md +1 -1
  132. package/docs/api/interfaces/RBACContextType.md +1 -1
  133. package/docs/api/interfaces/RBACLogger.md +1 -1
  134. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  135. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  136. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  137. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  138. package/docs/api/interfaces/RouteConfig.md +2 -2
  139. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  140. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  141. package/docs/api/interfaces/StorageConfig.md +1 -1
  142. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  143. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  144. package/docs/api/interfaces/StorageListOptions.md +1 -1
  145. package/docs/api/interfaces/StorageListResult.md +1 -1
  146. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  147. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  148. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  149. package/docs/api/interfaces/StyleImport.md +1 -1
  150. package/docs/api/interfaces/ToastActionElement.md +1 -1
  151. package/docs/api/interfaces/ToastProps.md +1 -1
  152. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  153. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  154. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  155. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  156. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  157. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  158. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  159. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  160. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  161. package/docs/api/interfaces/UserEventAccess.md +1 -1
  162. package/docs/api/interfaces/UserMenuProps.md +1 -1
  163. package/docs/api/interfaces/UserProfile.md +1 -1
  164. package/docs/api/modules.md +204 -200
  165. package/docs/api-reference/components.md +141 -163
  166. package/docs/api-reference/hooks.md +347 -0
  167. package/docs/core-concepts/rbac-system.md +69 -16
  168. package/docs/getting-started/examples/basic-auth-app.md +0 -1
  169. package/docs/implementation-guides/datatable-rbac-usage.md +12 -11
  170. package/docs/implementation-guides/file-upload-storage.md +733 -0
  171. package/docs/implementation-guides/inactivity-tracking.md +779 -0
  172. package/docs/implementation-guides/organisation-security.md +748 -0
  173. package/docs/implementation-guides/public-pages-advanced.md +1022 -0
  174. package/docs/migration/MIGRATION_GUIDE.md +684 -0
  175. package/docs/migration/README.md +13 -2
  176. package/docs/migration/rbac-migration.md +73 -0
  177. package/docs/rbac/examples/rbac-rls-integration-example.md +11 -13
  178. package/docs/style-guide.md +269 -1
  179. package/package.json +1 -1
  180. package/src/__tests__/TESTING_GUIDELINES.md +331 -18
  181. package/src/__tests__/helpers/supabaseMock.ts +99 -0
  182. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +10 -7
  183. package/src/__tests__/shared.ts +6 -0
  184. package/src/components/DataTable/components/ActionButtons.tsx +2 -2
  185. package/src/components/DataTable/components/DataTableCore.tsx +2 -2
  186. package/src/components/DataTable/components/UnifiedTableBody.tsx +1 -1
  187. package/src/components/DataTable/utils/debugTools.ts +2 -2
  188. package/src/components/Dialog/Dialog.test.tsx +12 -2
  189. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +6 -6
  190. package/src/components/ErrorBoundary/ErrorBoundary.tsx +2 -2
  191. package/src/components/FileDisplay.tsx +233 -0
  192. package/src/components/FileUpload.tsx +176 -0
  193. package/src/components/Footer/Footer.test.tsx +7 -7
  194. package/src/components/NavigationMenu/NavigationMenu.test.tsx +13 -6
  195. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +30 -3
  196. package/src/components/OrganisationSelector/OrganisationSelector.tsx +1 -1
  197. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +558 -0
  198. package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
  199. package/src/components/PublicLayout/PublicPageDebugger.tsx +2 -2
  200. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +2 -2
  201. package/src/components/PublicLayout/PublicPageProvider.tsx +2 -2
  202. package/src/components/Select/Select.test.tsx +50 -15
  203. package/src/components/SuperAdminGuard.tsx +2 -2
  204. package/src/components/__tests__/SuperAdminGuard.test.tsx +559 -0
  205. package/src/components/index.ts +0 -183
  206. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +2 -2
  207. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +1 -1
  208. package/src/hooks/__tests__/useRBAC.unit.test.ts +191 -138
  209. package/src/hooks/public/usePublicEvent.ts +2 -2
  210. package/src/hooks/useAppConfig.ts +3 -3
  211. package/src/hooks/useComponentPerformance.ts +1 -1
  212. package/src/hooks/useDataTablePerformance.ts +1 -1
  213. package/src/hooks/useFileReference.ts +232 -0
  214. package/src/hooks/useOrganisationPermissions.test.ts +254 -344
  215. package/src/hooks/useOrganisationPermissions.ts +15 -7
  216. package/src/hooks/useOrganisationSecurity.test.ts +390 -402
  217. package/src/hooks/usePerformanceMonitor.ts +1 -1
  218. package/src/hooks/usePermissionCache.test.ts +264 -395
  219. package/src/hooks/usePermissionCache.ts +34 -4
  220. package/src/hooks/useSecureDataAccess.test.ts +486 -0
  221. package/src/hooks/useSecureDataAccess.ts +4 -1
  222. package/src/providers/InactivityProvider.tsx +2 -2
  223. package/src/providers/OrganisationProvider.test.simple.tsx +168 -0
  224. package/src/providers/OrganisationProvider.test.tsx +168 -0
  225. package/src/providers/OrganisationProvider.tsx +25 -31
  226. package/src/providers/UnifiedAuthProvider.test.simple.tsx +205 -0
  227. package/src/providers/UnifiedAuthProvider.test.tsx +128 -0
  228. package/src/providers/__tests__/InactivityProvider.test.tsx +3 -4
  229. package/src/providers/__tests__/OrganisationProvider.test.tsx +19 -14
  230. package/src/rbac/__tests__/integration.authflow.test.tsx +123 -0
  231. package/src/rbac/__tests__/integration.navigation.test.tsx +72 -0
  232. package/src/rbac/__tests__/integration.securedata.test.tsx +92 -0
  233. package/src/rbac/__tests__/integration.smoke.test.tsx +73 -0
  234. package/src/rbac/__tests__/rbac-core.test.tsx +26 -22
  235. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +411 -0
  236. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +285 -0
  237. package/src/rbac/__tests__/rbac-functions.test.ts +655 -0
  238. package/src/rbac/__tests__/rbac-integration.test.ts +532 -0
  239. package/src/rbac/__tests__/scenarios.user-role.test.tsx +196 -0
  240. package/src/rbac/api.test.ts +6 -6
  241. package/src/rbac/api.ts +2 -2
  242. package/src/rbac/audit.test.ts +485 -0
  243. package/src/rbac/audit.ts +7 -1
  244. package/src/rbac/cache-invalidation.ts +318 -0
  245. package/src/rbac/cache.test.ts +286 -0
  246. package/src/rbac/components/EnhancedNavigationMenu.test.tsx +559 -0
  247. package/src/rbac/components/EnhancedNavigationMenu.tsx +29 -23
  248. package/src/rbac/components/NavigationProvider.test.tsx +449 -0
  249. package/src/rbac/components/PagePermissionGuard.tsx +4 -4
  250. package/src/rbac/components/PagePermissionProvider.test.tsx +479 -0
  251. package/src/rbac/components/SecureDataProvider.test.tsx +511 -0
  252. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +159 -430
  253. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +4 -5
  254. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +112 -118
  255. package/src/rbac/config.test.ts +410 -0
  256. package/src/rbac/engine.test.simple.ts +237 -0
  257. package/src/rbac/engine.test.ts +233 -0
  258. package/src/rbac/engine.ts +37 -41
  259. package/src/rbac/examples/CompleteRBACExample.tsx +3 -3
  260. package/src/rbac/examples/EventBasedApp.tsx +4 -4
  261. package/src/rbac/hooks/useRBAC.simple.test.ts +16 -0
  262. package/src/rbac/hooks/useRBAC.test.ts +207 -455
  263. package/src/rbac/hooks/useRBAC.ts +30 -22
  264. package/src/rbac/permissions.test.ts +128 -0
  265. package/src/rbac/permissions.ts +56 -141
  266. package/src/rbac/providers/RBACProvider.tsx +1 -1
  267. package/src/rbac/secureClient.test.ts +444 -0
  268. package/src/rbac/security.test.ts +390 -0
  269. package/src/rbac/security.ts +1 -1
  270. package/src/rbac/types.test.ts +382 -0
  271. package/src/rbac/types.ts +2 -2
  272. package/src/styles/core.css +0 -125
  273. package/src/types/file-reference.ts +77 -0
  274. package/src/types/rbac-functions.ts +290 -0
  275. package/src/types/supabase.ts +10 -28
  276. package/src/types/unified.ts +4 -1
  277. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +81 -55
  278. package/src/utils/__tests__/lazyLoad.unit.test.tsx +21 -12
  279. package/src/utils/__tests__/organisationContext.unit.test.ts +13 -7
  280. package/src/utils/__tests__/performanceBudgets.unit.test.ts +3 -3
  281. package/src/utils/__tests__/sessionTracking.unit.test.ts +32 -12
  282. package/src/utils/appConfig.ts +1 -1
  283. package/src/utils/appIdResolver.test.ts +503 -0
  284. package/src/utils/appIdResolver.ts +1 -1
  285. package/src/utils/appNameResolver.test.ts +494 -0
  286. package/src/utils/appNameResolver.ts +3 -2
  287. package/src/utils/bundleAnalysis.ts +3 -3
  288. package/src/utils/debugLogger.ts +1 -1
  289. package/src/utils/file-reference.ts +263 -0
  290. package/src/utils/formatDate.test.ts +2 -2
  291. package/src/utils/organisationContext.test.ts +340 -0
  292. package/src/utils/organisationContext.ts +19 -6
  293. package/src/utils/performanceBudgets.ts +2 -2
  294. package/src/utils/permissionUtils.test.ts +393 -0
  295. package/src/utils/permissionUtils.ts +5 -2
  296. package/src/utils/secureDataAccess.test.ts +715 -0
  297. package/src/utils/secureDataAccess.ts +21 -5
  298. package/src/utils/sessionTracking.ts +34 -4
  299. package/src/utils/storage/__tests__/helpers.unit.test.ts +328 -0
  300. package/src/utils/storage/__tests__/index.unit.test.ts +16 -0
  301. package/src/utils/storage/helpers.ts +20 -25
  302. package/src/utils/storage/index.ts +29 -1
  303. package/src/vite-env.d.ts +17 -0
  304. package/dist/chunk-22KLBHPS.js.map +0 -1
  305. package/dist/chunk-7BNPOCLL.js.map +0 -1
  306. package/dist/chunk-BC3S53OZ.js.map +0 -1
  307. package/dist/chunk-GWSBHC4J.js.map +0 -1
  308. package/dist/chunk-MYP2EGHX.js.map +0 -1
  309. package/dist/chunk-MZBUOP4P.js.map +0 -1
  310. package/dist/chunk-NYUJ4FJR.js.map +0 -1
  311. package/dist/chunk-NZ655MWE.js.map +0 -1
  312. package/dist/chunk-SS3E6QLB.js.map +0 -1
  313. package/dist/chunk-TRIZ7IB7.js.map +0 -1
  314. package/dist/chunk-WJARTBCT.js.map +0 -1
  315. package/dist/chunk-YDJW5XTN.js.map +0 -1
  316. package/docs/print-components/README.md +0 -258
  317. package/docs/print-components/api-reference.md +0 -636
  318. package/docs/print-components/examples/README.md +0 -204
  319. package/docs/print-components/examples/basic-report.tsx +0 -92
  320. package/docs/print-components/examples/card-catalog.tsx +0 -149
  321. package/docs/print-components/examples/cover-page-report.tsx +0 -163
  322. package/docs/print-components/quick-start.md +0 -363
  323. package/src/components/PrintButton/PrintButton.tsx +0 -321
  324. package/src/components/PrintButton/PrintButtonGroup.tsx +0 -84
  325. package/src/components/PrintButton/PrintToolbar.tsx +0 -94
  326. package/src/components/PrintButton/__tests__/PrintButton.test.tsx +0 -271
  327. package/src/components/PrintButton/examples/PrintButtonShowcase.tsx +0 -438
  328. package/src/components/PrintButton/index.ts +0 -33
  329. package/src/components/PrintButton/types.ts +0 -173
  330. package/src/components/PrintCard/PrintCard.tsx +0 -154
  331. package/src/components/PrintCard/PrintCardContent.tsx +0 -57
  332. package/src/components/PrintCard/PrintCardFooter.tsx +0 -60
  333. package/src/components/PrintCard/PrintCardGrid.tsx +0 -91
  334. package/src/components/PrintCard/PrintCardHeader.tsx +0 -78
  335. package/src/components/PrintCard/PrintCardImage.tsx +0 -81
  336. package/src/components/PrintCard/examples/PrintCardShowcase.tsx +0 -239
  337. package/src/components/PrintCard/index.ts +0 -34
  338. package/src/components/PrintCard/types.ts +0 -171
  339. package/src/components/PrintDataTable/PrintDataTable.tsx +0 -215
  340. package/src/components/PrintDataTable/PrintTableGroup.tsx +0 -90
  341. package/src/components/PrintDataTable/PrintTableRow.tsx +0 -76
  342. package/src/components/PrintDataTable/index.ts +0 -25
  343. package/src/components/PrintDataTable/types.ts +0 -67
  344. package/src/components/PrintFooter/PrintFooter.tsx +0 -183
  345. package/src/components/PrintFooter/PrintFooterContent.tsx +0 -71
  346. package/src/components/PrintFooter/PrintFooterInfo.tsx +0 -86
  347. package/src/components/PrintFooter/PrintPageNumber.tsx +0 -90
  348. package/src/components/PrintFooter/examples/PrintFooterShowcase.tsx +0 -390
  349. package/src/components/PrintFooter/index.ts +0 -30
  350. package/src/components/PrintFooter/types.ts +0 -149
  351. package/src/components/PrintGrid/PrintGrid.tsx +0 -180
  352. package/src/components/PrintGrid/PrintGridBreakpoint.tsx +0 -109
  353. package/src/components/PrintGrid/PrintGridContainer.tsx +0 -128
  354. package/src/components/PrintGrid/PrintGridItem.tsx +0 -220
  355. package/src/components/PrintGrid/examples/PrintGridShowcase.tsx +0 -359
  356. package/src/components/PrintGrid/index.ts +0 -31
  357. package/src/components/PrintGrid/types.ts +0 -159
  358. package/src/components/PrintHeader/PrintCoverHeader.tsx +0 -230
  359. package/src/components/PrintHeader/PrintHeader.tsx +0 -150
  360. package/src/components/PrintHeader/index.ts +0 -17
  361. package/src/components/PrintHeader/types.ts +0 -42
  362. package/src/components/PrintLayout/PrintLayout.tsx +0 -122
  363. package/src/components/PrintLayout/PrintLayoutContext.tsx +0 -66
  364. package/src/components/PrintLayout/PrintPageBreak.tsx +0 -52
  365. package/src/components/PrintLayout/examples/PrintShowcase.tsx +0 -230
  366. package/src/components/PrintLayout/index.ts +0 -19
  367. package/src/components/PrintLayout/types.ts +0 -37
  368. package/src/components/PrintPageBreak/PrintPageBreak.tsx +0 -120
  369. package/src/components/PrintPageBreak/PrintPageBreakGroup.tsx +0 -90
  370. package/src/components/PrintPageBreak/PrintPageBreakIndicator.tsx +0 -112
  371. package/src/components/PrintPageBreak/examples/PrintPageBreakShowcase.tsx +0 -279
  372. package/src/components/PrintPageBreak/index.ts +0 -23
  373. package/src/components/PrintPageBreak/types.ts +0 -94
  374. package/src/components/PrintSection/PrintColumn.tsx +0 -104
  375. package/src/components/PrintSection/PrintDivider.tsx +0 -101
  376. package/src/components/PrintSection/PrintSection.tsx +0 -129
  377. package/src/components/PrintSection/PrintSectionContent.tsx +0 -75
  378. package/src/components/PrintSection/PrintSectionHeader.tsx +0 -97
  379. package/src/components/PrintSection/examples/PrintSectionShowcase.tsx +0 -258
  380. package/src/components/PrintSection/index.ts +0 -33
  381. package/src/components/PrintSection/types.ts +0 -155
  382. package/src/components/PrintText/PrintText.tsx +0 -116
  383. package/src/components/PrintText/index.ts +0 -16
  384. package/src/components/PrintText/types.ts +0 -24
  385. package/src/rbac/__tests__/integration.test.tsx +0 -218
  386. package/src/utils/print/PrintDataProcessor.ts +0 -390
  387. package/src/utils/print/examples/PrintUtilitiesShowcase.tsx +0 -397
  388. package/src/utils/print/index.ts +0 -29
  389. package/src/utils/print/types.ts +0 -196
  390. package/src/utils/print/usePrintOptimization.ts +0 -272
  391. /package/dist/{DataTable-7FMFXA7A.js.map → DataTable-DJQTKX33.js.map} +0 -0
  392. /package/dist/{api-H5A3H4IR.js.map → api-LUNF5O6M.js.map} +0 -0
  393. /package/dist/{appNameResolver-7GHF5ED2.js.map → appNameResolver-UURKN7NF.js.map} +0 -0
  394. /package/dist/{audit-BUW3LMJB.js.map → audit-6TOCAMKO.js.map} +0 -0
  395. /package/dist/{chunk-NRK4AIHQ.js.map → chunk-2DFCT6D3.js.map} +0 -0
  396. /package/dist/{chunk-6MTY77WU.js.map → chunk-QB4GXDUM.js.map} +0 -0
@@ -1240,169 +1240,6 @@ import { PasswordChangeForm } from '@jmruthers/pace-core';
1240
1240
  />
1241
1241
  ```
1242
1242
 
1243
- ## Print Components
1244
-
1245
- PACE Core includes a comprehensive set of print-optimized components for creating reports and documents.
1246
-
1247
- ### PrintLayout
1248
-
1249
- The main container for print documents with A4 optimization.
1250
-
1251
- ```typescript
1252
- interface PrintLayoutProps {
1253
- children: React.ReactNode;
1254
- orientation?: 'portrait' | 'landscape';
1255
- pageSize?: 'A4' | 'A3' | 'Letter';
1256
- className?: string;
1257
- }
1258
- ```
1259
-
1260
- ### PrintHeader
1261
-
1262
- Document header with title and branding.
1263
-
1264
- ```typescript
1265
- interface PrintHeaderProps {
1266
- title: string;
1267
- subtitle?: string;
1268
- branding?: {
1269
- companyName: string;
1270
- projectName?: string;
1271
- logo?: string;
1272
- };
1273
- className?: string;
1274
- }
1275
- ```
1276
-
1277
- ### PrintDataTable
1278
-
1279
- Print-optimized data table with pagination and styling.
1280
-
1281
- ```typescript
1282
- interface PrintDataTableProps<TData> {
1283
- data: TData[];
1284
- columns: PrintColumn<TData>[];
1285
- title?: string;
1286
- showPagination?: boolean;
1287
- pageSize?: number;
1288
- className?: string;
1289
- }
1290
- ```
1291
-
1292
- ### PrintCard
1293
-
1294
- Print-optimized card component.
1295
-
1296
- ```typescript
1297
- interface PrintCardProps {
1298
- children: React.ReactNode;
1299
- title?: string;
1300
- className?: string;
1301
- }
1302
- ```
1303
-
1304
- ### PrintSection
1305
-
1306
- Section divider for print documents.
1307
-
1308
- ```typescript
1309
- interface PrintSectionProps {
1310
- children: React.ReactNode;
1311
- title?: string;
1312
- level?: 1 | 2 | 3;
1313
- className?: string;
1314
- }
1315
- ```
1316
-
1317
- ### PrintGrid
1318
-
1319
- Grid layout for print documents.
1320
-
1321
- ```typescript
1322
- interface PrintGridProps {
1323
- children: React.ReactNode;
1324
- columns?: 1 | 2 | 3 | 4;
1325
- gap?: 'sm' | 'md' | 'lg';
1326
- className?: string;
1327
- }
1328
- ```
1329
-
1330
- ### PrintButton
1331
-
1332
- Print-optimized button (appears as text in print).
1333
-
1334
- ```typescript
1335
- interface PrintButtonProps {
1336
- children: React.ReactNode;
1337
- onClick?: () => void;
1338
- className?: string;
1339
- }
1340
- ```
1341
-
1342
- ### PrintPageBreak
1343
-
1344
- Forces a page break in print documents.
1345
-
1346
- ```tsx
1347
- <PrintPageBreak />
1348
- ```
1349
-
1350
- ### PrintDivider
1351
-
1352
- Visual divider for print documents.
1353
-
1354
- ```tsx
1355
- <PrintDivider />
1356
- ```
1357
-
1358
- ### Print Usage Example
1359
-
1360
- ```tsx
1361
- import {
1362
- PrintLayout,
1363
- PrintHeader,
1364
- PrintDataTable,
1365
- PrintCard,
1366
- PrintSection,
1367
- PrintPageBreak
1368
- } from '@jmruthers/pace-core';
1369
-
1370
- function ReportPage() {
1371
- return (
1372
- <PrintLayout orientation="portrait" pageSize="A4">
1373
- <PrintHeader
1374
- title="Monthly Report"
1375
- subtitle="Q4 2024"
1376
- branding={{
1377
- companyName: "Your Company",
1378
- projectName: "Analytics Dashboard"
1379
- }}
1380
- />
1381
-
1382
- <PrintSection title="Executive Summary" level={1}>
1383
- <PrintCard title="Key Metrics">
1384
- <p>Total revenue: $1,234,567</p>
1385
- <p>Growth rate: 15.3%</p>
1386
- </PrintCard>
1387
- </PrintSection>
1388
-
1389
- <PrintPageBreak />
1390
-
1391
- <PrintSection title="Detailed Data" level={1}>
1392
- <PrintDataTable
1393
- data={reportData}
1394
- columns={columns}
1395
- title="Revenue by Region"
1396
- showPagination={true}
1397
- pageSize={20}
1398
- />
1399
- </PrintSection>
1400
- </PrintLayout>
1401
- );
1402
- }
1403
- ```
1404
-
1405
- For detailed print component usage, see [Print Components Guide](../print-components/README.md).
1406
1243
 
1407
1244
  ## Public Page Components
1408
1245
 
@@ -1572,6 +1409,147 @@ import { ErrorBoundary } from '@jmruthers/pace-core';
1572
1409
  ```
1573
1410
 
1574
1411
 
1412
+ ## File Management Components
1413
+
1414
+ ### FileUpload
1415
+
1416
+ A comprehensive file upload component with drag-and-drop support, validation, and progress tracking.
1417
+
1418
+ #### Props
1419
+
1420
+ ```typescript
1421
+ interface FileUploadProps {
1422
+ supabase: SupabaseClient;
1423
+ appName: string;
1424
+ orgId: string;
1425
+ onUploadComplete?: (fileRef: FileReference) => void;
1426
+ onUploadStart?: (file: File) => void;
1427
+ accept?: string;
1428
+ maxSize?: number;
1429
+ multiple?: boolean;
1430
+ disabled?: boolean;
1431
+ className?: string;
1432
+ children?: React.ReactNode;
1433
+ }
1434
+ ```
1435
+
1436
+ #### Usage
1437
+
1438
+ ```tsx
1439
+ import { FileUpload, FileCategory } from '@jmruthers/pace-core';
1440
+
1441
+ function MyFileUpload() {
1442
+ const handleUpload = (fileRef: FileReference) => {
1443
+ console.log('File uploaded:', fileRef);
1444
+ };
1445
+
1446
+ return (
1447
+ <FileUpload
1448
+ supabase={supabase}
1449
+ appName="my-app"
1450
+ orgId={organisationId}
1451
+ onUploadComplete={handleUpload}
1452
+ accept="image/*"
1453
+ maxSize={2 * 1024 * 1024} // 2MB
1454
+ >
1455
+ <div className="border-2 border-dashed border-main-300 rounded-lg p-8 text-center">
1456
+ <p>Drag and drop files here or click to browse</p>
1457
+ </div>
1458
+ </FileUpload>
1459
+ );
1460
+ }
1461
+ ```
1462
+
1463
+ For detailed implementation, see [File Upload & Storage Guide](../implementation-guides/file-upload-storage.md).
1464
+
1465
+ ### InactivityWarningModal
1466
+
1467
+ A modal component that displays inactivity warnings with countdown timer and action buttons.
1468
+
1469
+ #### Props
1470
+
1471
+ ```typescript
1472
+ interface InactivityWarningModalProps {
1473
+ isOpen: boolean;
1474
+ timeRemaining: number;
1475
+ onStayActive: () => void;
1476
+ onSignOut: () => void;
1477
+ title?: string;
1478
+ message?: string;
1479
+ stayActiveText?: string;
1480
+ signOutText?: string;
1481
+ className?: string;
1482
+ }
1483
+ ```
1484
+
1485
+ #### Usage
1486
+
1487
+ ```tsx
1488
+ import { InactivityWarningModal, useInactivityTracker } from '@jmruthers/pace-core';
1489
+
1490
+ function MyApp() {
1491
+ const { showWarning, timeRemaining, resetActivity } = useInactivityTracker({
1492
+ idleTimeoutMs: 30 * 60 * 1000,
1493
+ warnBeforeMs: 5 * 60 * 1000
1494
+ });
1495
+
1496
+ return (
1497
+ <div>
1498
+ <h1>My App</h1>
1499
+
1500
+ <InactivityWarningModal
1501
+ isOpen={showWarning}
1502
+ timeRemaining={timeRemaining}
1503
+ onStayActive={resetActivity}
1504
+ onSignOut={() => signOut()}
1505
+ title="Session Timeout Warning"
1506
+ message="You will be signed out due to inactivity."
1507
+ />
1508
+ </div>
1509
+ );
1510
+ }
1511
+ ```
1512
+
1513
+ For detailed implementation, see [Inactivity Tracking Guide](../implementation-guides/inactivity-tracking.md).
1514
+
1515
+ ### EventLogo
1516
+
1517
+ A component for displaying event logos with automatic loading and caching.
1518
+
1519
+ #### Props
1520
+
1521
+ ```typescript
1522
+ interface EventLogoProps {
1523
+ eventId: string;
1524
+ size?: 'small' | 'medium' | 'large' | 'xlarge';
1525
+ variant?: 'default' | 'square' | 'wide';
1526
+ className?: string;
1527
+ fallback?: React.ReactNode;
1528
+ showLoading?: boolean;
1529
+ }
1530
+ ```
1531
+
1532
+ #### Usage
1533
+
1534
+ ```tsx
1535
+ import { EventLogo } from '@jmruthers/pace-core';
1536
+
1537
+ function EventHeader({ eventId }: { eventId: string }) {
1538
+ return (
1539
+ <div className="text-center">
1540
+ <EventLogo
1541
+ eventId={eventId}
1542
+ size="large"
1543
+ className="mx-auto mb-4"
1544
+ />
1545
+ <h1>Event Name</h1>
1546
+ </div>
1547
+ );
1548
+ }
1549
+ ```
1550
+
1551
+ For detailed implementation, see [Public Pages Advanced Guide](../implementation-guides/public-pages-advanced.md).
1552
+
1575
1553
  ## Component Styling
1576
1554
 
1577
1555
  All components use Tailwind CSS for styling and support:
@@ -614,6 +614,353 @@ function PublicComponent() {
614
614
 
615
615
  For detailed public page implementation, see [Public Pages Guide](../implementation-guides/public-pages.md).
616
616
 
617
+ ## Inactivity Tracking Hooks
618
+
619
+ ### useInactivityTracker
620
+
621
+ Hook for tracking user inactivity with configurable timeouts and callbacks.
622
+
623
+ ```typescript
624
+ interface UseInactivityTrackerOptions {
625
+ idleTimeoutMs?: number;
626
+ warnBeforeMs?: number;
627
+ onIdle?: () => void;
628
+ onWarning?: () => void;
629
+ onActivity?: () => void;
630
+ events?: string[];
631
+ throttleMs?: number;
632
+ enableCrossTabSync?: boolean;
633
+ storageKey?: string;
634
+ debug?: boolean;
635
+ }
636
+
637
+ interface UseInactivityTrackerReturn {
638
+ isIdle: boolean;
639
+ timeRemaining: number;
640
+ showWarning: boolean;
641
+ resetActivity: () => void;
642
+ startTracking: () => void;
643
+ stopTracking: () => void;
644
+ getActivityStatus: () => {
645
+ isIdle: boolean;
646
+ timeRemaining: number;
647
+ lastActivity: number;
648
+ };
649
+ }
650
+
651
+ function useInactivityTracker(options?: UseInactivityTrackerOptions): UseInactivityTrackerReturn;
652
+ ```
653
+
654
+ **Usage:**
655
+ ```tsx
656
+ import { useInactivityTracker } from '@jmruthers/pace-core';
657
+
658
+ function MyComponent() {
659
+ const { isIdle, timeRemaining, showWarning, resetActivity } = useInactivityTracker({
660
+ idleTimeoutMs: 30 * 60 * 1000, // 30 minutes
661
+ warnBeforeMs: 5 * 60 * 1000, // 5 minutes warning
662
+ onIdle: () => {
663
+ console.log('User is idle');
664
+ signOut();
665
+ },
666
+ onWarning: () => {
667
+ console.log('Warning: User will be idle soon');
668
+ }
669
+ });
670
+
671
+ return (
672
+ <div>
673
+ <p>Idle: {isIdle ? 'Yes' : 'No'}</p>
674
+ <p>Time remaining: {Math.floor(timeRemaining / 1000)}s</p>
675
+ {showWarning && (
676
+ <div>
677
+ <p>You will be signed out soon due to inactivity.</p>
678
+ <button onClick={resetActivity}>Stay Active</button>
679
+ </div>
680
+ )}
681
+ </div>
682
+ );
683
+ }
684
+ ```
685
+
686
+ For detailed implementation, see [Inactivity Tracking Guide](../implementation-guides/inactivity-tracking.md).
687
+
688
+ ## Organisation Security Hooks
689
+
690
+ ### useOrganisationSecurity
691
+
692
+ Hook for organisation-level security operations and super admin functionality.
693
+
694
+ ```typescript
695
+ interface OrganisationSecurityHook {
696
+ superAdminContext: SuperAdminContext;
697
+ validateOrganisationAccess: (orgId: string) => Promise<boolean>;
698
+ hasMinimumRole: (minRole: string, orgId?: string) => boolean;
699
+ canAccessChildOrganisations: (orgId?: string) => boolean;
700
+ hasPermission: (permission: string, orgId?: string) => Promise<boolean>;
701
+ getUserPermissions: (orgId?: string) => Promise<string[]>;
702
+ logOrganisationAccess: (action: string, details?: any) => Promise<void>;
703
+ ensureOrganisationAccess: (orgId: string) => Promise<void>;
704
+ validateUserAccess: (userId: string, orgId: string) => Promise<boolean>;
705
+ }
706
+
707
+ interface SuperAdminContext {
708
+ isSuperAdmin: boolean;
709
+ context: 'organisation' | 'event' | 'global';
710
+ bypassEnabled: boolean;
711
+ elevatedPermissions: string[];
712
+ }
713
+
714
+ function useOrganisationSecurity(): OrganisationSecurityHook;
715
+ ```
716
+
717
+ **Usage:**
718
+ ```tsx
719
+ import { useOrganisationSecurity } from '@jmruthers/pace-core';
720
+
721
+ function SecureComponent() {
722
+ const {
723
+ superAdminContext,
724
+ validateOrganisationAccess,
725
+ hasPermission,
726
+ logOrganisationAccess
727
+ } = useOrganisationSecurity();
728
+
729
+ const handleSecureAction = async () => {
730
+ try {
731
+ const hasAccess = await validateOrganisationAccess(organisationId);
732
+ if (!hasAccess) {
733
+ throw new Error('Access denied');
734
+ }
735
+
736
+ const canEdit = await hasPermission('update:users', organisationId);
737
+ if (!canEdit) {
738
+ throw new Error('Insufficient permissions');
739
+ }
740
+
741
+ await logOrganisationAccess('user_update', { userId, organisationId });
742
+ // Perform secure action
743
+ } catch (error) {
744
+ console.error('Security check failed:', error);
745
+ }
746
+ };
747
+
748
+ return (
749
+ <div>
750
+ <p>Super Admin: {superAdminContext.isSuperAdmin ? 'Yes' : 'No'}</p>
751
+ <button onClick={handleSecureAction}>Perform Secure Action</button>
752
+ </div>
753
+ );
754
+ }
755
+ ```
756
+
757
+ For detailed implementation, see [Organisation Security Guide](../implementation-guides/organisation-security.md).
758
+
759
+ ## Storage Hooks
760
+
761
+ ### useStorage
762
+
763
+ Hook for file storage operations with Supabase.
764
+
765
+ ```typescript
766
+ interface UseStorageOptions {
767
+ bucket?: string;
768
+ folder?: string;
769
+ maxFileSize?: number;
770
+ allowedTypes?: string[];
771
+ }
772
+
773
+ interface UseStorageReturn {
774
+ uploadFile: (file: File, path?: string) => Promise<string>;
775
+ downloadFile: (path: string) => Promise<Blob>;
776
+ deleteFile: (path: string) => Promise<void>;
777
+ getPublicUrl: (path: string) => string;
778
+ isLoading: boolean;
779
+ error: Error | null;
780
+ }
781
+
782
+ function useStorage(options?: UseStorageOptions): UseStorageReturn;
783
+ ```
784
+
785
+ **Usage:**
786
+ ```tsx
787
+ import { useStorage } from '@jmruthers/pace-core';
788
+
789
+ function FileUpload() {
790
+ const { uploadFile, isLoading, error } = useStorage({
791
+ bucket: 'my-bucket',
792
+ folder: 'uploads',
793
+ maxFileSize: 5 * 1024 * 1024, // 5MB
794
+ allowedTypes: ['image/jpeg', 'image/png', 'application/pdf']
795
+ });
796
+
797
+ const handleFileUpload = async (file: File) => {
798
+ try {
799
+ const url = await uploadFile(file);
800
+ console.log('File uploaded:', url);
801
+ } catch (err) {
802
+ console.error('Upload failed:', err);
803
+ }
804
+ };
805
+
806
+ return (
807
+ <div>
808
+ <input
809
+ type="file"
810
+ onChange={(e) => e.target.files?.[0] && handleFileUpload(e.target.files[0])}
811
+ disabled={isLoading}
812
+ />
813
+ {isLoading && <div>Uploading...</div>}
814
+ {error && <div>Error: {error.message}</div>}
815
+ </div>
816
+ );
817
+ }
818
+ ```
819
+
820
+ ### useFileUpload
821
+
822
+ Hook for file upload operations with progress tracking.
823
+
824
+ ```typescript
825
+ interface UseFileUploadOptions {
826
+ onProgress?: (progress: number) => void;
827
+ onSuccess?: (url: string) => void;
828
+ onError?: (error: Error) => void;
829
+ }
830
+
831
+ interface UseFileUploadReturn {
832
+ uploadFile: (file: File, path?: string) => Promise<string>;
833
+ uploadProgress: number;
834
+ isUploading: boolean;
835
+ error: Error | null;
836
+ reset: () => void;
837
+ }
838
+
839
+ function useFileUpload(options?: UseFileUploadOptions): UseFileUploadReturn;
840
+ ```
841
+
842
+ **Usage:**
843
+ ```tsx
844
+ import { useFileUpload } from '@jmruthers/pace-core';
845
+
846
+ function FileUploadWithProgress() {
847
+ const { uploadFile, uploadProgress, isUploading, error, reset } = useFileUpload({
848
+ onProgress: (progress) => console.log(`Upload progress: ${progress}%`),
849
+ onSuccess: (url) => console.log('Upload successful:', url),
850
+ onError: (error) => console.error('Upload failed:', error)
851
+ });
852
+
853
+ const handleFileUpload = async (file: File) => {
854
+ try {
855
+ await uploadFile(file, `uploads/${file.name}`);
856
+ } catch (err) {
857
+ console.error('Upload failed:', err);
858
+ }
859
+ };
860
+
861
+ return (
862
+ <div>
863
+ <input
864
+ type="file"
865
+ onChange={(e) => e.target.files?.[0] && handleFileUpload(e.target.files[0])}
866
+ disabled={isUploading}
867
+ />
868
+ {isUploading && (
869
+ <div>
870
+ <div>Uploading... {uploadProgress}%</div>
871
+ <div className="w-full bg-sec-200 rounded-full h-2">
872
+ <div
873
+ className="bg-main-600 h-2 rounded-full transition-all duration-300"
874
+ style={{ width: `${uploadProgress}%` }}
875
+ />
876
+ </div>
877
+ </div>
878
+ )}
879
+ {error && (
880
+ <div>
881
+ <div>Error: {error.message}</div>
882
+ <button onClick={reset}>Try Again</button>
883
+ </div>
884
+ )}
885
+ </div>
886
+ );
887
+ }
888
+ ```
889
+
890
+ For detailed implementation, see [File Upload & Storage Guide](../implementation-guides/file-upload-storage.md).
891
+
892
+ ## App Configuration Hooks
893
+
894
+ ### useAppConfig
895
+
896
+ Hook for accessing and managing app configuration.
897
+
898
+ ```typescript
899
+ interface UseAppConfigReturn {
900
+ config: AppConfig | null;
901
+ isLoading: boolean;
902
+ error: Error | null;
903
+ updateConfig: (updates: Partial<AppConfig>) => Promise<void>;
904
+ resetConfig: () => Promise<void>;
905
+ }
906
+
907
+ interface AppConfig {
908
+ appName: string;
909
+ appId: string;
910
+ version: string;
911
+ environment: 'development' | 'staging' | 'production';
912
+ features: Record<string, boolean>;
913
+ settings: Record<string, any>;
914
+ }
915
+
916
+ function useAppConfig(): UseAppConfigReturn;
917
+ ```
918
+
919
+ **Usage:**
920
+ ```tsx
921
+ import { useAppConfig } from '@jmruthers/pace-core';
922
+
923
+ function AppSettings() {
924
+ const { config, isLoading, error, updateConfig } = useAppConfig();
925
+
926
+ const handleToggleFeature = async (featureName: string) => {
927
+ if (!config) return;
928
+
929
+ await updateConfig({
930
+ features: {
931
+ ...config.features,
932
+ [featureName]: !config.features[featureName]
933
+ }
934
+ });
935
+ };
936
+
937
+ if (isLoading) return <div>Loading configuration...</div>;
938
+ if (error) return <div>Error: {error.message}</div>;
939
+ if (!config) return <div>No configuration available</div>;
940
+
941
+ return (
942
+ <div>
943
+ <h2>App Configuration</h2>
944
+ <p>App Name: {config.appName}</p>
945
+ <p>Version: {config.version}</p>
946
+ <p>Environment: {config.environment}</p>
947
+
948
+ <h3>Features</h3>
949
+ {Object.entries(config.features).map(([name, enabled]) => (
950
+ <label key={name}>
951
+ <input
952
+ type="checkbox"
953
+ checked={enabled}
954
+ onChange={() => handleToggleFeature(name)}
955
+ />
956
+ {name}
957
+ </label>
958
+ ))}
959
+ </div>
960
+ );
961
+ }
962
+ ```
963
+
617
964
  ## Hook Testing
618
965
 
619
966
  All hooks include comprehensive testing: