@jmruthers/pace-core 0.5.75 → 0.5.77
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/CHANGELOG.md +8 -0
- package/dist/{RBACService-C4udt_Zp.d.ts → AuthService-SBHZQtCH.d.ts} +5 -118
- package/dist/{DataTable-ntgmhO2W.d.ts → DataTable-BE0OXZKQ.d.ts} +9 -2
- package/dist/DataTable-QCNCV6IK.js +157 -0
- package/dist/{PublicLoadingSpinner-BKNBT6b6.d.ts → PublicLoadingSpinner-CnUaz0vG.d.ts} +33 -19
- package/dist/{UnifiedAuthProvider-Bj6YCf7c.d.ts → UnifiedAuthProvider-B391Aqum.d.ts} +42 -45
- package/dist/{UnifiedAuthProvider-3NKDOSOK.js → UnifiedAuthProvider-Z2FWNW7O.js} +4 -5
- package/dist/{api-DDMUKIUD.js → api-KG4A2X7P.js} +9 -3
- package/dist/{audit-6TOCAMKO.js → audit-65VNHEV2.js} +2 -2
- package/dist/{chunk-2DFZ432F.js → chunk-7PX43UYN.js} +197 -629
- package/dist/chunk-7PX43UYN.js.map +1 -0
- package/dist/{chunk-DAXLNIDY.js → chunk-C4RQ3GQA.js} +108 -32
- package/dist/chunk-C4RQ3GQA.js.map +1 -0
- package/dist/{chunk-LW7MMEAQ.js → chunk-CRKP3HXI.js} +2 -2
- package/dist/{chunk-XLZ7U46Z.js → chunk-CVMVPYAL.js} +9 -60
- package/dist/chunk-CVMVPYAL.js.map +1 -0
- package/dist/{chunk-CY3AHGO4.js → chunk-DDPG7FCX.js} +3395 -3254
- package/dist/chunk-DDPG7FCX.js.map +1 -0
- package/dist/{chunk-URUTVZ7N.js → chunk-DVHZ5L55.js} +2 -2
- package/dist/{chunk-5BSLGBYI.js → chunk-JCQZ6LA7.js} +2 -8
- package/dist/{chunk-5BSLGBYI.js.map → chunk-JCQZ6LA7.js.map} +1 -1
- package/dist/{chunk-WN6XJWOS.js → chunk-JDQ7T3QB.js} +256 -743
- package/dist/chunk-JDQ7T3QB.js.map +1 -0
- package/dist/{chunk-ZTT2AXMX.js → chunk-LMYTEMUH.js} +153 -132
- package/dist/chunk-LMYTEMUH.js.map +1 -0
- package/dist/{chunk-33PHABLB.js → chunk-NKT2DLZI.js} +13 -130
- package/dist/chunk-NKT2DLZI.js.map +1 -0
- package/dist/chunk-PUKTJMRT.js +732 -0
- package/dist/chunk-PUKTJMRT.js.map +1 -0
- package/dist/{chunk-B2WTCLCV.js → chunk-Q7APDV6H.js} +18 -8
- package/dist/chunk-Q7APDV6H.js.map +1 -0
- package/dist/{chunk-FGMFQSHX.js → chunk-S63MFSY6.js} +500 -551
- package/dist/chunk-S63MFSY6.js.map +1 -0
- package/dist/{chunk-NTNILOBC.js → chunk-TLD5BEU6.js} +4 -4
- package/dist/chunk-WUXCWRL6.js +20 -0
- package/dist/chunk-WUXCWRL6.js.map +1 -0
- package/dist/{chunk-YNUBMSMV.js → chunk-YCKPEMJA.js} +186 -263
- package/dist/chunk-YCKPEMJA.js.map +1 -0
- package/dist/{chunk-A4FUBC7B.js → chunk-Z3T6RK3K.js} +2 -4
- package/dist/{chunk-A4FUBC7B.js.map → chunk-Z3T6RK3K.js.map} +1 -1
- package/dist/components.d.ts +6 -6
- package/dist/components.js +17 -20
- package/dist/components.js.map +1 -1
- package/dist/{database-C3Szpi5J.d.ts → database-BXAfr2Y_.d.ts} +18 -0
- package/dist/hooks.d.ts +21 -44
- package/dist/hooks.js +12 -13
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +19 -27
- package/dist/index.js +27 -33
- package/dist/index.js.map +1 -1
- package/dist/{organisation-BtshODVF.d.ts → organisation-D6qRDtbF.d.ts} +1 -1
- package/dist/providers.d.ts +7 -21
- package/dist/providers.js +3 -10
- package/dist/rbac/index.d.ts +118 -215
- package/dist/rbac/index.js +18 -18
- package/dist/{types-CGX9Vyf5.d.ts → types-BDg1mAGG.d.ts} +36 -6
- package/dist/types.d.ts +3 -3
- package/dist/types.js +61 -18
- package/dist/types.js.map +1 -1
- package/dist/{unified-CM7T0aTK.d.ts → unified-DQ4VcT7H.d.ts} +1 -1
- package/dist/{usePublicRouteParams-B-CumWRc.d.ts → usePublicRouteParams-BlgwXweB.d.ts} +3 -3
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +52 -9
- package/dist/utils.js.map +1 -1
- package/docs/CONTENT_AUDIT_REPORT.md +253 -0
- package/docs/DOCUMENTATION_AUDIT.md +172 -0
- package/docs/README.md +142 -147
- package/docs/STYLE_GUIDE.md +37 -0
- package/docs/api/classes/ColumnFactory.md +17 -17
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +4 -4
- package/docs/api/classes/MissingUserContextError.md +4 -4
- package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
- package/docs/api/classes/PermissionDeniedError.md +5 -5
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +8 -8
- package/docs/api/classes/RBACCache.md +35 -5
- package/docs/api/classes/RBACEngine.md +49 -20
- package/docs/api/classes/RBACError.md +4 -4
- package/docs/api/classes/RBACNotInitializedError.md +4 -4
- 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/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 +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +11 -0
- package/docs/api/interfaces/DataTableAction.md +65 -29
- package/docs/api/interfaces/DataTableColumn.md +36 -23
- package/docs/api/interfaces/DataTableProps.md +80 -38
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- 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/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 +11 -11
- package/docs/api/interfaces/NavigationContextType.md +9 -9
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- 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 +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +16 -3
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
- 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/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +2 -2
- package/docs/api/interfaces/RouteConfig.md +2 -2
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- 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 +94 -521
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +16 -16
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +47 -0
- package/docs/api/interfaces/UseResolvedScopeReturn.md +47 -0
- 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 +303 -275
- package/docs/api-reference/components.md +193 -0
- package/docs/api-reference/hooks.md +265 -0
- package/docs/api-reference/providers.md +32 -7
- package/docs/api-reference/types.md +6 -0
- package/docs/api-reference/utilities.md +207 -0
- package/docs/architecture/README.md +6 -0
- package/docs/{database-schema-requirements.md → architecture/database-schema-requirements.md} +6 -0
- package/docs/architecture/rbac-security-architecture.md +258 -0
- package/docs/architecture/services.md +9 -1
- package/docs/best-practices/README.md +26 -0
- package/docs/best-practices/accessibility.md +572 -0
- package/docs/{common-patterns.md → best-practices/common-patterns.md} +6 -0
- package/docs/best-practices/deployment.md +6 -0
- package/docs/best-practices/performance.md +475 -2
- package/docs/best-practices/security.md +6 -0
- package/docs/best-practices/testing.md +6 -0
- package/docs/core-concepts/authentication.md +21 -7
- package/docs/core-concepts/events.md +6 -0
- package/docs/core-concepts/organisations.md +6 -0
- package/docs/core-concepts/permissions.md +6 -0
- package/docs/core-concepts/rbac-system.md +6 -0
- package/docs/documentation-index.md +121 -182
- package/docs/{consuming-app-vite-config.md → getting-started/consuming-app-vite-config.md} +6 -0
- package/docs/getting-started/documentation-index.md +40 -0
- package/docs/getting-started/examples/README.md +878 -35
- package/docs/{faq.md → getting-started/faq.md} +7 -1
- package/docs/getting-started/installation-guide.md +6 -0
- package/docs/{quick-reference.md → getting-started/quick-reference.md} +6 -0
- package/docs/implementation-guides/app-layout.md +6 -0
- package/docs/implementation-guides/authentication.md +1021 -0
- package/docs/implementation-guides/component-styling.md +416 -0
- package/docs/implementation-guides/data-tables.md +1264 -2076
- package/docs/implementation-guides/dynamic-colors.md +6 -0
- package/docs/implementation-guides/event-theming-summary.md +6 -0
- package/docs/{file-reference-system.md → implementation-guides/file-reference-system.md} +6 -0
- package/docs/implementation-guides/file-upload-storage.md +6 -0
- package/docs/implementation-guides/forms.md +6 -0
- package/docs/implementation-guides/inactivity-tracking.md +6 -0
- package/docs/implementation-guides/navigation.md +6 -0
- package/docs/implementation-guides/organisation-security.md +6 -0
- package/docs/implementation-guides/permission-enforcement.md +6 -0
- package/docs/implementation-guides/public-pages-advanced.md +6 -0
- package/docs/implementation-guides/public-pages.md +6 -0
- package/docs/migration/MIGRATION_GUIDE.md +827 -351
- package/docs/migration/README.md +7 -1
- package/docs/migration/organisation-context-timing-fix.md +6 -0
- package/docs/migration/rbac-migration.md +44 -1
- package/docs/migration/service-architecture.md +6 -0
- package/docs/migration/v0.4.15-tailwind-scanning.md +6 -0
- package/docs/migration/v0.4.16-css-first-approach.md +6 -0
- package/docs/migration/v0.4.17-source-path-fix.md +6 -0
- package/docs/rbac/README-rbac-rls-integration.md +6 -0
- package/docs/rbac/README.md +6 -0
- package/docs/rbac/advanced-patterns.md +6 -0
- package/docs/rbac/api-reference.md +7 -1
- package/docs/rbac/breaking-changes-v3.md +222 -0
- package/docs/rbac/examples/rbac-rls-integration-example.md +6 -0
- package/docs/rbac/examples.md +6 -0
- package/docs/rbac/getting-started.md +6 -0
- package/docs/rbac/migration-guide.md +260 -0
- package/docs/rbac/quick-start.md +6 -0
- package/docs/rbac/rbac-rls-integration.md +6 -0
- package/docs/rbac/super-admin-guide.md +6 -0
- package/docs/rbac/troubleshooting.md +6 -0
- package/docs/security/README.md +6 -0
- package/docs/security/checklist.md +6 -0
- package/docs/styles/README.md +7 -1
- package/docs/{usage.md → styles/usage.md} +6 -0
- package/docs/testing/README.md +6 -0
- package/docs/{visual-testing.md → testing/visual-testing.md} +6 -0
- package/docs/troubleshooting/README.md +387 -5
- package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +6 -0
- package/docs/troubleshooting/common-issues.md +6 -0
- package/docs/troubleshooting/database-view-compatibility.md +6 -0
- package/docs/troubleshooting/organisation-context-setup.md +6 -0
- package/docs/troubleshooting/react-hooks-issue-analysis.md +6 -0
- package/docs/troubleshooting/styling-issues.md +6 -0
- package/docs/troubleshooting/tailwind-content-scanning.md +6 -0
- package/package.json +1 -1
- package/src/__tests__/TEST_GUIDE_CURSOR.md +290 -0
- package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -1
- package/src/__tests__/helpers/supabaseMock.ts +48 -2
- package/src/__tests__/helpers/test-providers.tsx +3 -53
- package/src/components/DataTable/DataTable.test.tsx +319 -0
- package/src/components/DataTable/DataTable.tsx +32 -11
- package/src/components/DataTable/__tests__/{DataTable.comprehensive.test.tsx → DataTable.comprehensive.test.tsx.skip} +6 -4
- package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +17 -6
- package/src/components/DataTable/__tests__/{DataTable.test.tsx → DataTable.test.tsx.skip} +6 -4
- package/src/components/DataTable/__tests__/DataTableCore.test.tsx +96 -10
- package/src/components/DataTable/__tests__/a11y.basic.test.tsx +601 -0
- package/src/components/DataTable/__tests__/keyboard.test.tsx +615 -0
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +639 -0
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx.skip +330 -0
- package/src/components/DataTable/components/AccessDeniedPage.tsx +2 -2
- package/src/components/DataTable/components/ActionButtons.tsx +88 -104
- package/src/components/DataTable/components/DataTableCore.tsx +442 -665
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +4 -2
- package/src/components/DataTable/components/DataTableModals.tsx +22 -1
- package/src/components/DataTable/components/EditableRow.tsx +69 -84
- package/src/components/DataTable/components/EmptyState.tsx +5 -1
- package/src/components/DataTable/components/ImportModal.tsx +65 -36
- package/src/components/DataTable/components/PaginationControls.tsx +40 -100
- package/src/components/DataTable/components/UnifiedTableBody.tsx +222 -278
- package/src/components/DataTable/components/index.ts +1 -2
- package/src/components/DataTable/context/DataTableContext.tsx +1 -1
- package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +208 -275
- package/src/components/DataTable/core/ColumnFactory.ts +5 -0
- package/src/components/DataTable/core/index.ts +1 -8
- package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +12 -10
- package/src/components/DataTable/examples/HierarchicalExample.tsx +1 -1
- package/src/components/DataTable/examples/InitialPageSizeExample.tsx +1 -0
- package/src/components/DataTable/examples/PerformanceExample.tsx +1 -0
- package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +521 -0
- package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +570 -0
- package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +167 -0
- package/src/components/DataTable/hooks/__tests__/useHierarchicalState.test.ts +214 -0
- package/src/components/DataTable/hooks/__tests__/useTableColumns.test.ts +224 -0
- package/src/components/DataTable/hooks/index.ts +13 -0
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +32 -15
- package/src/components/DataTable/hooks/useColumnReordering.ts +1 -0
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +102 -0
- package/src/components/DataTable/hooks/useDataTableConfiguration.ts +89 -0
- package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +117 -0
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +193 -0
- package/src/components/DataTable/hooks/useDataTableState.ts +51 -17
- package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +33 -0
- package/src/components/DataTable/hooks/useHierarchicalState.ts +41 -9
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +447 -0
- package/src/components/DataTable/hooks/useServerSideDataEffect.ts +94 -0
- package/src/components/DataTable/hooks/useTableColumns.ts +156 -0
- package/src/components/DataTable/hooks/useTableHandlers.ts +174 -0
- package/src/components/DataTable/index.ts +13 -12
- package/src/components/DataTable/types.ts +129 -9
- package/src/components/DataTable/utils/__tests__/COVERAGE_NOTE.md +89 -0
- package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +162 -28
- package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +573 -0
- package/src/components/DataTable/utils/__tests__/hierarchicalSorting.test.ts +247 -0
- package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +8 -6
- package/src/components/DataTable/utils/__tests__/performanceUtils.test.ts +466 -0
- package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +251 -0
- package/src/components/DataTable/utils/a11yUtils.ts +244 -0
- package/src/components/DataTable/utils/debugTools.ts +47 -21
- package/src/components/DataTable/utils/errorHandling.ts +52 -460
- package/src/components/DataTable/utils/exportUtils.ts +157 -28
- package/src/components/DataTable/utils/flexibleImport.ts +202 -32
- package/src/components/DataTable/utils/hierarchicalSorting.ts +50 -3
- package/src/components/DataTable/utils/hierarchicalUtils.ts +167 -34
- package/src/components/DataTable/utils/index.ts +7 -0
- package/src/components/DataTable/utils/paginationUtils.ts +350 -0
- package/src/components/DataTable/utils/rowUtils.ts +69 -0
- package/src/components/EventSelector/EventSelector.test.tsx +672 -0
- package/src/components/Label/__tests__/Label.test.tsx +434 -0
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -24
- package/src/components/NavigationMenu/NavigationMenu.tsx +19 -8
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +1 -23
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +56 -6
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +137 -13
- package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +190 -0
- package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +185 -0
- package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +1 -1
- package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +313 -0
- package/src/components/Select/Select.test.tsx +143 -120
- package/src/components/Select/Select.tsx +48 -212
- package/src/components/Select/hooks.ts +36 -1
- package/src/components/Select/index.ts +2 -1
- package/src/components/examples/PermissionExample.tsx +173 -0
- package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
- package/src/examples/PublicEventPage.tsx +274 -0
- package/src/examples/PublicPageApp.tsx +308 -0
- package/src/examples/PublicPageUsageExample.tsx +216 -0
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +12 -1
- package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +129 -17
- package/src/hooks/__tests__/useRBAC.unit.test.ts +151 -846
- package/src/hooks/useOrganisationPermissions.test.ts +42 -18
- package/src/hooks/useOrganisationPermissions.ts +12 -6
- package/src/hooks/useOrganisationSecurity.test.ts +138 -85
- package/src/hooks/useOrganisationSecurity.ts +41 -10
- package/src/hooks/useSecureDataAccess.test.ts +32 -29
- package/src/index.ts +0 -1
- package/src/providers/AuthProvider.simplified.tsx +880 -0
- package/src/providers/UnifiedAuthProvider.test.simple.tsx +8 -8
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +341 -0
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +29 -19
- package/src/providers/index.ts +0 -1
- package/src/providers/services/EventServiceProvider.tsx +19 -15
- package/src/providers/services/InactivityServiceProvider.tsx +19 -15
- package/src/providers/services/OrganisationServiceProvider.tsx +19 -15
- package/src/providers/services/UnifiedAuthProvider.tsx +156 -127
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +1 -1
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -3
- package/src/rbac/README.md +1 -1
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +25 -27
- package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +313 -0
- package/src/rbac/__tests__/engine.comprehensive.test.ts +114 -348
- package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +28 -110
- package/src/rbac/__tests__/rbac-engine-simplified.test.ts +33 -85
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +2 -2
- package/src/rbac/adapters.tsx +26 -69
- package/src/rbac/api.test.ts +90 -27
- package/src/rbac/api.ts +61 -10
- package/src/rbac/audit.test.ts +33 -38
- package/src/rbac/audit.ts +21 -6
- package/src/rbac/cache.ts +33 -1
- package/src/rbac/components/NavigationGuard.tsx +11 -11
- package/src/rbac/components/NavigationProvider.test.tsx +11 -5
- package/src/rbac/components/NavigationProvider.tsx +37 -13
- package/src/rbac/components/PagePermissionGuard.tsx +111 -50
- package/src/rbac/components/PagePermissionProvider.tsx +5 -5
- package/src/rbac/components/PermissionEnforcer.tsx +11 -11
- package/src/rbac/components/RoleBasedRouter.tsx +5 -5
- package/src/rbac/components/SecureDataProvider.tsx +5 -5
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +8 -8
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +14 -14
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +12 -12
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +6 -6
- package/src/rbac/engine.test.simple.ts +19 -13
- package/src/rbac/engine.test.ts +1 -0
- package/src/rbac/engine.ts +330 -766
- package/src/rbac/errors.ts +156 -0
- package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +437 -0
- package/src/rbac/hooks/index.ts +2 -0
- package/src/rbac/hooks/usePermissions.ts +32 -10
- package/src/rbac/hooks/useRBAC.test.ts +126 -512
- package/src/rbac/hooks/useRBAC.ts +147 -193
- package/src/rbac/hooks/useResolvedScope.ts +244 -0
- package/src/rbac/index.ts +7 -4
- package/src/rbac/security.ts +109 -18
- package/src/rbac/types.ts +12 -1
- package/src/services/AuthService.ts +2 -15
- package/src/services/EventService.ts +26 -46
- package/src/services/OrganisationService.ts +51 -31
- package/src/services/__tests__/AuthService.test.ts +1 -1
- package/src/services/__tests__/EventService.test.ts +1 -1
- package/src/services/__tests__/InactivityService.lifecycle.test.ts +411 -0
- package/src/services/__tests__/OrganisationService.pagination.test.ts +375 -0
- package/src/services/__tests__/OrganisationService.test.ts +1 -1
- package/src/styles/base.css +208 -0
- package/src/styles/semantic.css +24 -0
- package/src/types/__tests__/README.md +114 -0
- package/src/types/__tests__/validation.test.ts +731 -0
- package/src/types/database.generated.ts +7347 -0
- package/src/types/database.ts +20 -0
- package/src/utils/__tests__/file-reference.test.ts +383 -0
- package/src/utils/__tests__/performanceBenchmark.test.ts +175 -0
- package/src/utils/appNameResolver.test.ts +54 -0
- package/src/utils/logger.ts +179 -0
- package/src/utils/organisationContext.ts +11 -4
- package/src/utils/storage/__tests__/helpers.unit.test.ts +6 -2
- package/src/validation/__tests__/csrf.unit.test.ts +63 -0
- package/src/validation/__tests__/passwordSchema.unit.test.ts +105 -0
- package/dist/DataTable-HWZQGASI.js +0 -102
- package/dist/appNameResolver-UURKN7NF.js +0 -22
- package/dist/audit-6TOCAMKO.js.map +0 -1
- package/dist/chunk-2CHATWBF.js +0 -523
- package/dist/chunk-2CHATWBF.js.map +0 -1
- package/dist/chunk-2DFZ432F.js.map +0 -1
- package/dist/chunk-33PHABLB.js.map +0 -1
- package/dist/chunk-B2WTCLCV.js.map +0 -1
- package/dist/chunk-CY3AHGO4.js.map +0 -1
- package/dist/chunk-DAXLNIDY.js.map +0 -1
- package/dist/chunk-FGMFQSHX.js.map +0 -1
- package/dist/chunk-TYHR5X4W.js +0 -33
- package/dist/chunk-TYHR5X4W.js.map +0 -1
- package/dist/chunk-ULBI5JGB.js +0 -109
- package/dist/chunk-ULBI5JGB.js.map +0 -1
- package/dist/chunk-WN6XJWOS.js.map +0 -1
- package/dist/chunk-XLZ7U46Z.js.map +0 -1
- package/dist/chunk-YNUBMSMV.js.map +0 -1
- package/dist/chunk-ZTT2AXMX.js.map +0 -1
- package/dist/eventContext-BBA42P6G.js +0 -14
- package/dist/eventContext-BBA42P6G.js.map +0 -1
- package/docs/DOCUMENTATION_CHECKLIST.md +0 -281
- package/docs/api/interfaces/RBACContextType.md +0 -468
- package/docs/api/interfaces/RBACProviderProps.md +0 -107
- package/docs/breaking-changes.md +0 -179
- package/docs/consuming-app-example.md +0 -290
- package/docs/documentation-style-checklist.md +0 -294
- package/docs/examples/navigation-menu-auth-fix.md +0 -344
- package/docs/getting-started/examples/basic-auth-app.md +0 -520
- package/docs/getting-started/examples/full-featured-app.md +0 -616
- package/docs/getting-started/quick-start.md +0 -426
- package/docs/implementation-guides/datatable-filtering.md +0 -313
- package/docs/implementation-guides/datatable-rbac-usage.md +0 -317
- package/docs/implementation-guides/hierarchical-datatable.md +0 -850
- package/docs/implementation-guides/large-datasets.md +0 -281
- package/docs/implementation-guides/performance.md +0 -403
- package/docs/migration/quick-migration-guide.md +0 -320
- package/docs/migration-guide.md +0 -193
- package/docs/migration-guides/unified-auth-provider-mandatory-timeouts.md +0 -226
- package/docs/performance/README.md +0 -551
- package/docs/style-guide.md +0 -925
- package/docs/troubleshooting/authentication-issues.md +0 -334
- package/docs/troubleshooting/debugging.md +0 -1117
- package/docs/troubleshooting/migration.md +0 -918
- package/src/__tests__/hooks/usePermissions.test.ts +0 -261
- package/src/components/DataTable/components/DataTableBody.tsx +0 -488
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -144
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -515
- package/src/components/DataTable/core/ActionManager.ts +0 -235
- package/src/components/DataTable/core/ColumnManager.ts +0 -215
- package/src/components/DataTable/core/DataManager.ts +0 -188
- package/src/components/DataTable/core/DataTableContext.tsx +0 -181
- package/src/components/DataTable/core/LocalDataAdapter.ts +0 -264
- package/src/components/DataTable/core/PluginRegistry.ts +0 -229
- package/src/components/DataTable/core/StateManager.ts +0 -311
- package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -634
- package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +0 -193
- package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -519
- package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -714
- package/src/components/DataTable/core/interfaces.ts +0 -338
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.rbac.test.tsx +0 -574
- package/src/components/Select/Select.bug-test.tsx +0 -69
- package/src/components/Select/Select.refactored.tsx +0 -497
- package/src/hooks/__tests__/ServiceHooks.test.tsx +0 -613
- package/src/hooks/services/usePermissions.ts +0 -70
- package/src/hooks/services/useRBACService.ts +0 -30
- package/src/hooks/usePermissionCheck.ts +0 -150
- package/src/providers/__tests__/ServiceProviders.test.tsx +0 -477
- package/src/providers/services/RBACServiceProvider.tsx +0 -79
- package/src/rbac/__tests__/integration.authflow.test.tsx +0 -119
- package/src/rbac/__tests__/integration.navigation.test.tsx +0 -69
- package/src/rbac/__tests__/integration.securedata.test.tsx +0 -92
- package/src/rbac/__tests__/integration.smoke.test.tsx +0 -73
- package/src/rbac/providers/RBACProvider.tsx +0 -645
- package/src/rbac/providers/__tests__/RBACProvider.integration.test.tsx +0 -688
- package/src/rbac/providers/__tests__/RBACProvider.test.tsx +0 -1186
- package/src/rbac/providers/index.ts +0 -11
- package/src/services/RBACService.ts +0 -522
- package/src/services/__tests__/RBACService.test.ts +0 -492
- package/src/services/interfaces/IRBACService.ts +0 -62
- package/src/utils/appNameResolver.test 2.ts +0 -494
- /package/dist/{DataTable-HWZQGASI.js.map → DataTable-QCNCV6IK.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-3NKDOSOK.js.map → UnifiedAuthProvider-Z2FWNW7O.js.map} +0 -0
- /package/dist/{api-DDMUKIUD.js.map → api-KG4A2X7P.js.map} +0 -0
- /package/dist/{appNameResolver-UURKN7NF.js.map → audit-65VNHEV2.js.map} +0 -0
- /package/dist/{chunk-LW7MMEAQ.js.map → chunk-CRKP3HXI.js.map} +0 -0
- /package/dist/{chunk-URUTVZ7N.js.map → chunk-DVHZ5L55.js.map} +0 -0
- /package/dist/{chunk-NTNILOBC.js.map → chunk-TLD5BEU6.js.map} +0 -0
- /package/docs/{app.css.example → styles/app.css.example} +0 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Public Page App Example
|
|
3
|
+
* @package @jmruthers/pace-core
|
|
4
|
+
* @module Examples/PublicPages
|
|
5
|
+
* @since 1.0.0
|
|
6
|
+
*
|
|
7
|
+
* A complete example showing how to properly implement public pages
|
|
8
|
+
* that are completely isolated from the authentication context.
|
|
9
|
+
*
|
|
10
|
+
* This example demonstrates the correct architecture for public pages:
|
|
11
|
+
* 1. Separate routing structure outside authentication context
|
|
12
|
+
* 2. PublicPageProvider for environment variables
|
|
13
|
+
* 3. No authentication context initialization
|
|
14
|
+
* 4. Proper error handling and loading states
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```tsx
|
|
18
|
+
* import { PublicPageApp } from '@jmruthers/pace-core/examples';
|
|
19
|
+
*
|
|
20
|
+
* // In your main App.tsx, use this for public routes
|
|
21
|
+
* function App() {
|
|
22
|
+
* return (
|
|
23
|
+
* <BrowserRouter>
|
|
24
|
+
* <Routes>
|
|
25
|
+
* <Route path="/public/*" element={<PublicPageApp />} />
|
|
26
|
+
* <Route path="/*" element={<AuthenticatedApp />} />
|
|
27
|
+
* </Routes>
|
|
28
|
+
* </BrowserRouter>
|
|
29
|
+
* );
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
|
|
34
|
+
import React from 'react';
|
|
35
|
+
import { Routes, Route } from 'react-router-dom';
|
|
36
|
+
import {
|
|
37
|
+
PublicPageProvider,
|
|
38
|
+
PublicPageLayout,
|
|
39
|
+
PublicPageHeader,
|
|
40
|
+
PublicPageFooter,
|
|
41
|
+
EventLogo,
|
|
42
|
+
usePublicEvent,
|
|
43
|
+
usePublicRouteParams,
|
|
44
|
+
PublicLoadingSpinner,
|
|
45
|
+
PublicErrorBoundary
|
|
46
|
+
} from '../index';
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Complete public page application that works independently
|
|
50
|
+
* of the main application's authentication context.
|
|
51
|
+
*
|
|
52
|
+
* This component should be used for all public routes that don't
|
|
53
|
+
* require authentication, such as:
|
|
54
|
+
* - Event pages: /events/:eventCode/recipe-grid-report
|
|
55
|
+
* - Public reports: /reports/:reportId
|
|
56
|
+
* - Public information: /info/:pageId
|
|
57
|
+
*/
|
|
58
|
+
export function PublicPageApp() {
|
|
59
|
+
return (
|
|
60
|
+
<PublicPageProvider>
|
|
61
|
+
<Routes>
|
|
62
|
+
{/* Public event pages */}
|
|
63
|
+
<Route path="/events/:eventCode/recipe-grid-report" element={<PublicRecipeGridReportPage />} />
|
|
64
|
+
<Route path="/events/:eventCode" element={<PublicEventPage />} />
|
|
65
|
+
|
|
66
|
+
{/* Add more public routes as needed */}
|
|
67
|
+
<Route path="/info/:pageId" element={<PublicInfoPage />} />
|
|
68
|
+
<Route path="/reports/:reportId" element={<PublicReportPage />} />
|
|
69
|
+
</Routes>
|
|
70
|
+
</PublicPageProvider>
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Public recipe grid report page
|
|
76
|
+
*
|
|
77
|
+
* This is the specific page mentioned in the bug report.
|
|
78
|
+
* It demonstrates the correct usage pattern for public pages.
|
|
79
|
+
*/
|
|
80
|
+
function PublicRecipeGridReportPage() {
|
|
81
|
+
// Step 1: Extract event code from URL (no auth context triggered)
|
|
82
|
+
const { eventCode } = usePublicRouteParams({ fetchEventData: false });
|
|
83
|
+
|
|
84
|
+
// Step 2: Fetch event data using the event code
|
|
85
|
+
const { event, isLoading, error, refetch } = usePublicEvent(eventCode || '');
|
|
86
|
+
|
|
87
|
+
// Step 3: Handle loading state
|
|
88
|
+
if (isLoading) {
|
|
89
|
+
return (
|
|
90
|
+
<PublicLoadingSpinner
|
|
91
|
+
message="Loading recipe grid report..."
|
|
92
|
+
/>
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Step 4: Handle error state
|
|
97
|
+
if (error) {
|
|
98
|
+
return (
|
|
99
|
+
<div className="min-h-screen bg-white flex items-center justify-center">
|
|
100
|
+
<div className="max-w-md mx-auto text-center px-4">
|
|
101
|
+
<div className="mb-6">
|
|
102
|
+
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4">
|
|
103
|
+
<svg className="h-6 w-6 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
104
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
|
|
105
|
+
</svg>
|
|
106
|
+
</div>
|
|
107
|
+
<h1 className="text-2xl font-bold text-gray-900 mb-2">
|
|
108
|
+
Recipe Grid Report Not Found
|
|
109
|
+
</h1>
|
|
110
|
+
<p className="text-gray-600 mb-6">
|
|
111
|
+
The event code "{eventCode}" is invalid or the recipe grid report is not available for public viewing.
|
|
112
|
+
</p>
|
|
113
|
+
<button
|
|
114
|
+
onClick={refetch}
|
|
115
|
+
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
|
|
116
|
+
>
|
|
117
|
+
Try Again
|
|
118
|
+
</button>
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
// Step 5: Handle missing event
|
|
126
|
+
if (!event) {
|
|
127
|
+
return (
|
|
128
|
+
<div className="min-h-screen bg-white flex items-center justify-center">
|
|
129
|
+
<div className="max-w-md mx-auto text-center px-4">
|
|
130
|
+
<h1 className="text-2xl font-bold text-gray-900 mb-4">
|
|
131
|
+
Recipe Grid Report Not Available
|
|
132
|
+
</h1>
|
|
133
|
+
<p className="text-gray-600 mb-6">
|
|
134
|
+
This recipe grid report is not available for public viewing.
|
|
135
|
+
</p>
|
|
136
|
+
<button
|
|
137
|
+
onClick={refetch}
|
|
138
|
+
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
|
|
139
|
+
>
|
|
140
|
+
Try Again
|
|
141
|
+
</button>
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Step 6: Render the public page with event data
|
|
148
|
+
return (
|
|
149
|
+
<PublicPageLayout eventCode={eventCode || ''} event={event}>
|
|
150
|
+
<PublicPageHeader
|
|
151
|
+
event={event}
|
|
152
|
+
eventCode={eventCode || ''}
|
|
153
|
+
title="Recipe Grid Report"
|
|
154
|
+
description="Public recipe grid report for this event"
|
|
155
|
+
/>
|
|
156
|
+
|
|
157
|
+
<main className="max-w-6xl mx-auto px-4 py-8">
|
|
158
|
+
{/* Recipe Grid Report Content */}
|
|
159
|
+
<div className="mb-12">
|
|
160
|
+
<div className="bg-green-50 border border-green-200 rounded-lg p-6">
|
|
161
|
+
<h3 className="font-semibold text-green-900 mb-2">Recipe Grid Report</h3>
|
|
162
|
+
<p className="text-green-800">
|
|
163
|
+
This is where your recipe grid report content would go.
|
|
164
|
+
The public page is now working correctly without authentication context conflicts.
|
|
165
|
+
</p>
|
|
166
|
+
<div className="mt-4 text-sm text-green-700">
|
|
167
|
+
<p><strong>Event Code:</strong> {eventCode}</p>
|
|
168
|
+
<p><strong>Event ID:</strong> {event.event_id}</p>
|
|
169
|
+
<p><strong>Event Name:</strong> {event.event_name}</p>
|
|
170
|
+
</div>
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
|
|
174
|
+
{/* Event Information */}
|
|
175
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12">
|
|
176
|
+
<div className="lg:col-span-2 space-y-6">
|
|
177
|
+
<div>
|
|
178
|
+
<h2 className="text-2xl font-bold text-gray-900 mb-4">Event Information</h2>
|
|
179
|
+
<div className="bg-gray-50 rounded-lg p-6 space-y-4">
|
|
180
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
181
|
+
<div>
|
|
182
|
+
<h3 className="font-semibold text-gray-700">Date</h3>
|
|
183
|
+
<p className="text-gray-900">
|
|
184
|
+
{event.event_date ? new Date(event.event_date).toLocaleDateString('en-AU', {
|
|
185
|
+
weekday: 'long',
|
|
186
|
+
year: 'numeric',
|
|
187
|
+
month: 'long',
|
|
188
|
+
day: 'numeric'
|
|
189
|
+
}) : 'TBA'}
|
|
190
|
+
</p>
|
|
191
|
+
</div>
|
|
192
|
+
<div>
|
|
193
|
+
<h3 className="font-semibold text-gray-700">Venue</h3>
|
|
194
|
+
<p className="text-gray-900">{event.event_venue || 'TBA'}</p>
|
|
195
|
+
</div>
|
|
196
|
+
<div>
|
|
197
|
+
<h3 className="font-semibold text-gray-700">Participants</h3>
|
|
198
|
+
<p className="text-gray-900">{event.event_participants || 'TBA'}</p>
|
|
199
|
+
</div>
|
|
200
|
+
<div>
|
|
201
|
+
<h3 className="font-semibold text-gray-700">Event Code</h3>
|
|
202
|
+
<p className="text-gray-900 font-mono">{event.event_code}</p>
|
|
203
|
+
</div>
|
|
204
|
+
</div>
|
|
205
|
+
</div>
|
|
206
|
+
</div>
|
|
207
|
+
</div>
|
|
208
|
+
|
|
209
|
+
{/* Event Logo */}
|
|
210
|
+
<div className="flex justify-center lg:justify-start">
|
|
211
|
+
<div className="text-center">
|
|
212
|
+
<EventLogo
|
|
213
|
+
eventId={event.event_id}
|
|
214
|
+
eventName={event.event_name}
|
|
215
|
+
organisationId={event.organisation_id}
|
|
216
|
+
size="2xl"
|
|
217
|
+
className="rounded-lg shadow-lg"
|
|
218
|
+
/>
|
|
219
|
+
<p className="mt-4 text-sm text-gray-600">Event Logo</p>
|
|
220
|
+
</div>
|
|
221
|
+
</div>
|
|
222
|
+
</div>
|
|
223
|
+
</main>
|
|
224
|
+
|
|
225
|
+
<PublicPageFooter event={event} />
|
|
226
|
+
</PublicPageLayout>
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Generic public event page
|
|
232
|
+
*/
|
|
233
|
+
function PublicEventPage() {
|
|
234
|
+
const { eventCode } = usePublicRouteParams({ fetchEventData: false });
|
|
235
|
+
const { event, isLoading, error, refetch } = usePublicEvent(eventCode || '');
|
|
236
|
+
|
|
237
|
+
if (isLoading) return <PublicLoadingSpinner message="Loading event..." />;
|
|
238
|
+
if (error || !event) return <div>Event not found</div>;
|
|
239
|
+
|
|
240
|
+
return (
|
|
241
|
+
<PublicPageLayout eventCode={eventCode || ''} event={event}>
|
|
242
|
+
<PublicPageHeader
|
|
243
|
+
event={event}
|
|
244
|
+
eventCode={eventCode || ''}
|
|
245
|
+
title="Event Details"
|
|
246
|
+
description="Public information about this event"
|
|
247
|
+
/>
|
|
248
|
+
|
|
249
|
+
<main className="max-w-4xl mx-auto px-4 py-6">
|
|
250
|
+
<div className="text-center mb-6">
|
|
251
|
+
<EventLogo
|
|
252
|
+
eventId={event.event_id}
|
|
253
|
+
eventName={event.event_name}
|
|
254
|
+
organisationId={event.organisation_id}
|
|
255
|
+
size="xl"
|
|
256
|
+
className="mx-auto mb-4"
|
|
257
|
+
/>
|
|
258
|
+
<h1 className="text-2xl font-bold text-gray-900">{event.event_name}</h1>
|
|
259
|
+
{event.event_date && (
|
|
260
|
+
<p className="text-gray-600 mt-2">
|
|
261
|
+
{new Date(event.event_date).toLocaleDateString('en-AU')}
|
|
262
|
+
</p>
|
|
263
|
+
)}
|
|
264
|
+
</div>
|
|
265
|
+
</main>
|
|
266
|
+
|
|
267
|
+
<PublicPageFooter event={event} />
|
|
268
|
+
</PublicPageLayout>
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Generic public info page
|
|
274
|
+
*/
|
|
275
|
+
function PublicInfoPage() {
|
|
276
|
+
return (
|
|
277
|
+
<div className="min-h-screen bg-white flex items-center justify-center">
|
|
278
|
+
<div className="max-w-md mx-auto text-center px-4">
|
|
279
|
+
<h1 className="text-2xl font-bold text-gray-900 mb-4">
|
|
280
|
+
Public Information Page
|
|
281
|
+
</h1>
|
|
282
|
+
<p className="text-gray-600">
|
|
283
|
+
This is a public information page that doesn't require authentication.
|
|
284
|
+
</p>
|
|
285
|
+
</div>
|
|
286
|
+
</div>
|
|
287
|
+
);
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Generic public report page
|
|
292
|
+
*/
|
|
293
|
+
function PublicReportPage() {
|
|
294
|
+
return (
|
|
295
|
+
<div className="min-h-screen bg-white flex items-center justify-center">
|
|
296
|
+
<div className="max-w-md mx-auto text-center px-4">
|
|
297
|
+
<h1 className="text-2xl font-bold text-gray-900 mb-4">
|
|
298
|
+
Public Report Page
|
|
299
|
+
</h1>
|
|
300
|
+
<p className="text-gray-600">
|
|
301
|
+
This is a public report page that doesn't require authentication.
|
|
302
|
+
</p>
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export default PublicPageApp;
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Public Page Usage Example
|
|
3
|
+
* @package @jmruthers/pace-core
|
|
4
|
+
* @module Examples/PublicPages
|
|
5
|
+
* @since 1.0.0
|
|
6
|
+
*
|
|
7
|
+
* A complete example showing the correct usage pattern for public pages.
|
|
8
|
+
* This example demonstrates how to properly implement public pages without
|
|
9
|
+
* authentication context conflicts.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```tsx
|
|
13
|
+
* import { PublicPageUsageExample } from '@jmruthers/pace-core/examples';
|
|
14
|
+
*
|
|
15
|
+
* function App() {
|
|
16
|
+
* return (
|
|
17
|
+
* <BrowserRouter>
|
|
18
|
+
* <Routes>
|
|
19
|
+
* <Route path="/events/:eventCode/recipe-grid-report" element={<PublicPageUsageExample />} />
|
|
20
|
+
* </Routes>
|
|
21
|
+
* </BrowserRouter>
|
|
22
|
+
* );
|
|
23
|
+
* }
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
import React from 'react';
|
|
28
|
+
import {
|
|
29
|
+
PublicPageLayout,
|
|
30
|
+
PublicPageHeader,
|
|
31
|
+
PublicPageFooter,
|
|
32
|
+
EventLogo,
|
|
33
|
+
usePublicEvent,
|
|
34
|
+
usePublicRouteParams,
|
|
35
|
+
PublicLoadingSpinner,
|
|
36
|
+
PublicErrorBoundary
|
|
37
|
+
} from '../index';
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Correct usage pattern for public pages
|
|
41
|
+
*
|
|
42
|
+
* This component demonstrates the proper way to implement public pages:
|
|
43
|
+
* 1. Use usePublicRouteParams to get the eventCode from URL
|
|
44
|
+
* 2. Use usePublicEvent to fetch event data
|
|
45
|
+
* 3. Pass event data to PublicPageLayout
|
|
46
|
+
* 4. No authentication context is triggered
|
|
47
|
+
*/
|
|
48
|
+
export function PublicPageUsageExample() {
|
|
49
|
+
// Step 1: Extract event code from URL parameters
|
|
50
|
+
const { eventCode } = usePublicRouteParams({ fetchEventData: false });
|
|
51
|
+
|
|
52
|
+
// Step 2: Fetch event data using the event code
|
|
53
|
+
const { event, isLoading, error, refetch } = usePublicEvent(eventCode || '');
|
|
54
|
+
|
|
55
|
+
// Step 3: Handle loading state
|
|
56
|
+
if (isLoading) {
|
|
57
|
+
return (
|
|
58
|
+
<PublicLoadingSpinner
|
|
59
|
+
message="Loading event details..."
|
|
60
|
+
/>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Step 4: Handle error state
|
|
65
|
+
if (error) {
|
|
66
|
+
return (
|
|
67
|
+
<div className="min-h-screen bg-white flex items-center justify-center">
|
|
68
|
+
<div className="max-w-md mx-auto text-center px-4">
|
|
69
|
+
<div className="mb-6">
|
|
70
|
+
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-red-100 mb-4">
|
|
71
|
+
<svg className="h-6 w-6 text-red-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
72
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-2.5L13.732 4c-.77-.833-1.964-.833-2.732 0L3.732 16.5c-.77.833.192 2.5 1.732 2.5z" />
|
|
73
|
+
</svg>
|
|
74
|
+
</div>
|
|
75
|
+
<h1 className="text-2xl font-bold text-gray-900 mb-2">
|
|
76
|
+
Event Not Found
|
|
77
|
+
</h1>
|
|
78
|
+
<p className="text-gray-600 mb-6">
|
|
79
|
+
The event code "{eventCode}" is invalid or the event is not available for public viewing.
|
|
80
|
+
</p>
|
|
81
|
+
<button
|
|
82
|
+
onClick={refetch}
|
|
83
|
+
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
|
|
84
|
+
>
|
|
85
|
+
Try Again
|
|
86
|
+
</button>
|
|
87
|
+
</div>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Step 5: Handle missing event
|
|
94
|
+
if (!event) {
|
|
95
|
+
return (
|
|
96
|
+
<div className="min-h-screen bg-white flex items-center justify-center">
|
|
97
|
+
<div className="max-w-md mx-auto text-center px-4">
|
|
98
|
+
<h1 className="text-2xl font-bold text-gray-900 mb-4">
|
|
99
|
+
Event Not Available
|
|
100
|
+
</h1>
|
|
101
|
+
<p className="text-gray-600 mb-6">
|
|
102
|
+
This event is not available for public viewing.
|
|
103
|
+
</p>
|
|
104
|
+
<button
|
|
105
|
+
onClick={refetch}
|
|
106
|
+
className="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700 transition-colors"
|
|
107
|
+
>
|
|
108
|
+
Try Again
|
|
109
|
+
</button>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// Step 6: Render the public page with event data
|
|
116
|
+
return (
|
|
117
|
+
<PublicErrorBoundary>
|
|
118
|
+
<PublicPageLayout eventCode={eventCode || ''} event={event}>
|
|
119
|
+
<PublicPageHeader
|
|
120
|
+
event={event}
|
|
121
|
+
eventCode={eventCode || ''}
|
|
122
|
+
title="Recipe Grid Report"
|
|
123
|
+
description="Public recipe grid report for this event"
|
|
124
|
+
/>
|
|
125
|
+
|
|
126
|
+
<main className="max-w-6xl mx-auto px-4 py-8">
|
|
127
|
+
{/* Event Overview */}
|
|
128
|
+
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8 mb-12">
|
|
129
|
+
{/* Event Information */}
|
|
130
|
+
<div className="lg:col-span-2 space-y-6">
|
|
131
|
+
<div>
|
|
132
|
+
<h2 className="text-2xl font-bold text-gray-900 mb-4">Event Information</h2>
|
|
133
|
+
<div className="bg-gray-50 rounded-lg p-6 space-y-4">
|
|
134
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
|
|
135
|
+
<div>
|
|
136
|
+
<h3 className="font-semibold text-gray-700">Date</h3>
|
|
137
|
+
<p className="text-gray-900">
|
|
138
|
+
{event.event_date ? new Date(event.event_date).toLocaleDateString('en-AU', {
|
|
139
|
+
weekday: 'long',
|
|
140
|
+
year: 'numeric',
|
|
141
|
+
month: 'long',
|
|
142
|
+
day: 'numeric'
|
|
143
|
+
}) : 'TBA'}
|
|
144
|
+
</p>
|
|
145
|
+
</div>
|
|
146
|
+
<div>
|
|
147
|
+
<h3 className="font-semibold text-gray-700">Venue</h3>
|
|
148
|
+
<p className="text-gray-900">{event.event_venue || 'TBA'}</p>
|
|
149
|
+
</div>
|
|
150
|
+
<div>
|
|
151
|
+
<h3 className="font-semibold text-gray-700">Participants</h3>
|
|
152
|
+
<p className="text-gray-900">{event.event_participants || 'TBA'}</p>
|
|
153
|
+
</div>
|
|
154
|
+
<div>
|
|
155
|
+
<h3 className="font-semibold text-gray-700">Event Code</h3>
|
|
156
|
+
<p className="text-gray-900 font-mono">{event.event_code}</p>
|
|
157
|
+
</div>
|
|
158
|
+
</div>
|
|
159
|
+
|
|
160
|
+
{event.event_news && (
|
|
161
|
+
<div>
|
|
162
|
+
<h3 className="font-semibold text-gray-700 mb-2">Event News</h3>
|
|
163
|
+
<p className="text-gray-900">{event.event_news}</p>
|
|
164
|
+
</div>
|
|
165
|
+
)}
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
|
|
170
|
+
{/* Event Logo */}
|
|
171
|
+
<div className="flex justify-center lg:justify-start">
|
|
172
|
+
<div className="text-center">
|
|
173
|
+
<EventLogo
|
|
174
|
+
eventId={event.event_id}
|
|
175
|
+
eventName={event.event_name}
|
|
176
|
+
organisationId={event.organisation_id}
|
|
177
|
+
size="2xl"
|
|
178
|
+
className="rounded-lg shadow-lg"
|
|
179
|
+
/>
|
|
180
|
+
<p className="mt-4 text-sm text-gray-600">Event Logo</p>
|
|
181
|
+
</div>
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
{/* Recipe Grid Report Content */}
|
|
186
|
+
<div className="mb-12">
|
|
187
|
+
<div className="bg-green-50 border border-green-200 rounded-lg p-6">
|
|
188
|
+
<h3 className="font-semibold text-green-900 mb-2">Recipe Grid Report</h3>
|
|
189
|
+
<p className="text-green-800">
|
|
190
|
+
This is where your recipe grid report content would go.
|
|
191
|
+
The public page is now working correctly without authentication context conflicts.
|
|
192
|
+
</p>
|
|
193
|
+
<div className="mt-4 text-sm text-green-700">
|
|
194
|
+
<p><strong>Event Code:</strong> {eventCode}</p>
|
|
195
|
+
<p><strong>Event ID:</strong> {event.event_id}</p>
|
|
196
|
+
<p><strong>Event Name:</strong> {event.event_name}</p>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
</div>
|
|
200
|
+
|
|
201
|
+
{/* Event Footer Information */}
|
|
202
|
+
{event.event_footer && (
|
|
203
|
+
<div className="bg-gray-50 rounded-lg p-6">
|
|
204
|
+
<h3 className="font-semibold text-gray-900 mb-2">Additional Information</h3>
|
|
205
|
+
<p className="text-gray-700">{event.event_footer}</p>
|
|
206
|
+
</div>
|
|
207
|
+
)}
|
|
208
|
+
</main>
|
|
209
|
+
|
|
210
|
+
<PublicPageFooter event={event} />
|
|
211
|
+
</PublicPageLayout>
|
|
212
|
+
</PublicErrorBoundary>
|
|
213
|
+
);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export default PublicPageUsageExample;
|
|
@@ -15,6 +15,17 @@ vi.mock('../../providers/OrganisationProvider', () => ({
|
|
|
15
15
|
useOrganisations: vi.fn(() => mockUseOrganisations)
|
|
16
16
|
}));
|
|
17
17
|
|
|
18
|
+
// Mock useOrganisationSecurity to avoid provider dependencies
|
|
19
|
+
vi.mock('../useOrganisationSecurity', () => ({
|
|
20
|
+
useOrganisationSecurity: vi.fn(() => ({
|
|
21
|
+
superAdminContext: {
|
|
22
|
+
isSuperAdmin: false,
|
|
23
|
+
hasGlobalAccess: false,
|
|
24
|
+
canManageAllOrganisations: false
|
|
25
|
+
}
|
|
26
|
+
}))
|
|
27
|
+
}));
|
|
28
|
+
|
|
18
29
|
describe('useOrganisationPermissions', () => {
|
|
19
30
|
describe('Basic functionality', () => {
|
|
20
31
|
it('should return default values when no organisation context', () => {
|
|
@@ -108,7 +119,7 @@ describe('useOrganisationPermissions', () => {
|
|
|
108
119
|
const { result } = renderHook(() => useOrganisationPermissions());
|
|
109
120
|
|
|
110
121
|
expect(result.current.isOrgAdmin).toBe(true);
|
|
111
|
-
expect(result.current.isSuperAdmin).toBe(
|
|
122
|
+
expect(result.current.isSuperAdmin).toBe(false); // Super admin requires database query, not role-based
|
|
112
123
|
expect(result.current.canModerate).toBe(true);
|
|
113
124
|
expect(result.current.canManageMembers).toBe(true);
|
|
114
125
|
expect(result.current.canManageSettings).toBe(true);
|