@jmruthers/pace-core 0.5.135 → 0.5.137
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DataTable-A36PJG6N.js → DataTable-6M4L6BI2.js} +26 -13
- package/dist/{DataTable-C7GaRZye.d.ts → DataTable-CWAZZcXC.d.ts} +1 -1
- package/dist/{PublicLoadingSpinner-CUAnTvcg.d.ts → EventLogo-rFL_kRjk.d.ts} +123 -135
- package/dist/{UnifiedAuthProvider-BVKmQd9u.d.ts → UnifiedAuthProvider-DJxGTftH.d.ts} +1 -1
- package/dist/{UnifiedAuthProvider-CQDZRJIS.js → UnifiedAuthProvider-XIQQ7LVU.js} +5 -5
- package/dist/{api-TNIBJWLM.js → api-45XYYO2A.js} +4 -3
- package/dist/{audit-T36HM7IM.js → audit-64X3VJXB.js} +3 -2
- package/dist/{chunk-F64FFPOZ.js → chunk-22WKWKRX.js} +26 -20
- package/dist/chunk-22WKWKRX.js.map +1 -0
- package/dist/{chunk-VZ5OR6HD.js → chunk-4C7EXCAR.js} +62 -150
- package/dist/chunk-4C7EXCAR.js.map +1 -0
- package/dist/{chunk-PYUXFQJ3.js → chunk-56XJ3TU6.js} +2 -2
- package/dist/chunk-56XJ3TU6.js.map +1 -0
- package/dist/{chunk-CTJRBUX2.js → chunk-6LAAY47Q.js} +2 -2
- package/dist/{chunk-UJI6WSMD.js → chunk-7QCC6MCP.js} +90 -3
- package/dist/chunk-7QCC6MCP.js.map +1 -0
- package/dist/{chunk-66C4BSAY.js → chunk-ANBQRTPX.js} +9 -2
- package/dist/chunk-ANBQRTPX.js.map +1 -0
- package/dist/{chunk-CQZU6TFE.js → chunk-BCIBECNB.js} +100 -62
- package/dist/chunk-BCIBECNB.js.map +1 -0
- package/dist/{chunk-GKHF54DI.js → chunk-BESYRHQM.js} +10 -4
- package/dist/chunk-BESYRHQM.js.map +1 -0
- package/dist/chunk-BJPBT3CU.js +21 -0
- package/dist/chunk-BJPBT3CU.js.map +1 -0
- package/dist/{chunk-BYXRHAIF.js → chunk-BLCXZEYF.js} +23 -14
- package/dist/chunk-BLCXZEYF.js.map +1 -0
- package/dist/{chunk-WP5I5GLN.js → chunk-BVYWGZVV.js} +112 -97
- package/dist/chunk-BVYWGZVV.js.map +1 -0
- package/dist/{chunk-GEVIB2UB.js → chunk-ERISIBYU.js} +14 -5
- package/dist/chunk-ERISIBYU.js.map +1 -0
- package/dist/{chunk-O3NWNXDY.js → chunk-FMUCXFII.js} +2 -2
- package/dist/chunk-FMUCXFII.js.map +1 -0
- package/dist/{chunk-GVDR7WNV.js → chunk-HAWZXGR2.js} +334 -614
- package/dist/chunk-HAWZXGR2.js.map +1 -0
- package/dist/{chunk-ZV77RZMU.js → chunk-INQLMHPF.js} +2 -2
- package/dist/chunk-JISYG63F.js +70 -0
- package/dist/chunk-JISYG63F.js.map +1 -0
- package/dist/{chunk-HMNOSGVA.js → chunk-KYRHUBIU.js} +576 -767
- package/dist/chunk-KYRHUBIU.js.map +1 -0
- package/dist/{chunk-M6DDYFUD.js → chunk-LS353YLY.js} +19 -16
- package/dist/chunk-LS353YLY.js.map +1 -0
- package/dist/{chunk-TGIY2AR2.js → chunk-MA6EPSGZ.js} +4 -3
- package/dist/{chunk-TGIY2AR2.js.map → chunk-MA6EPSGZ.js.map} +1 -1
- package/dist/chunk-OWAG3GSU.js +58 -0
- package/dist/chunk-OWAG3GSU.js.map +1 -0
- package/dist/{chunk-JCQZ6LA7.js → chunk-Q5QRDWKI.js} +9 -3
- package/dist/chunk-Q5QRDWKI.js.map +1 -0
- package/dist/chunk-S5OFRT4M.js +94 -0
- package/dist/chunk-S5OFRT4M.js.map +1 -0
- package/dist/{chunk-3DBFLLLU.js → chunk-SBVILCCA.js} +14 -9
- package/dist/chunk-SBVILCCA.js.map +1 -0
- package/dist/{chunk-ZYZCRSBD.js → chunk-T6JN6LH6.js} +16 -11
- package/dist/chunk-T6JN6LH6.js.map +1 -0
- package/dist/chunk-XDNLUEXI.js +138 -0
- package/dist/chunk-XDNLUEXI.js.map +1 -0
- package/dist/{chunk-3CG5L6RN.js → chunk-YCWDTTUK.js} +90 -75
- package/dist/chunk-YCWDTTUK.js.map +1 -0
- package/dist/{chunk-5F3NDPJV.js → chunk-ZZ2SS7NI.js} +10 -5
- package/dist/chunk-ZZ2SS7NI.js.map +1 -0
- package/dist/components.d.ts +7 -287
- package/dist/components.js +27 -157
- package/dist/components.js.map +1 -1
- package/dist/{file-reference-C9isKNPn.d.ts → file-reference-C6Gkn77H.d.ts} +1 -1
- package/dist/{formatting-DFcCxUEk.d.ts → formatting-CvUXy2mF.d.ts} +1 -1
- package/dist/hooks.d.ts +3 -3
- package/dist/hooks.js +21 -16
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +101 -9
- package/dist/index.js +44 -31
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +4 -4
- package/dist/rbac/index.js +12 -12
- package/dist/schema-DTDZQe2u.d.ts +28 -0
- package/dist/styles/index.js +2 -1
- package/dist/theming/runtime.d.ts +2 -19
- package/dist/theming/runtime.js +2 -1
- package/dist/{types-D5rqZQXk.d.ts → types-Dfz9dmVH.d.ts} +12 -1
- package/dist/types.d.ts +153 -4
- package/dist/types.js +51 -16
- package/dist/types.js.map +1 -1
- package/dist/{useInactivityTracker-MRUU55XI.js → useInactivityTracker-TO6ZOF35.js} +3 -2
- package/dist/{usePublicRouteParams-Dyt1tzI9.d.ts → usePublicRouteParams-B7PabvuH.d.ts} +1 -1
- package/dist/utils.d.ts +221 -173
- package/dist/utils.js +185 -225
- package/dist/utils.js.map +1 -1
- package/dist/validation.d.ts +24 -115
- package/dist/validation.js +19 -474
- package/dist/validation.js.map +1 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +6 -6
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +6 -6
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +7 -7
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +1 -1
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +4 -4
- package/docs/api/interfaces/BadgeProps.md +27 -0
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +29 -4
- package/docs/api/interfaces/DataAccessRecord.md +9 -9
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +18 -18
- package/docs/api/interfaces/DataTableColumn.md +61 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +14 -14
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +152 -0
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +8 -8
- package/docs/api/interfaces/FileDisplayProps.md +15 -15
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
- package/docs/api/interfaces/NavigationContextType.md +9 -9
- package/docs/api/interfaces/NavigationGuardProps.md +10 -10
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +7 -7
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +27 -27
- package/docs/api/interfaces/PaceLoginPageProps.md +4 -4
- package/docs/api/interfaces/PageAccessRecord.md +8 -8
- package/docs/api/interfaces/PagePermissionContextType.md +8 -8
- package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
- package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
- package/docs/api/interfaces/PaletteData.md +4 -4
- package/docs/api/interfaces/PermissionEnforcerProps.md +11 -11
- package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
- package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +10 -10
- package/docs/api/interfaces/RouteConfig.md +10 -10
- package/docs/api/interfaces/SecureDataContextType.md +9 -9
- package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +21 -0
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +9 -9
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
- package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
- package/docs/api/interfaces/UsePublicEventReturn.md +5 -5
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +9 -9
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
- package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
- package/docs/api/interfaces/UserEventAccess.md +11 -11
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +591 -220
- package/docs/api-reference/components.md +106 -26
- package/docs/architecture/README.md +0 -3
- package/docs/implementation-guides/data-tables.md +277 -13
- package/docs/implementation-guides/forms.md +1 -16
- package/docs/implementation-guides/permission-enforcement.md +8 -2
- package/docs/styles/README.md +0 -2
- package/examples/README.md +30 -14
- package/examples/STRUCTURE.md +125 -0
- package/examples/components 2/DataTable/HierarchicalActionsExample.tsx +421 -0
- package/examples/components 2/DataTable/HierarchicalExample.tsx +475 -0
- package/examples/components 2/DataTable/InitialPageSizeExample.tsx +177 -0
- package/examples/components 2/DataTable/PerformanceExample.tsx +506 -0
- package/examples/components 2/DataTable/index.ts +13 -0
- package/examples/components 2/Dialog/BasicHtmlTest.tsx +55 -0
- package/examples/components 2/Dialog/DebugHtmlExample.tsx +68 -0
- package/examples/components 2/Dialog/HtmlDialogExample.tsx +202 -0
- package/examples/components 2/Dialog/ScrollableDialogExample.tsx +290 -0
- package/examples/components 2/Dialog/SimpleHtmlTest.tsx +61 -0
- package/examples/components 2/Dialog/SmartDialogExample.tsx +322 -0
- package/examples/components 2/Dialog/index.ts +15 -0
- package/examples/components 2/index.ts +11 -0
- package/examples/features/index.ts +12 -0
- package/{src/examples → examples/features/public-pages}/CorrectPublicPageImplementation.tsx +14 -17
- package/{src/examples → examples/features/public-pages}/PublicEventPage.tsx +14 -27
- package/{src/examples → examples/features/public-pages}/PublicPageApp.tsx +15 -28
- package/{src/examples → examples/features/public-pages}/PublicPageUsageExample.tsx +8 -10
- package/examples/features/public-pages/index.ts +14 -0
- package/examples/features/rbac/CompleteRBACExample.tsx +324 -0
- package/examples/features/rbac/EventBasedApp.tsx +239 -0
- package/examples/features/rbac/PermissionExample.tsx +151 -0
- package/examples/features/rbac/index.ts +13 -0
- package/examples/index.ts +11 -3
- package/package.json +30 -19
- package/src/__tests__/TEST_STANDARD.md +92 -0
- package/src/components/Alert/Alert.tsx +1 -1
- package/src/components/Avatar/Avatar.tsx +1 -1
- package/src/components/Badge/Badge.test.tsx +314 -0
- package/src/components/Badge/Badge.tsx +304 -0
- package/src/components/Badge/index.ts +3 -0
- package/src/components/Button/Button.tsx +1 -1
- package/src/components/Card/Card.tsx +1 -1
- package/src/components/Checkbox/Checkbox.tsx +1 -1
- package/src/components/DataTable/DataTable.test.tsx +1 -1
- package/src/components/DataTable/DataTable.tsx +1 -30
- package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +562 -0
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +217 -0
- package/src/components/DataTable/__tests__/styles.test.ts +3 -3
- package/src/components/DataTable/components/ActionButtons.tsx +0 -15
- package/src/components/DataTable/components/ColumnFilter.tsx +8 -4
- package/src/components/DataTable/components/DataTableBody.tsx +461 -0
- package/src/components/DataTable/components/DataTableCore.tsx +4 -185
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +1 -1
- package/src/components/DataTable/components/DataTableModals.tsx +1 -27
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +144 -0
- package/src/components/DataTable/components/EditableRow.tsx +1 -1
- package/src/components/DataTable/components/FilterRow.tsx +9 -3
- package/src/components/DataTable/components/ImportModal.tsx +2 -14
- package/src/components/DataTable/components/PaginationControls.tsx +2 -1
- package/src/components/DataTable/components/UnifiedTableBody.tsx +109 -82
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +513 -0
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +14 -68
- package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +62 -0
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +1 -1
- package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +43 -0
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +1 -1
- package/src/components/DataTable/core/ActionManager.ts +235 -0
- package/src/components/DataTable/core/ColumnManager.ts +205 -0
- package/src/components/DataTable/core/DataManager.ts +188 -0
- package/src/components/DataTable/core/DataTableContext.tsx +181 -0
- package/src/components/DataTable/core/LocalDataAdapter.ts +273 -0
- package/src/components/DataTable/core/PluginRegistry.ts +229 -0
- package/src/components/DataTable/core/StateManager.ts +311 -0
- package/src/components/DataTable/core/interfaces.ts +338 -0
- package/src/components/DataTable/examples/GroupingAggregationExample.tsx +273 -0
- package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +1 -1
- package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +1 -1
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +1 -1
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +1 -1
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +2 -23
- package/src/components/DataTable/index.ts +4 -0
- package/src/components/DataTable/styles.ts +28 -7
- package/src/components/DataTable/types.ts +13 -0
- package/src/components/DataTable/utils/__tests__/columnUtils.test.ts +94 -0
- package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +1 -1
- package/src/components/DataTable/utils/aggregationUtils.ts +161 -0
- package/src/components/DataTable/utils/columnUtils.ts +40 -0
- package/src/components/DataTable/utils/debugTools.ts +609 -0
- package/src/components/DataTable/utils/exportUtils.ts +1 -1
- package/src/components/DataTable/utils/flexibleImport.ts +1 -11
- package/src/components/DataTable/utils/index.ts +2 -0
- package/src/components/DataTable/utils/paginationUtils.ts +1 -1
- package/src/components/Dialog/Dialog.tsx +2 -2
- package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +8 -1
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +35 -7
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -4
- package/src/components/EventSelector/EventSelector.tsx +3 -2
- package/src/components/FileDisplay/FileDisplay.tsx +2 -36
- package/src/components/FileUpload/FileUpload.test.tsx +2 -2
- package/src/components/FileUpload/FileUpload.tsx +2 -2
- package/src/components/Footer/Footer.test.tsx +1 -1
- package/src/components/Footer/Footer.tsx +1 -1
- package/src/components/Form/Form.test.tsx +5 -510
- package/src/components/Form/Form.tsx +1 -1
- package/src/components/Form/FormField.tsx +1 -1
- package/src/components/Form/index.ts +0 -12
- package/src/components/Header/Header.tsx +1 -1
- package/src/components/Input/Input.tsx +1 -1
- package/src/components/Label/Label.tsx +1 -1
- package/src/components/LoginForm/LoginForm.test.tsx +1 -1
- package/src/components/LoginForm/LoginForm.tsx +1 -1
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -3
- package/src/components/NavigationMenu/NavigationMenu.tsx +9 -8
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +4 -3
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -12
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +0 -16
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +76 -10
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +0 -1
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -9
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +35 -3
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +14 -13
- package/src/components/PasswordReset/PasswordChangeForm.tsx +1 -1
- package/src/components/PasswordReset/index.ts +0 -2
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +35 -8
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -2
- package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
- package/src/components/PublicLayout/PublicLoadingSpinner.tsx +1 -1
- package/src/components/PublicLayout/PublicPageContextChecker.tsx +44 -43
- package/src/components/PublicLayout/PublicPageFooter.tsx +1 -1
- package/src/components/PublicLayout/PublicPageHeader.tsx +1 -15
- package/src/components/PublicLayout/PublicPageProvider.tsx +3 -2
- package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +2 -0
- package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +1 -1
- package/src/components/PublicLayout/index.ts +4 -2
- package/src/components/Select/Select.test.tsx +1 -1
- package/src/components/Select/Select.tsx +21 -9
- package/src/components/{SessionRestorationLoader.tsx → SessionRestorationLoader/SessionRestorationLoader.tsx} +3 -2
- package/src/components/SessionRestorationLoader/index.ts +3 -0
- package/src/components/Switch/Switch.tsx +1 -1
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Table/__tests__/Table.test.tsx +1 -1
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.tsx +1 -1
- package/src/components/index.ts +7 -10
- package/src/hooks/__tests__/hooks.integration.test.tsx +37 -22
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +33 -17
- package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +28 -3
- package/src/hooks/__tests__/useFileDisplay.unit.test.ts +36 -9
- package/src/hooks/__tests__/useFileUrl.unit.test.ts +83 -85
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +26 -2
- package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +19 -6
- package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -4
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +17 -4
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +26 -6
- package/src/hooks/__tests__/usePublicFileDisplay.test.ts +16 -6
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +3 -3
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +17 -3
- package/src/hooks/public/usePublicEvent.ts +7 -6
- package/src/hooks/public/usePublicEventLogo.ts +7 -4
- package/src/hooks/public/usePublicFileDisplay.ts +6 -150
- package/src/hooks/useComponentPerformance.ts +4 -1
- package/src/hooks/useDataTablePerformance.ts +4 -3
- package/src/hooks/useEventTheme.test.ts +18 -5
- package/src/hooks/useEventTheme.ts +4 -1
- package/src/hooks/useEvents.ts +2 -0
- package/src/hooks/useFileDisplay.ts +9 -8
- package/src/hooks/useFileReference.ts +4 -1
- package/src/hooks/useFileUrl.ts +4 -1
- package/src/hooks/useInactivityTracker.ts +5 -4
- package/src/hooks/useOrganisationSecurity.test.ts +33 -12
- package/src/hooks/useOrganisationSecurity.ts +8 -7
- package/src/hooks/usePerformanceMonitor.ts +6 -3
- package/src/hooks/usePermissionCache.ts +13 -6
- package/src/hooks/useSecureDataAccess.test.ts +2 -2
- package/src/hooks/useSecureDataAccess.ts +9 -8
- package/src/hooks/useSessionRestoration.ts +4 -1
- package/src/hooks/useStorage.ts +4 -1
- package/src/index.ts +20 -7
- package/src/providers/services/AuthServiceProvider.tsx +3 -2
- package/src/providers/services/EventServiceProvider.tsx +2 -1
- package/src/providers/services/InactivityServiceProvider.tsx +2 -1
- package/src/providers/services/OrganisationServiceProvider.tsx +2 -1
- package/src/providers/services/UnifiedAuthProvider.tsx +4 -3
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +22 -2
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +24 -2
- package/src/rbac/__tests__/cache-invalidation.test.ts +20 -6
- package/src/rbac/api.ts +5 -2
- package/src/rbac/audit-enhanced.ts +6 -6
- package/src/rbac/audit.test.ts +60 -38
- package/src/rbac/audit.ts +8 -8
- package/src/rbac/cache-invalidation.ts +7 -4
- package/src/rbac/components/EnhancedNavigationMenu.tsx +11 -5
- package/src/rbac/components/NavigationGuard.tsx +7 -3
- package/src/rbac/components/NavigationProvider.tsx +6 -3
- package/src/rbac/components/PagePermissionGuard.tsx +28 -16
- package/src/rbac/components/PagePermissionProvider.tsx +4 -1
- package/src/rbac/components/PermissionEnforcer.tsx +9 -3
- package/src/rbac/components/RoleBasedRouter.tsx +3 -1
- package/src/rbac/components/SecureDataProvider.tsx +7 -3
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +87 -61
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +83 -33
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +36 -13
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +2 -2
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +22 -8
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +19 -6
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +43 -17
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +42 -17
- package/src/rbac/engine.ts +15 -7
- package/src/rbac/hooks/usePermissions.ts +7 -3
- package/src/rbac/hooks/useResolvedScope.test.ts +2 -2
- package/src/rbac/hooks/useResolvedScope.ts +10 -7
- package/src/rbac/permissions.ts +5 -2
- package/src/rbac/security.test.ts +27 -16
- package/src/rbac/security.ts +5 -4
- package/src/services/AuthService.ts +22 -21
- package/src/services/EventService.ts +12 -12
- package/src/services/InactivityService.ts +5 -4
- package/src/services/OrganisationService.ts +26 -25
- package/src/services/__tests__/AuthService.test.ts +51 -19
- package/src/services/__tests__/EventService.test.ts +37 -5
- package/src/services/__tests__/InactivityService.test.ts +38 -4
- package/src/services/__tests__/OrganisationService.test.ts +3 -8
- package/src/services/base/BaseService.ts +3 -1
- package/src/styles/core.css +3 -0
- package/src/theming/__tests__/runtime.test.ts +21 -12
- package/src/theming/parseEventColours.ts +5 -19
- package/src/theming/runtime.ts +8 -4
- package/src/types/validation.ts +2 -29
- package/src/utils/__tests__/appConfig.unit.test.ts +1 -1
- package/src/utils/__tests__/audit.unit.test.ts +1 -1
- package/src/utils/__tests__/auth-utils.unit.test.ts +1 -1
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +19 -19
- package/src/utils/__tests__/cn.unit.test.ts +1 -1
- package/src/utils/__tests__/debugLogger.test.ts +1 -1
- package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -1
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -1
- package/src/utils/__tests__/formatting.unit.test.ts +1 -1
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +1 -1
- package/src/utils/__tests__/logger.unit.test.ts +1 -1
- package/src/utils/__tests__/organisationContext.unit.test.ts +1 -1
- package/src/utils/__tests__/performanceBenchmark.test.ts +1 -1
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +1 -1
- package/src/utils/__tests__/permissionTypes.unit.test.ts +1 -1
- package/src/utils/__tests__/permissionUtils.unit.test.ts +1 -1
- package/src/utils/__tests__/sanitization.unit.test.ts +1 -1
- package/src/utils/__tests__/schemaUtils.unit.test.ts +1 -1
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +1 -1
- package/src/utils/__tests__/secureErrors.unit.test.ts +33 -15
- package/src/utils/__tests__/secureStorage.unit.test.ts +1 -1
- package/src/utils/__tests__/security.unit.test.ts +40 -18
- package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -1
- package/src/utils/__tests__/sessionTracking.unit.test.ts +40 -29
- package/src/utils/__tests__/validationUtils.unit.test.ts +19 -6
- package/src/utils/app/appConfig.ts +47 -0
- package/src/utils/app/appIdResolver.test.ts +497 -0
- package/src/utils/app/appIdResolver.ts +133 -0
- package/src/utils/app/appNameResolver.simple.test.ts +212 -0
- package/src/utils/app/appNameResolver.test.ts +121 -0
- package/src/utils/app/appNameResolver.ts +195 -0
- package/src/utils/audit/audit.ts +127 -0
- package/src/utils/context/organisationContext.test.ts +322 -0
- package/src/utils/context/organisationContext.ts +156 -0
- package/src/utils/context/sessionTracking.ts +125 -0
- package/src/utils/core/cn.ts +7 -0
- package/src/utils/core/debugLogger.ts +67 -0
- package/src/utils/core/logger.ts +181 -0
- package/src/utils/device/deviceFingerprint.ts +215 -0
- package/src/utils/dynamic/dynamicUtils.ts +105 -0
- package/src/utils/dynamic/lazyLoad.tsx +44 -0
- package/src/utils/file-reference/__tests__/file-reference.test.ts +788 -0
- package/src/utils/file-reference/index.ts +501 -0
- package/src/utils/formatting/formatDate.test.ts +237 -0
- package/src/utils/formatting/formatting.ts +133 -0
- package/src/utils/index.ts +39 -54
- package/src/utils/performance/bundleAnalysis.ts +129 -0
- package/src/utils/performance/performanceBenchmark.ts +64 -0
- package/src/utils/performance/performanceBudgets.ts +110 -0
- package/src/utils/permissions/permissionTypes.ts +37 -0
- package/src/utils/permissions/permissionUtils.test.ts +393 -0
- package/src/utils/permissions/permissionUtils.ts +34 -0
- package/src/utils/security/auth-utils.ts +96 -0
- package/src/utils/security/secureDataAccess.test.ts +711 -0
- package/src/utils/security/secureDataAccess.ts +377 -0
- package/src/utils/security/secureErrors.ts +82 -0
- package/src/utils/security/secureStorage.ts +244 -0
- package/src/utils/security/security.ts +159 -0
- package/src/utils/security/securityMonitor.ts +45 -0
- package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -4
- package/src/utils/storage/helpers.ts +15 -8
- package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +598 -0
- package/src/{validation → utils/validation}/csrf.ts +1 -1
- package/src/utils/validation/htmlSanitization.ts +184 -0
- package/src/utils/validation/index.ts +79 -0
- package/src/utils/validation/sanitization.ts +333 -0
- package/src/{validation/schemaUtils.ts → utils/validation/schema.ts} +11 -6
- package/src/{validation → utils/validation}/sqlInjectionProtection.ts +2 -0
- package/src/utils/validation/validation.ts +111 -0
- package/src/utils/validation/validationUtils.ts +123 -0
- package/src/validation/index.ts +3 -34
- package/dist/chunk-24MKLB7U.js +0 -81
- package/dist/chunk-24MKLB7U.js.map +0 -1
- package/dist/chunk-3CG5L6RN.js.map +0 -1
- package/dist/chunk-3DBFLLLU.js.map +0 -1
- package/dist/chunk-5F3NDPJV.js.map +0 -1
- package/dist/chunk-66C4BSAY.js.map +0 -1
- package/dist/chunk-BDZUMRBD.js +0 -87
- package/dist/chunk-BDZUMRBD.js.map +0 -1
- package/dist/chunk-BYXRHAIF.js.map +0 -1
- package/dist/chunk-CDQ3PX7L.js +0 -18
- package/dist/chunk-CDQ3PX7L.js.map +0 -1
- package/dist/chunk-CQZU6TFE.js.map +0 -1
- package/dist/chunk-F64FFPOZ.js.map +0 -1
- package/dist/chunk-GEVIB2UB.js.map +0 -1
- package/dist/chunk-GKHF54DI.js.map +0 -1
- package/dist/chunk-GVDR7WNV.js.map +0 -1
- package/dist/chunk-HMNOSGVA.js.map +0 -1
- package/dist/chunk-JCQZ6LA7.js.map +0 -1
- package/dist/chunk-M6DDYFUD.js.map +0 -1
- package/dist/chunk-O3NWNXDY.js.map +0 -1
- package/dist/chunk-PYUXFQJ3.js.map +0 -1
- package/dist/chunk-UJI6WSMD.js.map +0 -1
- package/dist/chunk-VZ5OR6HD.js.map +0 -1
- package/dist/chunk-WP5I5GLN.js.map +0 -1
- package/dist/chunk-ZYZCRSBD.js.map +0 -1
- package/dist/validation-DnhrNMju.d.ts +0 -159
- package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +0 -185
- package/src/validation/__tests__/common.unit.test.ts +0 -101
- package/src/validation/__tests__/csrf.unit.test.ts +0 -365
- package/src/validation/__tests__/passwordSchema.unit.test.ts +0 -203
- package/src/validation/__tests__/sanitization.unit.test.ts +0 -250
- package/src/validation/__tests__/schemaUtils.unit.test.ts +0 -451
- package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +0 -462
- package/src/validation/__tests__/user.unit.test.ts +0 -440
- package/src/validation/sanitization.ts +0 -96
- /package/dist/{DataTable-A36PJG6N.js.map → DataTable-6M4L6BI2.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-CQDZRJIS.js.map → UnifiedAuthProvider-XIQQ7LVU.js.map} +0 -0
- /package/dist/{api-TNIBJWLM.js.map → api-45XYYO2A.js.map} +0 -0
- /package/dist/{audit-T36HM7IM.js.map → audit-64X3VJXB.js.map} +0 -0
- /package/dist/{chunk-CTJRBUX2.js.map → chunk-6LAAY47Q.js.map} +0 -0
- /package/dist/{chunk-ZV77RZMU.js.map → chunk-INQLMHPF.js.map} +0 -0
- /package/dist/{useInactivityTracker-MRUU55XI.js.map → useInactivityTracker-TO6ZOF35.js.map} +0 -0
- /package/src/{validation → utils/validation}/common.ts +0 -0
- /package/src/{validation → utils/validation}/passwordSchema.ts +0 -0
- /package/src/{validation → utils/validation}/user.ts +0 -0
|
@@ -98,7 +98,21 @@ describe('ProtectedRoute Component', () => {
|
|
|
98
98
|
isLoading: false,
|
|
99
99
|
};
|
|
100
100
|
|
|
101
|
+
let originalMode: string | undefined;
|
|
102
|
+
|
|
101
103
|
beforeEach(() => {
|
|
104
|
+
// Ensure logger is enabled by setting MODE to development
|
|
105
|
+
originalMode = import.meta.env.MODE;
|
|
106
|
+
(import.meta.env as any).MODE = 'development';
|
|
107
|
+
|
|
108
|
+
import('../../utils/core/logger').then(({ Logger, LogLevel }) => {
|
|
109
|
+
Logger.configure({
|
|
110
|
+
level: LogLevel.DEBUG,
|
|
111
|
+
includeTimestamp: false,
|
|
112
|
+
includeComponent: true,
|
|
113
|
+
});
|
|
114
|
+
});
|
|
115
|
+
|
|
102
116
|
vi.clearAllMocks();
|
|
103
117
|
console.debug = vi.fn();
|
|
104
118
|
console.warn = vi.fn();
|
|
@@ -112,6 +126,11 @@ describe('ProtectedRoute Component', () => {
|
|
|
112
126
|
afterEach(() => {
|
|
113
127
|
console.debug = originalConsoleDebug;
|
|
114
128
|
console.warn = originalConsoleWarn;
|
|
129
|
+
|
|
130
|
+
// Restore original mode
|
|
131
|
+
if (originalMode !== undefined) {
|
|
132
|
+
(import.meta.env as any).MODE = originalMode;
|
|
133
|
+
}
|
|
115
134
|
});
|
|
116
135
|
|
|
117
136
|
describe('Rendering', () => {
|
|
@@ -124,6 +143,8 @@ describe('ProtectedRoute Component', () => {
|
|
|
124
143
|
});
|
|
125
144
|
|
|
126
145
|
it('renders outlet when events exist but none selected (allows event selector visibility)', () => {
|
|
146
|
+
const consoleDebugSpy = vi.spyOn(console, 'debug').mockImplementation(() => {});
|
|
147
|
+
|
|
127
148
|
mockUseEvents.mockReturnValue({
|
|
128
149
|
selectedEvent: null,
|
|
129
150
|
events: [{ id: 'event-1', name: 'Test Event' }],
|
|
@@ -133,8 +154,8 @@ describe('ProtectedRoute Component', () => {
|
|
|
133
154
|
renderWithProviders(<ProtectedRoute />);
|
|
134
155
|
|
|
135
156
|
expect(screen.getByTestId('outlet')).toBeInTheDocument();
|
|
136
|
-
expect(
|
|
137
|
-
'[ProtectedRoute] Events available but none selected - allowing render so selector is visible'
|
|
157
|
+
expect(consoleDebugSpy).toHaveBeenCalledWith(
|
|
158
|
+
expect.stringContaining('[DEBUG] [ProtectedRoute] Events available but none selected - allowing render so selector is visible')
|
|
138
159
|
);
|
|
139
160
|
});
|
|
140
161
|
|
|
@@ -222,6 +243,8 @@ describe('ProtectedRoute Component', () => {
|
|
|
222
243
|
});
|
|
223
244
|
|
|
224
245
|
it('warns when redirecting due to session restoration timeout', () => {
|
|
246
|
+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
247
|
+
|
|
225
248
|
mockUseUnifiedAuth.mockReturnValue({
|
|
226
249
|
isAuthenticated: false,
|
|
227
250
|
authLoading: false,
|
|
@@ -236,8 +259,8 @@ describe('ProtectedRoute Component', () => {
|
|
|
236
259
|
|
|
237
260
|
renderWithProviders(<ProtectedRoute />);
|
|
238
261
|
|
|
239
|
-
expect(
|
|
240
|
-
'[ProtectedRoute] Session restoration failed, redirecting to login',
|
|
262
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
263
|
+
expect.stringContaining('[WARN] [ProtectedRoute] Session restoration failed, redirecting to login'),
|
|
241
264
|
expect.objectContaining({
|
|
242
265
|
timedOut: true,
|
|
243
266
|
})
|
|
@@ -259,10 +282,12 @@ describe('ProtectedRoute Component', () => {
|
|
|
259
282
|
hasTimedOut: false,
|
|
260
283
|
});
|
|
261
284
|
|
|
285
|
+
const consoleWarnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
|
|
286
|
+
|
|
262
287
|
renderWithProviders(<ProtectedRoute />);
|
|
263
288
|
|
|
264
|
-
expect(
|
|
265
|
-
'[ProtectedRoute] Session restoration failed, redirecting to login',
|
|
289
|
+
expect(consoleWarnSpy).toHaveBeenCalledWith(
|
|
290
|
+
expect.stringContaining('[WARN] [ProtectedRoute] Session restoration failed, redirecting to login'),
|
|
266
291
|
expect.objectContaining({
|
|
267
292
|
error: 'Session restoration failed',
|
|
268
293
|
timedOut: false,
|
|
@@ -408,11 +433,13 @@ describe('ProtectedRoute Component', () => {
|
|
|
408
433
|
isLoading: false,
|
|
409
434
|
});
|
|
410
435
|
|
|
436
|
+
const consoleDebugSpy = vi.spyOn(console, 'debug').mockImplementation(() => {});
|
|
437
|
+
|
|
411
438
|
renderWithProviders(<ProtectedRoute requireEvent={true} />);
|
|
412
439
|
|
|
413
440
|
expect(screen.getByTestId('outlet')).toBeInTheDocument();
|
|
414
|
-
expect(
|
|
415
|
-
'[ProtectedRoute] Events available but none selected - allowing render so selector is visible'
|
|
441
|
+
expect(consoleDebugSpy).toHaveBeenCalledWith(
|
|
442
|
+
expect.stringContaining('[DEBUG] [ProtectedRoute] Events available but none selected - allowing render so selector is visible')
|
|
416
443
|
);
|
|
417
444
|
});
|
|
418
445
|
|
|
@@ -76,6 +76,7 @@ import { useEvents } from '../../hooks/useEvents';
|
|
|
76
76
|
import { LoadingSpinner } from '../LoadingSpinner/LoadingSpinner';
|
|
77
77
|
import { SessionRestorationLoader } from '../SessionRestorationLoader';
|
|
78
78
|
import { Alert, AlertDescription, AlertTitle } from '../Alert/Alert';
|
|
79
|
+
import { logger } from '../../utils/core/logger';
|
|
79
80
|
|
|
80
81
|
export interface ProtectedRouteProps {
|
|
81
82
|
/**
|
|
@@ -175,7 +176,7 @@ export function ProtectedRoute({
|
|
|
175
176
|
// Redirect to login if not authenticated
|
|
176
177
|
if (!isAuthenticated) {
|
|
177
178
|
if (sessionRestoration.hasTimedOut || sessionRestoration.restorationError) {
|
|
178
|
-
|
|
179
|
+
logger.warn('ProtectedRoute', 'Session restoration failed, redirecting to login', {
|
|
179
180
|
timedOut: sessionRestoration.hasTimedOut,
|
|
180
181
|
error: sessionRestoration.restorationError?.message
|
|
181
182
|
});
|
|
@@ -217,7 +218,7 @@ export function ProtectedRoute({
|
|
|
217
218
|
// The event selector will be visible and user can select, or auto-selection will kick in
|
|
218
219
|
if (!selectedEvent) {
|
|
219
220
|
// Log for debugging - this is expected behavior, not an error
|
|
220
|
-
|
|
221
|
+
logger.debug('ProtectedRoute', 'Events available but none selected - allowing render so selector is visible');
|
|
221
222
|
return <Outlet />;
|
|
222
223
|
}
|
|
223
224
|
|
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
import React, { useEffect } from 'react';
|
|
12
12
|
import { usePublicPageContext } from './PublicPageProvider';
|
|
13
|
+
import { logger } from '../../utils/core/logger';
|
|
13
14
|
|
|
14
15
|
export interface PublicPageContextCheckerProps {
|
|
15
16
|
/** Whether to enable checking */
|
|
@@ -23,88 +24,88 @@ export interface PublicPageContextCheckerProps {
|
|
|
23
24
|
*
|
|
24
25
|
* This component will immediately log to console if authentication context
|
|
25
26
|
* is being triggered in a public page.
|
|
27
|
+
*
|
|
28
|
+
* Only enabled in development mode when VITE_ENABLE_DEBUG_LOGS is 'true'
|
|
26
29
|
*/
|
|
27
30
|
export function PublicPageContextChecker({ enabled = true, label = 'PublicPage' }: PublicPageContextCheckerProps) {
|
|
31
|
+
// Check if debug logging is enabled
|
|
32
|
+
// Allow in development mode with VITE_ENABLE_DEBUG_LOGS, or in test mode
|
|
33
|
+
// Also check for VITEST environment variable which is set by Vitest
|
|
34
|
+
const isDebugEnabled =
|
|
35
|
+
(import.meta.env.MODE === 'development' && import.meta.env.VITE_ENABLE_DEBUG_LOGS === 'true') ||
|
|
36
|
+
import.meta.env.MODE === 'test' ||
|
|
37
|
+
import.meta.env.VITEST === true ||
|
|
38
|
+
(typeof process !== 'undefined' && process.env.NODE_ENV === 'test');
|
|
39
|
+
|
|
40
|
+
// Early return if not in debug mode
|
|
41
|
+
if (!isDebugEnabled || !enabled) {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
|
|
28
45
|
useEffect(() => {
|
|
29
|
-
if (!enabled) return;
|
|
30
46
|
|
|
31
|
-
|
|
47
|
+
logger.debug('PublicPageContextChecker', `🚨 [${label}] PUBLIC PAGE CONTEXT CHECK`);
|
|
32
48
|
|
|
33
49
|
// Check for authentication context
|
|
34
50
|
try {
|
|
35
51
|
// This will throw if we're not in UnifiedAuthProvider
|
|
36
52
|
const { isAuthenticated } = require('../../providers/UnifiedAuthProvider').useUnifiedAuth();
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
53
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] AUTHENTICATION CONTEXT DETECTED!`);
|
|
54
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] isAuthenticated:`, isAuthenticated);
|
|
55
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] This public page is inside UnifiedAuthProvider - THIS IS WRONG!`);
|
|
56
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] SOLUTION: Move public routes outside of authentication providers`);
|
|
41
57
|
} catch (error) {
|
|
42
|
-
|
|
58
|
+
logger.debug('PublicPageContextChecker', `✅ [${label}] No authentication context detected (GOOD!)`);
|
|
43
59
|
}
|
|
44
60
|
|
|
45
61
|
// Check for organisation context
|
|
46
62
|
try {
|
|
47
63
|
// This will throw if we're not in OrganisationProvider
|
|
48
64
|
const { selectedOrganisation } = require('../../providers/OrganisationProvider').useOrganisations();
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
65
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] ORGANISATION CONTEXT DETECTED!`);
|
|
66
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] selectedOrganisation:`, selectedOrganisation);
|
|
67
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] This public page is inside OrganisationProvider - THIS IS WRONG!`);
|
|
68
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] SOLUTION: Move public routes outside of authentication providers`);
|
|
53
69
|
} catch (error) {
|
|
54
|
-
|
|
70
|
+
logger.debug('PublicPageContextChecker', `✅ [${label}] No organisation context detected (GOOD!)`);
|
|
55
71
|
}
|
|
56
72
|
|
|
57
73
|
// Check for event context
|
|
58
74
|
try {
|
|
59
75
|
// This will throw if we're not in EventProvider
|
|
60
76
|
const { events } = require('../../providers/EventProvider').useEvents();
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
77
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] EVENT CONTEXT DETECTED!`);
|
|
78
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] events:`, events);
|
|
79
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] This public page is inside EventProvider - THIS IS WRONG!`);
|
|
80
|
+
logger.error('PublicPageContextChecker', `❌ [${label}] SOLUTION: Move public routes outside of authentication providers`);
|
|
65
81
|
} catch (error) {
|
|
66
|
-
|
|
82
|
+
logger.debug('PublicPageContextChecker', `✅ [${label}] No event context detected (GOOD!)`);
|
|
67
83
|
}
|
|
68
84
|
|
|
69
85
|
// Check for PublicPageProvider context
|
|
70
86
|
try {
|
|
71
87
|
const { isPublicPage } = usePublicPageContext();
|
|
72
88
|
if (isPublicPage) {
|
|
73
|
-
|
|
89
|
+
logger.debug('PublicPageContextChecker', `✅ [${label}] Public page context detected (GOOD!)`);
|
|
74
90
|
} else {
|
|
75
|
-
|
|
76
|
-
|
|
91
|
+
logger.warn('PublicPageContextChecker', `⚠️ [${label}] Not in PublicPageProvider context`);
|
|
92
|
+
logger.warn('PublicPageContextChecker', `⚠️ [${label}] SOLUTION: Wrap your public page in <PublicPageProvider>`);
|
|
77
93
|
}
|
|
78
94
|
} catch (error) {
|
|
79
|
-
|
|
80
|
-
|
|
95
|
+
logger.warn('PublicPageContextChecker', `⚠️ [${label}] Not in PublicPageProvider context`);
|
|
96
|
+
logger.warn('PublicPageContextChecker', `⚠️ [${label}] SOLUTION: Wrap your public page in <PublicPageProvider>`);
|
|
81
97
|
}
|
|
82
98
|
|
|
83
|
-
console.groupEnd();
|
|
84
|
-
|
|
85
99
|
// Provide immediate guidance
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
console.log(`2. Make sure public routes are completely separate from authentication providers`);
|
|
93
|
-
console.log(`3. Follow the architecture in: packages/core/docs/public-pages-guide.md`);
|
|
94
|
-
console.log(``);
|
|
95
|
-
console.log(`✅ CORRECT ARCHITECTURE:`);
|
|
96
|
-
console.log(`<BrowserRouter>`);
|
|
97
|
-
console.log(` <Routes>`);
|
|
98
|
-
console.log(` <Route path="/events/*" element={<PublicPageApp />} />`);
|
|
99
|
-
console.log(` <Route path="/*" element={<AuthenticatedApp />} />`);
|
|
100
|
-
console.log(` </Routes>`);
|
|
101
|
-
console.log(`</BrowserRouter>`);
|
|
102
|
-
console.groupEnd();
|
|
100
|
+
logger.debug('PublicPageContextChecker', `📖 [${label}] IMMEDIATE ACTION REQUIRED`);
|
|
101
|
+
logger.debug('PublicPageContextChecker', `If you see any ❌ errors above, your public page is inside authentication context.`);
|
|
102
|
+
logger.debug('PublicPageContextChecker', `This will cause infinite loading loops and authentication errors.`);
|
|
103
|
+
logger.debug('PublicPageContextChecker', `🔧 SOLUTION: Check your main App.tsx file`);
|
|
104
|
+
logger.debug('PublicPageContextChecker', `Make sure public routes are completely separate from authentication providers`);
|
|
105
|
+
logger.debug('PublicPageContextChecker', `Follow the architecture in: packages/core/docs/public-pages-guide.md`);
|
|
103
106
|
|
|
104
107
|
}, [enabled, label]);
|
|
105
108
|
|
|
106
|
-
if (!enabled) return null;
|
|
107
|
-
|
|
108
109
|
return (
|
|
109
110
|
<div style={{
|
|
110
111
|
position: 'fixed',
|
|
@@ -55,7 +55,7 @@ import type { Event } from '../../types/unified';
|
|
|
55
55
|
import { FileDisplay } from '../FileDisplay/FileDisplay';
|
|
56
56
|
import { FileCategory } from '../../types/file-reference';
|
|
57
57
|
import { useAppConfig } from '../../hooks/useAppConfig';
|
|
58
|
-
import { cn } from '../../utils/cn';
|
|
58
|
+
import { cn } from '../../utils/core/cn';
|
|
59
59
|
|
|
60
60
|
export interface PublicPageHeaderProps {
|
|
61
61
|
/** The event data for this public page */
|
|
@@ -145,20 +145,6 @@ export function PublicPageHeader({
|
|
|
145
145
|
<>
|
|
146
146
|
{customEventLogo || (
|
|
147
147
|
<>
|
|
148
|
-
{/* Log organisation_id derivation chain for debugging */}
|
|
149
|
-
{(() => {
|
|
150
|
-
console.log('[PublicPageHeader] Organisation ID Derivation Chain:', {
|
|
151
|
-
eventCode: eventCode,
|
|
152
|
-
eventId: event.event_id,
|
|
153
|
-
eventName: event.event_name,
|
|
154
|
-
organisationId: event.organisation_id,
|
|
155
|
-
organisationIdType: typeof event.organisation_id,
|
|
156
|
-
organisationIdValid: !!event.organisation_id && event.organisation_id !== '',
|
|
157
|
-
derivation: 'URL → eventCode → usePublicEvent → event.organisation_id → FileDisplay',
|
|
158
|
-
note: 'Organisation ID is derived from event data fetched using event code from URL'
|
|
159
|
-
});
|
|
160
|
-
return null;
|
|
161
|
-
})()}
|
|
162
148
|
<FileDisplay
|
|
163
149
|
table_name="event"
|
|
164
150
|
record_id={event.event_id}
|
|
@@ -38,6 +38,7 @@ import React, { createContext, useContext, ReactNode, useMemo } from 'react';
|
|
|
38
38
|
import { createClient } from '@supabase/supabase-js';
|
|
39
39
|
import type { Database } from '../../types/database';
|
|
40
40
|
import { PublicErrorBoundary } from './PublicErrorBoundary';
|
|
41
|
+
import { logger } from '../../utils/core/logger';
|
|
41
42
|
|
|
42
43
|
interface PublicPageContextType {
|
|
43
44
|
isPublicPage: true;
|
|
@@ -93,11 +94,11 @@ export function PublicPageProvider({ children, appName }: PublicPageProviderProp
|
|
|
93
94
|
// Create Supabase client if environment variables are available
|
|
94
95
|
const supabase = useMemo(() => {
|
|
95
96
|
if (!supabaseUrl || !supabaseKey) {
|
|
96
|
-
|
|
97
|
+
logger.warn('PublicPageProvider', 'Missing Supabase environment variables. Please ensure VITE_SUPABASE_URL and VITE_SUPABASE_ANON_KEY are set in your environment.');
|
|
97
98
|
return null;
|
|
98
99
|
}
|
|
99
100
|
const client = createClient<Database>(supabaseUrl, supabaseKey);
|
|
100
|
-
|
|
101
|
+
logger.info('PublicPageProvider', 'Supabase client created successfully for public pages');
|
|
101
102
|
return client;
|
|
102
103
|
}, [supabaseUrl, supabaseKey]);
|
|
103
104
|
|
|
@@ -20,6 +20,8 @@ describe('PublicPageContextChecker', () => {
|
|
|
20
20
|
const consoleErrorSpy = vi.spyOn(console, 'error');
|
|
21
21
|
|
|
22
22
|
beforeEach(() => {
|
|
23
|
+
// Component now automatically detects test mode via process.env.NODE_ENV === 'test'
|
|
24
|
+
// No need to manually set environment variables
|
|
23
25
|
vi.clearAllMocks();
|
|
24
26
|
consoleGroupSpy.mockImplementation(() => {});
|
|
25
27
|
consoleGroupEndSpy.mockImplementation(() => {});
|
|
@@ -12,7 +12,7 @@ import { PublicPageFooter } from '../PublicPageFooter';
|
|
|
12
12
|
import type { Event } from '../../../types/unified';
|
|
13
13
|
|
|
14
14
|
// Mock the cn utility
|
|
15
|
-
vi.mock('../../../utils/cn', () => ({
|
|
15
|
+
vi.mock('../../../utils/core/cn', () => ({
|
|
16
16
|
cn: vi.fn((...classes) => classes.filter(Boolean).join(' '))
|
|
17
17
|
}));
|
|
18
18
|
|
|
@@ -21,8 +21,6 @@ export { PublicPageLayout, usePublicPageContext } from './PublicPageLayout';
|
|
|
21
21
|
export { PublicPageHeader } from './PublicPageHeader';
|
|
22
22
|
export { PublicPageProvider, usePublicPageContext as usePublicPageProviderContext, useIsPublicPage } from './PublicPageProvider';
|
|
23
23
|
export { PublicPageFooter } from './PublicPageFooter';
|
|
24
|
-
export { PublicPageDebugger } from './PublicPageDebugger';
|
|
25
|
-
export { PublicPageDiagnostic } from './PublicPageDiagnostic';
|
|
26
24
|
export { PublicPageContextChecker } from './PublicPageContextChecker';
|
|
27
25
|
|
|
28
26
|
|
|
@@ -40,6 +38,10 @@ export {
|
|
|
40
38
|
PublicLoadingSkeleton
|
|
41
39
|
} from './PublicLoadingSpinner';
|
|
42
40
|
|
|
41
|
+
// === EVENT LOGO COMPONENT ===
|
|
42
|
+
export { EventLogo, EventLogoCompact, EventLogoLarge } from './EventLogo';
|
|
43
|
+
export type { EventLogoProps } from './EventLogo';
|
|
44
|
+
|
|
43
45
|
// === TYPES ===
|
|
44
46
|
export type { PublicPageLayoutProps } from './PublicPageLayout';
|
|
45
47
|
export type { PublicPageHeaderProps } from './PublicPageHeader';
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
import * as React from "react";
|
|
16
16
|
import { Search, X, ChevronDown, Check } from "lucide-react";
|
|
17
17
|
import { Button, type ButtonProps } from "../Button/Button";
|
|
18
|
-
import { cn } from "../../utils/cn";
|
|
18
|
+
import { cn } from "../../utils/core/cn";
|
|
19
19
|
import {
|
|
20
20
|
useSelectState,
|
|
21
21
|
useSelectEvents,
|
|
@@ -33,11 +33,13 @@ export interface SelectContextValue extends SelectState {
|
|
|
33
33
|
actions: SelectActions;
|
|
34
34
|
registerItem?: (value: string, text: string) => void;
|
|
35
35
|
unregisterItem?: (value: string) => void;
|
|
36
|
+
direction?: 'up' | 'down';
|
|
36
37
|
}
|
|
37
38
|
|
|
38
39
|
export interface SelectProps extends Omit<React.HTMLAttributes<HTMLFormElement>, 'onChange' | 'onKeyDown' | 'onFocus' | 'onBlur'> {
|
|
39
40
|
children: React.ReactNode;
|
|
40
41
|
className?: string;
|
|
42
|
+
direction?: 'up' | 'down';
|
|
41
43
|
// State props are in UseSelectStateProps (via & intersection)
|
|
42
44
|
}
|
|
43
45
|
|
|
@@ -168,6 +170,7 @@ export const Select = React.forwardRef<HTMLFormElement, SelectProps & UseSelectS
|
|
|
168
170
|
({
|
|
169
171
|
children,
|
|
170
172
|
className,
|
|
173
|
+
direction = 'down',
|
|
171
174
|
...selectProps
|
|
172
175
|
}, ref) => {
|
|
173
176
|
const internalRef = React.useRef<HTMLFormElement>(null);
|
|
@@ -317,7 +320,8 @@ export const Select = React.forwardRef<HTMLFormElement, SelectProps & UseSelectS
|
|
|
317
320
|
actions,
|
|
318
321
|
registerItem,
|
|
319
322
|
unregisterItem,
|
|
320
|
-
|
|
323
|
+
direction,
|
|
324
|
+
}), [state, actions, registerItem, unregisterItem, direction]);
|
|
321
325
|
|
|
322
326
|
return (
|
|
323
327
|
<form
|
|
@@ -341,7 +345,8 @@ Select.displayName = "Select";
|
|
|
341
345
|
|
|
342
346
|
export const SelectTrigger = React.forwardRef<HTMLButtonElement, SelectTriggerProps>(
|
|
343
347
|
({ children, className, variant = "outline", size = "default", asChild = false, ...props }, ref) => {
|
|
344
|
-
const { open, disabled, value, actions } = useSelectContext();
|
|
348
|
+
const { open, disabled, value, actions, direction = 'down' } = useSelectContext();
|
|
349
|
+
const opensUpward = direction === 'up';
|
|
345
350
|
|
|
346
351
|
const handleClick = () => {
|
|
347
352
|
actions.setOpen(!open);
|
|
@@ -377,7 +382,8 @@ export const SelectTrigger = React.forwardRef<HTMLButtonElement, SelectTriggerPr
|
|
|
377
382
|
className: cn(
|
|
378
383
|
"!justify-between relative w-full",
|
|
379
384
|
"[&_svg]:pointer-events-none",
|
|
380
|
-
open && "!rounded-b-none !border-b-0",
|
|
385
|
+
open && !opensUpward && "!rounded-b-none !border-b-0",
|
|
386
|
+
open && opensUpward && "!rounded-t-none !border-t-0",
|
|
381
387
|
className
|
|
382
388
|
),
|
|
383
389
|
style: {
|
|
@@ -438,7 +444,8 @@ export const SelectTrigger = React.forwardRef<HTMLButtonElement, SelectTriggerPr
|
|
|
438
444
|
className={cn(
|
|
439
445
|
"!justify-between relative w-full",
|
|
440
446
|
"[&_svg]:pointer-events-none",
|
|
441
|
-
open && "!rounded-b-none !border-b-0",
|
|
447
|
+
open && !opensUpward && "!rounded-b-none !border-b-0",
|
|
448
|
+
open && opensUpward && "!rounded-t-none !border-t-0",
|
|
442
449
|
className
|
|
443
450
|
)}
|
|
444
451
|
style={{
|
|
@@ -493,10 +500,10 @@ export const SelectContent = React.forwardRef<HTMLUListElement, SelectContentPro
|
|
|
493
500
|
className,
|
|
494
501
|
searchable = false,
|
|
495
502
|
searchPlaceholder = "Search...",
|
|
496
|
-
maxHeight = "20rem",
|
|
503
|
+
maxHeight = "max(20rem, 50vh)",
|
|
497
504
|
style
|
|
498
505
|
}, ref) => {
|
|
499
|
-
const { open, actions } = useSelectContext();
|
|
506
|
+
const { open, actions, direction = 'down' } = useSelectContext();
|
|
500
507
|
const { searchTerm, setSearchTerm, filteredChildren, searchInputRef } = useSelectSearch({
|
|
501
508
|
children,
|
|
502
509
|
searchable,
|
|
@@ -525,16 +532,21 @@ export const SelectContent = React.forwardRef<HTMLUListElement, SelectContentPro
|
|
|
525
532
|
);
|
|
526
533
|
}
|
|
527
534
|
|
|
535
|
+
const opensUpward = direction === 'up';
|
|
536
|
+
|
|
528
537
|
return (
|
|
529
538
|
<ul
|
|
530
539
|
ref={ref}
|
|
531
540
|
className={cn(
|
|
532
|
-
"absolute z-[99999] w-full overflow-y-auto
|
|
541
|
+
"absolute z-[99999] w-full overflow-y-auto border border-main-300 bg-main-50 shadow-lg",
|
|
533
542
|
"list-none p-0 m-0",
|
|
543
|
+
opensUpward
|
|
544
|
+
? "rounded-t-md border-b-0"
|
|
545
|
+
: "rounded-b-md border-t-0",
|
|
534
546
|
className
|
|
535
547
|
)}
|
|
536
548
|
style={{
|
|
537
|
-
top: '100%',
|
|
549
|
+
[opensUpward ? 'bottom' : 'top']: '100%',
|
|
538
550
|
left: 0,
|
|
539
551
|
right: 0,
|
|
540
552
|
maxHeight,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @file SessionRestorationLoader Component
|
|
3
3
|
* @package @jmruthers/pace-core
|
|
4
|
-
* @module Components
|
|
4
|
+
* @module Components/SessionRestorationLoader
|
|
5
5
|
* @since 0.1.0
|
|
6
6
|
*
|
|
7
7
|
* Displays a consistent loading state while the authentication service
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
import React from 'react';
|
|
12
|
-
import { LoadingSpinner } from '
|
|
12
|
+
import { LoadingSpinner } from '../LoadingSpinner/LoadingSpinner';
|
|
13
13
|
|
|
14
14
|
export interface SessionRestorationLoaderProps {
|
|
15
15
|
/** Customise the status message displayed under the spinner */
|
|
@@ -46,3 +46,4 @@ export const SessionRestorationLoader: React.FC<SessionRestorationLoaderProps> =
|
|
|
46
46
|
</div>
|
|
47
47
|
);
|
|
48
48
|
};
|
|
49
|
+
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
import * as React from "react"
|
|
89
89
|
import * as ToastPrimitives from "@radix-ui/react-toast"
|
|
90
90
|
import { X } from "lucide-react"
|
|
91
|
-
import { cn } from "../../utils/cn"
|
|
91
|
+
import { cn } from "../../utils/core/cn"
|
|
92
92
|
import { useToast } from "../../hooks/useToast"
|
|
93
93
|
|
|
94
94
|
const ToastProvider = ToastPrimitives.Provider
|
package/src/components/index.ts
CHANGED
|
@@ -49,6 +49,9 @@ export type { LabelProps } from './Label';
|
|
|
49
49
|
export { Alert, AlertTitle, AlertDescription } from './Alert';
|
|
50
50
|
export { Avatar, AvatarImage, AvatarFallback } from './Avatar';
|
|
51
51
|
|
|
52
|
+
export { Badge } from './Badge';
|
|
53
|
+
export type { BadgeProps, BadgeVariant } from './Badge';
|
|
54
|
+
|
|
52
55
|
export { Checkbox } from './Checkbox';
|
|
53
56
|
export { Switch } from './Switch';
|
|
54
57
|
export type { SwitchProps } from './Switch';
|
|
@@ -151,17 +154,11 @@ export type { DataRecord } from './DataTable/types';
|
|
|
151
154
|
|
|
152
155
|
export {
|
|
153
156
|
Form,
|
|
154
|
-
FormField
|
|
155
|
-
FormErrorSummary,
|
|
156
|
-
FormLiveRegion,
|
|
157
|
-
FormFieldset
|
|
157
|
+
FormField
|
|
158
158
|
} from './Form';
|
|
159
159
|
export type {
|
|
160
160
|
FormProps,
|
|
161
|
-
FormFieldProps
|
|
162
|
-
FormErrorSummaryProps,
|
|
163
|
-
FormLiveRegionProps,
|
|
164
|
-
FormFieldsetProps
|
|
161
|
+
FormFieldProps
|
|
165
162
|
} from './Form';
|
|
166
163
|
|
|
167
164
|
// LoginForm - ensure it's exported
|
|
@@ -212,6 +209,7 @@ export { ErrorBoundary } from './ErrorBoundary';
|
|
|
212
209
|
export type { ErrorBoundaryProps, ErrorBoundaryState } from './ErrorBoundary';
|
|
213
210
|
export { LoadingSpinner } from './LoadingSpinner';
|
|
214
211
|
export { SessionRestorationLoader } from './SessionRestorationLoader';
|
|
212
|
+
export type { SessionRestorationLoaderProps } from './SessionRestorationLoader';
|
|
215
213
|
|
|
216
214
|
// ============================================================================
|
|
217
215
|
// EVENT MANAGEMENT
|
|
@@ -223,8 +221,7 @@ export { EventSelector } from './EventSelector';
|
|
|
223
221
|
// AUTHENTICATION FORMS
|
|
224
222
|
// ============================================================================
|
|
225
223
|
|
|
226
|
-
// Password Component exports
|
|
227
|
-
export { PasswordResetForm } from './PasswordReset';
|
|
224
|
+
// Password Component exports (PasswordResetForm removed - unused)
|
|
228
225
|
|
|
229
226
|
// ============================================================================
|
|
230
227
|
// STORAGE COMPONENTS
|