@jmruthers/pace-core 0.6.4 → 0.6.6
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 +104 -0
- package/README.md +5 -403
- package/core-usage-manifest.json +93 -0
- package/cursor-rules/00-pace-core-compliance.mdc +128 -26
- package/cursor-rules/01-standards-compliance.mdc +49 -8
- package/cursor-rules/02-project-structure.mdc +6 -0
- package/cursor-rules/03-solid-principles.mdc +2 -0
- package/cursor-rules/04-testing-standards.mdc +2 -0
- package/cursor-rules/05-bug-reports-and-features.mdc +2 -0
- package/cursor-rules/06-code-quality.mdc +2 -0
- package/cursor-rules/07-tech-stack-compliance.mdc +2 -0
- package/cursor-rules/08-markup-quality.mdc +52 -27
- package/cursor-rules/09-rbac-compliance.mdc +462 -0
- package/cursor-rules/10-error-handling-patterns.mdc +179 -0
- package/cursor-rules/11-performance-optimization.mdc +169 -0
- package/cursor-rules/12-ci-cd-integration.mdc +150 -0
- package/dist/{AuthService-Cb34EQs3.d.ts → AuthService-DmfO5rGS.d.ts} +10 -0
- package/dist/{DataTable-BMRU8a1j.d.ts → DataTable-2N_tqbfq.d.ts} +1 -1
- package/dist/DataTable-LRJL4IRV.js +15 -0
- package/dist/{PublicPageProvider-DEMpysFR.d.ts → PublicPageProvider-BBH6Vqg7.d.ts} +72 -139
- package/dist/UnifiedAuthProvider-ZT6TIGM7.js +7 -0
- package/dist/api-Y4MQWOFW.js +4 -0
- package/dist/audit-MYQXYZFU.js +3 -0
- package/dist/{chunk-J36DSWQK.js → chunk-2HGJFNAH.js} +8 -28
- package/dist/{chunk-OEWDTMG7.js → chunk-3O3WHILE.js} +38 -121
- package/dist/{chunk-M43Y4SSO.js → chunk-3QC3KRHK.js} +1 -14
- package/dist/{chunk-DGUM43GV.js → chunk-3RG5ZIWI.js} +1 -4
- package/dist/{chunk-QXHPKYJV.js → chunk-4SXLQIZO.js} +1 -26
- package/dist/chunk-4T7OBVTU.js +62 -0
- package/dist/{chunk-E66EQZE6.js → chunk-6GLLNA6U.js} +3 -9
- package/dist/{chunk-ZSAAAMVR.js → chunk-6QYDGKQY.js} +1 -4
- package/dist/{chunk-NN6WWZ5U.js → chunk-7TYHROIV.js} +579 -563
- package/dist/{chunk-M7MPQISP.js → chunk-A55DK444.js} +9 -16
- package/dist/{chunk-63FOKYGO.js → chunk-AHU7G2R5.js} +2 -11
- package/dist/{chunk-L4OXEN46.js → chunk-BVP2BCJF.js} +2 -16
- package/dist/chunk-C7NSAPTL.js +1 -0
- package/dist/{chunk-YKRAFF5K.js → chunk-FENMYN2U.js} +73 -149
- package/dist/{chunk-AVMLPIM7.js → chunk-FTCRZOG2.js} +284 -432
- package/dist/{chunk-G37KK66H.js → chunk-FYHN4DD5.js} +60 -19
- package/dist/{chunk-VBXEHIUJ.js → chunk-HF6O3O37.js} +6 -88
- package/dist/{chunk-I6DAQMWX.js → chunk-LAZMKTTF.js} +930 -891
- package/dist/{chunk-5EC5MEWX.js → chunk-MAGBIDNS.js} +77 -222
- package/dist/chunk-MBADTM7L.js +64 -0
- package/dist/chunk-OHIK3MIO.js +994 -0
- package/dist/{chunk-6SOIHG6Z.js → chunk-S7DKJPLT.js} +115 -44
- package/dist/{chunk-FMUCXFII.js → chunk-SD6WQY43.js} +1 -5
- package/dist/{chunk-PWLANIRT.js → chunk-TTRFSOKR.js} +1 -7
- package/dist/{chunk-5DRSZLL2.js → chunk-UH3NTO3F.js} +1 -6
- package/dist/{chunk-FFQEQTNW.js → chunk-UIYSCEV7.js} +134 -45
- package/dist/{chunk-3LPHPB62.js → chunk-ZFYPMX46.js} +271 -87
- package/dist/{chunk-7JPAB3T5.js → chunk-ZS5VO5JB.js} +1989 -1283
- package/dist/components.d.ts +6 -6
- package/dist/components.js +57 -267
- package/dist/{database.generated-CzIvgcPu.d.ts → database.generated-CcnC_DRc.d.ts} +4795 -3691
- package/dist/eslint-rules/index.cjs +22 -0
- package/dist/eslint-rules/rules/compliance.cjs +348 -0
- package/dist/eslint-rules/rules/components.cjs +113 -0
- package/dist/eslint-rules/rules/imports.cjs +102 -0
- package/dist/eslint-rules/rules/rbac.cjs +790 -0
- package/dist/eslint-rules/utils/helpers.cjs +42 -0
- package/dist/eslint-rules/utils/manifest-loader.cjs +75 -0
- package/dist/hooks.d.ts +5 -5
- package/dist/hooks.js +62 -270
- package/dist/icons/index.d.ts +1 -0
- package/dist/icons/index.js +1 -0
- package/dist/index.d.ts +36 -26
- package/dist/index.js +87 -690
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +8 -35
- package/dist/rbac/eslint-rules.d.ts +46 -44
- package/dist/rbac/eslint-rules.js +7 -4
- package/dist/rbac/index.d.ts +124 -594
- package/dist/rbac/index.js +14 -207
- package/dist/styles/index.js +2 -12
- package/dist/theming/runtime.js +3 -19
- package/dist/{timezone-CHhWg6b4.d.ts → timezone-BZe_eUxx.d.ts} +175 -1
- package/dist/{types-CkbwOr4Y.d.ts → types-B-K_5VnO.d.ts} +4 -0
- package/dist/types-t9H8qKRw.d.ts +55 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +7 -94
- package/dist/{usePublicRouteParams-i3qtoBgg.d.ts → usePublicRouteParams-COZ28Mvq.d.ts} +9 -9
- package/dist/utils.d.ts +24 -117
- package/dist/utils.js +54 -392
- package/docs/README.md +16 -6
- package/docs/api/README.md +4 -402
- package/docs/api/modules.md +454 -930
- package/docs/api-reference/components.md +3 -1
- package/docs/api-reference/deprecated.md +31 -6
- package/docs/api-reference/rpc-functions.md +78 -3
- package/docs/best-practices/accessibility.md +6 -3
- package/docs/getting-started/cursor-rules.md +3 -23
- package/docs/getting-started/dependencies.md +650 -0
- package/docs/getting-started/installation-guide.md +20 -7
- package/docs/getting-started/quick-start.md +23 -12
- package/docs/implementation-guides/permission-enforcement.md +4 -0
- package/docs/rbac/MIGRATION_GUIDE.md +819 -0
- package/docs/rbac/RBAC_CONTRACT.md +724 -0
- package/docs/rbac/README.md +12 -3
- package/docs/rbac/edge-functions-guide.md +376 -0
- package/docs/rbac/secure-client-protection.md +0 -34
- package/docs/standards/00-pace-core-compliance.md +967 -0
- package/docs/standards/01-standards-compliance.md +188 -0
- package/docs/standards/02-project-structure.md +985 -0
- package/docs/standards/03-solid-principles.md +39 -0
- package/docs/standards/04-testing-standards.md +36 -0
- package/docs/standards/05-bug-reports-and-features.md +27 -0
- package/docs/standards/{04-code-style-standard.md → 06-code-quality.md} +2 -0
- package/docs/standards/07-tech-stack-compliance.md +30 -0
- package/docs/standards/08-markup-quality.md +345 -0
- package/docs/standards/{07-rbac-and-rls-standard.md → 09-rbac-compliance.md} +149 -54
- package/docs/standards/10-error-handling-patterns.md +401 -0
- package/docs/standards/11-performance-optimization.md +348 -0
- package/docs/standards/12-ci-cd-integration.md +370 -0
- package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +192 -0
- package/docs/standards/README.md +62 -33
- package/docs/troubleshooting/organisation-context-setup.md +42 -19
- package/eslint-config-pace-core.cjs +20 -4
- package/package.json +31 -21
- package/scripts/audit/audit-compliance.cjs +1295 -0
- package/scripts/audit/audit-components.cjs +260 -0
- package/scripts/audit/audit-dependencies.cjs +395 -0
- package/scripts/audit/audit-rbac.cjs +954 -0
- package/scripts/audit/audit-standards.cjs +1268 -0
- package/scripts/audit/index.cjs +1898 -194
- package/scripts/install-cursor-rules.cjs +259 -8
- package/scripts/validate-master.js +1 -1
- package/src/__tests__/fixtures/supabase.ts +1 -1
- package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +1 -1
- package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +1 -1
- package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +1 -1
- package/src/__tests__/helpers/__tests__/test-utils.test.tsx +3 -3
- package/src/__tests__/helpers/component-test-utils.tsx +1 -1
- package/src/__tests__/helpers/supabaseMock.ts +2 -2
- package/src/__tests__/public-recipe-view.test.ts +38 -9
- package/src/components/Button/Button.tsx +5 -1
- package/src/components/ContextSelector/ContextSelector.tsx +42 -39
- package/src/components/DataTable/__tests__/keyboard.test.tsx +15 -2
- package/src/components/DataTable/components/DataTableBody.tsx +55 -31
- package/src/components/DataTable/components/DataTableCore.tsx +186 -13
- package/src/components/DataTable/components/DataTableLayout.tsx +30 -5
- package/src/components/DataTable/components/EditFields.tsx +23 -3
- package/src/components/DataTable/components/EditableRow.tsx +7 -2
- package/src/components/DataTable/components/ImportModal.tsx +4 -6
- package/src/components/DataTable/components/RowComponent.tsx +12 -0
- package/src/components/DataTable/components/ViewRowModal.tsx +4 -4
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +455 -96
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +122 -58
- package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -4
- package/src/components/DataTable/core/DataTableContext.tsx +1 -1
- package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +51 -47
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +24 -21
- package/src/components/DataTable/hooks/useDataTableState.ts +125 -9
- package/src/components/DataTable/hooks/useTableColumns.ts +40 -2
- package/src/components/DataTable/hooks/useTableHandlers.ts +11 -0
- package/src/components/DataTable/types.ts +5 -0
- package/src/components/DateTimeField/DateTimeField.tsx +20 -20
- package/src/components/DateTimeField/README.md +5 -2
- package/src/components/Dialog/Dialog.test.tsx +361 -318
- package/src/components/Dialog/Dialog.tsx +1154 -323
- package/src/components/Dialog/index.ts +3 -3
- package/src/components/FileDisplay/FileDisplay.test.tsx +45 -2
- package/src/components/FileDisplay/FileDisplay.tsx +28 -22
- package/src/components/Form/Form.test.tsx +9 -10
- package/src/components/Form/Form.tsx +369 -9
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +28 -28
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +40 -54
- package/src/components/LoginForm/LoginForm.tsx +2 -2
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +14 -13
- package/src/components/NavigationMenu/NavigationMenu.tsx +2 -2
- package/src/components/NavigationMenu/useNavigationFiltering.ts +11 -21
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +6 -4
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +30 -41
- package/src/components/PaceAppLayout/README.md +10 -9
- package/src/components/PaceAppLayout/test-setup.tsx +40 -31
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +108 -61
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +27 -3
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +61 -0
- package/src/components/PasswordChange/PasswordChangeForm.tsx +20 -13
- package/src/components/PublicLayout/PublicLayout.test.tsx +7 -3
- package/src/components/PublicLayout/PublicPageLayout.tsx +5 -8
- package/src/components/Select/Select.tsx +23 -21
- package/src/components/Select/types.ts +1 -1
- package/src/components/UserMenu/UserMenu.test.tsx +38 -6
- package/src/components/UserMenu/UserMenu.tsx +39 -34
- package/src/components/index.ts +3 -4
- package/src/eslint-rules/index.cjs +22 -0
- package/src/eslint-rules/rules/compliance.cjs +348 -0
- package/src/eslint-rules/rules/components.cjs +113 -0
- package/src/eslint-rules/rules/imports.cjs +102 -0
- package/src/eslint-rules/rules/rbac.cjs +790 -0
- package/src/eslint-rules/utils/helpers.cjs +42 -0
- package/src/eslint-rules/utils/manifest-loader.cjs +75 -0
- package/src/hooks/__tests__/hooks.integration.test.tsx +6 -8
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +129 -67
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +149 -67
- package/src/hooks/__tests__/usePublicEvent.test.ts +149 -79
- package/src/hooks/__tests__/usePublicEvent.unit.test.ts +158 -109
- package/src/hooks/__tests__/useSessionDraft.test.ts +163 -0
- package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +10 -5
- package/src/hooks/public/usePublicEvent.ts +62 -190
- package/src/hooks/public/usePublicEventLogo.test.ts +70 -17
- package/src/hooks/public/usePublicEventLogo.ts +19 -9
- package/src/hooks/useAppConfig.ts +26 -24
- package/src/hooks/useEventTheme.test.ts +211 -233
- package/src/hooks/useEventTheme.ts +19 -28
- package/src/hooks/useEvents.ts +11 -7
- package/src/hooks/useKeyboardShortcuts.ts +1 -1
- package/src/hooks/useOrganisationPermissions.ts +9 -11
- package/src/hooks/useOrganisations.ts +13 -7
- package/src/hooks/useQueryCache.ts +0 -1
- package/src/hooks/useSessionDraft.ts +380 -0
- package/src/hooks/useSessionRestoration.ts +3 -1
- package/src/icons/index.ts +27 -0
- package/src/index.ts +16 -1
- package/src/providers/OrganisationProvider.tsx +23 -14
- package/src/providers/services/EventServiceProvider.tsx +1 -24
- package/src/providers/services/UnifiedAuthProvider.tsx +5 -48
- package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +3 -0
- package/src/rbac/README.md +20 -20
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +7 -457
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +33 -7
- package/src/rbac/adapters.tsx +7 -295
- package/src/rbac/api.test.ts +44 -56
- package/src/rbac/api.ts +10 -17
- package/src/rbac/cache-invalidation.ts +0 -1
- package/src/rbac/compliance/index.ts +10 -0
- package/src/rbac/compliance/pattern-detector.ts +553 -0
- package/src/rbac/compliance/runtime-compliance.ts +22 -0
- package/src/rbac/components/AccessDenied.tsx +150 -0
- package/src/rbac/components/NavigationGuard.tsx +12 -20
- package/src/rbac/components/PagePermissionGuard.tsx +4 -24
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +21 -8
- package/src/rbac/components/index.ts +3 -41
- package/src/rbac/eslint-rules.js +1 -1
- package/src/rbac/hooks/index.ts +0 -3
- package/src/rbac/hooks/permissions/index.ts +0 -3
- package/src/rbac/hooks/permissions/useAccessLevel.ts +4 -8
- package/src/rbac/hooks/usePermissions.ts +0 -3
- package/src/rbac/hooks/useRBAC.test.ts +21 -3
- package/src/rbac/hooks/useRBAC.ts +4 -3
- package/src/rbac/hooks/useResolvedScope.test.ts +57 -47
- package/src/rbac/hooks/useResolvedScope.ts +58 -140
- package/src/rbac/hooks/useResourcePermissions.test.ts +241 -60
- package/src/rbac/hooks/useResourcePermissions.ts +182 -63
- package/src/rbac/hooks/useRoleManagement.test.ts +65 -22
- package/src/rbac/hooks/useRoleManagement.ts +147 -19
- package/src/rbac/hooks/useSecureSupabase.ts +4 -8
- package/src/rbac/index.ts +7 -9
- package/src/rbac/permissions.ts +17 -17
- package/src/rbac/utils/contextValidator.ts +45 -7
- package/src/services/AuthService.ts +132 -23
- package/src/services/EventService.ts +4 -97
- package/src/services/InactivityService.ts +155 -58
- package/src/services/OrganisationService.ts +7 -44
- package/src/services/__tests__/OrganisationService.test.ts +26 -8
- package/src/services/base/BaseService.ts +0 -3
- package/src/styles/core.css +4 -0
- package/src/types/database.generated.ts +4733 -3809
- package/src/utils/__tests__/organisationContext.unit.test.ts +9 -10
- package/src/utils/context/organisationContext.test.ts +13 -28
- package/src/utils/context/organisationContext.ts +21 -52
- package/src/utils/dynamic/dynamicUtils.ts +1 -1
- package/src/utils/file-reference/index.ts +39 -15
- package/src/utils/formatting/formatDateTime.test.ts +3 -2
- package/src/utils/formatting/formatTime.test.ts +3 -2
- package/src/utils/google-places/loadGoogleMapsScript.ts +29 -4
- package/src/utils/index.ts +4 -1
- package/src/utils/persistence/__tests__/keyDerivation.test.ts +135 -0
- package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +123 -0
- package/src/utils/persistence/keyDerivation.ts +304 -0
- package/src/utils/persistence/sensitiveFieldDetection.ts +212 -0
- package/src/utils/security/secureStorage.ts +5 -5
- package/src/utils/storage/helpers.ts +3 -3
- package/src/utils/supabase/createBaseClient.ts +147 -0
- package/src/utils/timezone/timezone.test.ts +1 -2
- package/src/utils/timezone/timezone.ts +1 -1
- package/src/utils/validation/csrf.ts +4 -4
- package/cursor-rules/CHANGELOG.md +0 -119
- package/cursor-rules/README.md +0 -192
- package/dist/DataTable-E7YQZD7D.js +0 -175
- package/dist/DataTable-E7YQZD7D.js.map +0 -1
- package/dist/UnifiedAuthProvider-QPXO24B4.js +0 -18
- package/dist/UnifiedAuthProvider-QPXO24B4.js.map +0 -1
- package/dist/api-6LVZTHDS.js +0 -52
- package/dist/api-6LVZTHDS.js.map +0 -1
- package/dist/audit-V53FV5AG.js +0 -17
- package/dist/audit-V53FV5AG.js.map +0 -1
- package/dist/chunk-36LVWXB2.js +0 -227
- package/dist/chunk-36LVWXB2.js.map +0 -1
- package/dist/chunk-3LPHPB62.js.map +0 -1
- package/dist/chunk-5DRSZLL2.js.map +0 -1
- package/dist/chunk-5EC5MEWX.js.map +0 -1
- package/dist/chunk-63FOKYGO.js.map +0 -1
- package/dist/chunk-6SOIHG6Z.js.map +0 -1
- package/dist/chunk-7JPAB3T5.js.map +0 -1
- package/dist/chunk-ATKZM7RX.js +0 -2053
- package/dist/chunk-ATKZM7RX.js.map +0 -1
- package/dist/chunk-AVMLPIM7.js.map +0 -1
- package/dist/chunk-DGUM43GV.js.map +0 -1
- package/dist/chunk-E66EQZE6.js.map +0 -1
- package/dist/chunk-FFQEQTNW.js.map +0 -1
- package/dist/chunk-FMUCXFII.js.map +0 -1
- package/dist/chunk-G37KK66H.js.map +0 -1
- package/dist/chunk-I6DAQMWX.js.map +0 -1
- package/dist/chunk-J36DSWQK.js.map +0 -1
- package/dist/chunk-KQCRWDSA.js +0 -1
- package/dist/chunk-KQCRWDSA.js.map +0 -1
- package/dist/chunk-L4OXEN46.js.map +0 -1
- package/dist/chunk-LMC26NLJ.js +0 -84
- package/dist/chunk-LMC26NLJ.js.map +0 -1
- package/dist/chunk-M43Y4SSO.js.map +0 -1
- package/dist/chunk-M7MPQISP.js.map +0 -1
- package/dist/chunk-NN6WWZ5U.js.map +0 -1
- package/dist/chunk-OEWDTMG7.js.map +0 -1
- package/dist/chunk-PWLANIRT.js.map +0 -1
- package/dist/chunk-QXHPKYJV.js.map +0 -1
- package/dist/chunk-VBXEHIUJ.js.map +0 -1
- package/dist/chunk-YKRAFF5K.js.map +0 -1
- package/dist/chunk-ZSAAAMVR.js.map +0 -1
- package/dist/components.js.map +0 -1
- package/dist/contextValidator-OOPCLPZW.js +0 -9
- package/dist/contextValidator-OOPCLPZW.js.map +0 -1
- package/dist/eslint-rules/pace-core-compliance.cjs +0 -510
- package/dist/hooks.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/providers.js.map +0 -1
- package/dist/rbac/eslint-rules.js.map +0 -1
- package/dist/rbac/index.js.map +0 -1
- package/dist/styles/index.js.map +0 -1
- package/dist/theming/runtime.js.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils.js.map +0 -1
- package/docs/standards/01-architecture-standard.md +0 -44
- package/docs/standards/02-api-and-rpc-standard.md +0 -39
- package/docs/standards/03-component-standard.md +0 -32
- package/docs/standards/05-security-standard.md +0 -44
- package/docs/standards/06-testing-and-docs-standard.md +0 -29
- package/docs/standards/pace-core-compliance.md +0 -432
- package/scripts/audit/core/checks/accessibility.cjs +0 -197
- package/scripts/audit/core/checks/api-usage.cjs +0 -191
- package/scripts/audit/core/checks/bundle.cjs +0 -142
- package/scripts/audit/core/checks/compliance.cjs +0 -2706
- package/scripts/audit/core/checks/config.cjs +0 -54
- package/scripts/audit/core/checks/coverage.cjs +0 -84
- package/scripts/audit/core/checks/dependencies.cjs +0 -994
- package/scripts/audit/core/checks/documentation.cjs +0 -268
- package/scripts/audit/core/checks/environment.cjs +0 -116
- package/scripts/audit/core/checks/error-handling.cjs +0 -340
- package/scripts/audit/core/checks/forms.cjs +0 -172
- package/scripts/audit/core/checks/heuristics.cjs +0 -68
- package/scripts/audit/core/checks/hooks.cjs +0 -334
- package/scripts/audit/core/checks/imports.cjs +0 -244
- package/scripts/audit/core/checks/performance.cjs +0 -325
- package/scripts/audit/core/checks/routes.cjs +0 -117
- package/scripts/audit/core/checks/state.cjs +0 -130
- package/scripts/audit/core/checks/structure.cjs +0 -65
- package/scripts/audit/core/checks/style.cjs +0 -584
- package/scripts/audit/core/checks/testing.cjs +0 -122
- package/scripts/audit/core/checks/typescript.cjs +0 -61
- package/scripts/audit/core/scanner.cjs +0 -199
- package/scripts/audit/core/utils.cjs +0 -137
- package/scripts/audit/reporters/console.cjs +0 -151
- package/scripts/audit/reporters/json.cjs +0 -54
- package/scripts/audit/reporters/markdown.cjs +0 -124
- package/scripts/audit-consuming-app.cjs +0 -86
- package/src/eslint-rules/pace-core-compliance.cjs +0 -510
- package/src/eslint-rules/pace-core-compliance.js +0 -638
- package/src/rbac/components/EnhancedNavigationMenu.test.tsx +0 -555
- package/src/rbac/components/EnhancedNavigationMenu.tsx +0 -293
- package/src/rbac/components/NavigationProvider.test.tsx +0 -481
- package/src/rbac/components/NavigationProvider.tsx +0 -345
- package/src/rbac/components/PagePermissionProvider.test.tsx +0 -476
- package/src/rbac/components/PagePermissionProvider.tsx +0 -279
- package/src/rbac/components/PermissionEnforcer.tsx +0 -312
- package/src/rbac/components/RoleBasedRouter.tsx +0 -440
- package/src/rbac/components/SecureDataProvider.test.tsx +0 -543
- package/src/rbac/components/SecureDataProvider.tsx +0 -339
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -620
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -726
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -661
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +0 -881
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +0 -783
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +0 -645
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -659
- package/src/rbac/hooks/permissions/useCachedPermissions.ts +0 -79
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +0 -90
- package/src/rbac/hooks/permissions/useHasAnyPermission.ts +0 -90
|
@@ -1,98 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
SelectTrigger,
|
|
28
|
-
SelectValue
|
|
29
|
-
} from "./chunk-7JPAB3T5.js";
|
|
30
|
-
import {
|
|
31
|
-
useCan,
|
|
32
|
-
usePermissions,
|
|
33
|
-
useRBAC,
|
|
34
|
-
useResolvedScope
|
|
35
|
-
} from "./chunk-NN6WWZ5U.js";
|
|
36
|
-
import {
|
|
37
|
-
createFileReferenceService,
|
|
38
|
-
generateFileUrlsBatch,
|
|
39
|
-
getPublicUrl,
|
|
40
|
-
getSignedUrl,
|
|
41
|
-
uploadFileWithReference,
|
|
42
|
-
useAddressAutocomplete,
|
|
43
|
-
useEventTheme,
|
|
44
|
-
useFileDisplay,
|
|
45
|
-
usePreventTabReload,
|
|
46
|
-
usePublicFileDisplay
|
|
47
|
-
} from "./chunk-YKRAFF5K.js";
|
|
48
|
-
import {
|
|
49
|
-
useToast
|
|
50
|
-
} from "./chunk-6SOIHG6Z.js";
|
|
51
|
-
import {
|
|
52
|
-
ErrorBoundary,
|
|
53
|
-
PublicPageContext,
|
|
54
|
-
useAppConfig,
|
|
55
|
-
useEvents,
|
|
56
|
-
useIsPublicPage
|
|
57
|
-
} from "./chunk-OEWDTMG7.js";
|
|
58
|
-
import {
|
|
59
|
-
EventServiceContext,
|
|
60
|
-
useOrganisations,
|
|
61
|
-
useSessionRestoration,
|
|
62
|
-
useUnifiedAuth
|
|
63
|
-
} from "./chunk-AVMLPIM7.js";
|
|
64
|
-
import {
|
|
65
|
-
isSuperAdmin
|
|
66
|
-
} from "./chunk-3LPHPB62.js";
|
|
67
|
-
import {
|
|
68
|
-
EventContextRequiredError,
|
|
69
|
-
OrganisationContextRequiredError
|
|
70
|
-
} from "./chunk-36LVWXB2.js";
|
|
71
|
-
import {
|
|
72
|
-
assertAppId
|
|
73
|
-
} from "./chunk-QXHPKYJV.js";
|
|
74
|
-
import {
|
|
75
|
-
LoadingSpinner,
|
|
76
|
-
getAppId
|
|
77
|
-
} from "./chunk-J36DSWQK.js";
|
|
78
|
-
import {
|
|
79
|
-
cn
|
|
80
|
-
} from "./chunk-M43Y4SSO.js";
|
|
81
|
-
import {
|
|
82
|
-
getCurrentAppName
|
|
83
|
-
} from "./chunk-M7MPQISP.js";
|
|
84
|
-
import {
|
|
85
|
-
clearPalette
|
|
86
|
-
} from "./chunk-L4OXEN46.js";
|
|
87
|
-
import {
|
|
88
|
-
createLogger,
|
|
89
|
-
logger
|
|
90
|
-
} from "./chunk-PWLANIRT.js";
|
|
1
|
+
import { AccessDenied } from './chunk-4T7OBVTU.js';
|
|
2
|
+
import { Input, Dialog, DialogContent, DialogHeader, DialogBody, DialogFooter, Card, CardHeader, CardTitle, CardDescription, CardContent, Alert, AlertDescription, CardFooter, Select, SelectTrigger, SelectContent, SelectLabel, SelectSeparator, SelectItem, DialogTitle, SelectValue, deriveFormKey, useSessionDraft, filterSensitiveFields, isSensitiveField, SelectGroup, AlertTitle } from './chunk-ZS5VO5JB.js';
|
|
3
|
+
import { Button, useRBAC, useResolvedScope, usePermissions, useEvents, useCan } from './chunk-7TYHROIV.js';
|
|
4
|
+
import { useAddressAutocomplete, createFileReferenceService, uploadFileWithReference, usePublicFileDisplay, useFileDisplay, getPublicUrl, getSignedUrl, generateFileUrlsBatch, useEventTheme, usePreventTabReload } from './chunk-FENMYN2U.js';
|
|
5
|
+
import { clearPalette } from './chunk-BVP2BCJF.js';
|
|
6
|
+
import { useToast } from './chunk-S7DKJPLT.js';
|
|
7
|
+
import { useIsPublicPage, PublicPageContext, useAppConfig, ErrorBoundary } from './chunk-3O3WHILE.js';
|
|
8
|
+
import { useUnifiedAuth, useOrganisations, UnifiedAuthContext, EventServiceContext, useSessionRestoration } from './chunk-FTCRZOG2.js';
|
|
9
|
+
import { EventContextRequiredError, OrganisationContextRequiredError, isSuperAdmin } from './chunk-ZFYPMX46.js';
|
|
10
|
+
import { assertAppId } from './chunk-4SXLQIZO.js';
|
|
11
|
+
import { LoadingSpinner, getAppId } from './chunk-2HGJFNAH.js';
|
|
12
|
+
import { cn, getCurrentAppName } from './chunk-A55DK444.js';
|
|
13
|
+
import { createLogger, logger } from './chunk-TTRFSOKR.js';
|
|
14
|
+
import * as React7 from 'react';
|
|
15
|
+
import React7__default, { useState, useRef, useMemo, useCallback, useEffect, useContext } from 'react';
|
|
16
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
17
|
+
import * as LabelPrimitive from '@radix-ui/react-label';
|
|
18
|
+
import { FileText, ExternalLink, X, ChevronDown, KeyRound, LogOut, Calendar as Calendar$1, Building2, AlertCircle, RefreshCw } from 'lucide-react';
|
|
19
|
+
import * as SwitchPrimitive from '@radix-ui/react-switch';
|
|
20
|
+
import * as TabsPrimitive from '@radix-ui/react-tabs';
|
|
21
|
+
import { useDayPicker, DayPicker } from 'react-day-picker';
|
|
22
|
+
import { enAU } from 'date-fns/locale';
|
|
23
|
+
import * as ToastPrimitives from '@radix-ui/react-toast';
|
|
24
|
+
import { useForm, useWatch, FormProvider, useFormContext, Controller } from 'react-hook-form';
|
|
25
|
+
import { zodResolver } from '@hookform/resolvers/zod';
|
|
26
|
+
import { useLocation, Link, useNavigate, Outlet, Navigate } from 'react-router-dom';
|
|
91
27
|
|
|
92
|
-
|
|
93
|
-
import * as React from "react";
|
|
94
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
95
|
-
var AddressField = React.forwardRef(
|
|
28
|
+
var AddressField = React7.forwardRef(
|
|
96
29
|
({
|
|
97
30
|
apiKey,
|
|
98
31
|
value: controlledValue,
|
|
@@ -111,13 +44,13 @@ var AddressField = React.forwardRef(
|
|
|
111
44
|
cacheTTL,
|
|
112
45
|
...props
|
|
113
46
|
}, ref) => {
|
|
114
|
-
const [internalValue, setInternalValue] =
|
|
115
|
-
const [isOpen, setIsOpen] =
|
|
116
|
-
const [selectedIndex, setSelectedIndex] =
|
|
117
|
-
const [inputFocused, setInputFocused] =
|
|
118
|
-
const inputRef =
|
|
119
|
-
const suggestionsRef =
|
|
120
|
-
const containerRef =
|
|
47
|
+
const [internalValue, setInternalValue] = React7.useState(defaultValue);
|
|
48
|
+
const [isOpen, setIsOpen] = React7.useState(false);
|
|
49
|
+
const [selectedIndex, setSelectedIndex] = React7.useState(-1);
|
|
50
|
+
const [inputFocused, setInputFocused] = React7.useState(false);
|
|
51
|
+
const inputRef = React7.useRef(null);
|
|
52
|
+
const suggestionsRef = React7.useRef(null);
|
|
53
|
+
const containerRef = React7.useRef(null);
|
|
121
54
|
const value = controlledValue !== void 0 ? controlledValue : internalValue;
|
|
122
55
|
const { suggestions, isLoading, error: autocompleteError, selectAddress, clearSuggestions } = useAddressAutocomplete(apiKey, value, {
|
|
123
56
|
autocompleteOptions,
|
|
@@ -125,14 +58,14 @@ var AddressField = React.forwardRef(
|
|
|
125
58
|
cacheEnabled,
|
|
126
59
|
cacheTTL
|
|
127
60
|
});
|
|
128
|
-
|
|
61
|
+
React7.useEffect(() => {
|
|
129
62
|
if (suggestions.length > 0 && inputFocused && value.trim()) {
|
|
130
63
|
setIsOpen(true);
|
|
131
64
|
} else if (suggestions.length === 0 || !value.trim()) {
|
|
132
65
|
setIsOpen(false);
|
|
133
66
|
}
|
|
134
67
|
}, [suggestions, inputFocused, value]);
|
|
135
|
-
const handleInputChange =
|
|
68
|
+
const handleInputChange = React7.useCallback(
|
|
136
69
|
(e) => {
|
|
137
70
|
const newValue = e.target.value;
|
|
138
71
|
if (controlledValue === void 0) {
|
|
@@ -147,7 +80,7 @@ var AddressField = React.forwardRef(
|
|
|
147
80
|
},
|
|
148
81
|
[controlledValue, onInputChange, onChange, clearSuggestions]
|
|
149
82
|
);
|
|
150
|
-
const handleSelectAddress =
|
|
83
|
+
const handleSelectAddress = React7.useCallback(
|
|
151
84
|
async (placeId) => {
|
|
152
85
|
setIsOpen(false);
|
|
153
86
|
setSelectedIndex(-1);
|
|
@@ -164,7 +97,7 @@ var AddressField = React.forwardRef(
|
|
|
164
97
|
},
|
|
165
98
|
[selectAddress, onChange, onInputChange, controlledValue]
|
|
166
99
|
);
|
|
167
|
-
const handleKeyDown =
|
|
100
|
+
const handleKeyDown = React7.useCallback(
|
|
168
101
|
(e) => {
|
|
169
102
|
if (!isOpen || suggestions.length === 0) {
|
|
170
103
|
if (e.key === "Escape") {
|
|
@@ -202,13 +135,13 @@ var AddressField = React.forwardRef(
|
|
|
202
135
|
},
|
|
203
136
|
[isOpen, suggestions, selectedIndex, handleSelectAddress]
|
|
204
137
|
);
|
|
205
|
-
const handleFocus =
|
|
138
|
+
const handleFocus = React7.useCallback(() => {
|
|
206
139
|
setInputFocused(true);
|
|
207
140
|
if (suggestions.length > 0 && value.trim()) {
|
|
208
141
|
setIsOpen(true);
|
|
209
142
|
}
|
|
210
143
|
}, [suggestions, value]);
|
|
211
|
-
const handleBlur =
|
|
144
|
+
const handleBlur = React7.useCallback(
|
|
212
145
|
(e) => {
|
|
213
146
|
setTimeout(() => {
|
|
214
147
|
if (!containerRef.current?.contains(document.activeElement)) {
|
|
@@ -220,7 +153,7 @@ var AddressField = React.forwardRef(
|
|
|
220
153
|
},
|
|
221
154
|
[]
|
|
222
155
|
);
|
|
223
|
-
|
|
156
|
+
React7.useEffect(() => {
|
|
224
157
|
const handleClickOutside = (event) => {
|
|
225
158
|
if (containerRef.current && !containerRef.current.contains(event.target)) {
|
|
226
159
|
setIsOpen(false);
|
|
@@ -234,8 +167,8 @@ var AddressField = React.forwardRef(
|
|
|
234
167
|
};
|
|
235
168
|
}
|
|
236
169
|
}, [isOpen]);
|
|
237
|
-
const suggestionsId =
|
|
238
|
-
|
|
170
|
+
const suggestionsId = React7.useId();
|
|
171
|
+
React7.useEffect(() => {
|
|
239
172
|
if (selectedIndex >= 0) {
|
|
240
173
|
const selectedItem = document.getElementById(
|
|
241
174
|
`${suggestionsId}-item-${selectedIndex}`
|
|
@@ -245,7 +178,7 @@ var AddressField = React.forwardRef(
|
|
|
245
178
|
}
|
|
246
179
|
}
|
|
247
180
|
}, [selectedIndex, suggestionsId]);
|
|
248
|
-
|
|
181
|
+
React7.useImperativeHandle(ref, () => inputRef.current);
|
|
249
182
|
const hasError = error || !!autocompleteError;
|
|
250
183
|
return /* @__PURE__ */ jsxs("form", { ref: containerRef, className: cn("relative w-full", className), children: [
|
|
251
184
|
/* @__PURE__ */ jsx(
|
|
@@ -285,7 +218,7 @@ var AddressField = React.forwardRef(
|
|
|
285
218
|
"list-none p-0 m-0"
|
|
286
219
|
),
|
|
287
220
|
"data-testid": "address-suggestions",
|
|
288
|
-
children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsxs(
|
|
221
|
+
children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsxs(React7.Fragment, { children: [
|
|
289
222
|
/* @__PURE__ */ jsx(
|
|
290
223
|
"dt",
|
|
291
224
|
{
|
|
@@ -314,15 +247,10 @@ var AddressField = React.forwardRef(
|
|
|
314
247
|
}
|
|
315
248
|
);
|
|
316
249
|
AddressField.displayName = "AddressField";
|
|
317
|
-
|
|
318
|
-
// src/components/Label/Label.tsx
|
|
319
|
-
import * as React2 from "react";
|
|
320
|
-
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
321
|
-
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
322
250
|
var getLabelClasses = () => {
|
|
323
251
|
return "font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70";
|
|
324
252
|
};
|
|
325
|
-
var Label =
|
|
253
|
+
var Label = React7.forwardRef(({
|
|
326
254
|
className,
|
|
327
255
|
required = false,
|
|
328
256
|
requiredIndicator,
|
|
@@ -337,8 +265,8 @@ var Label = React2.forwardRef(({
|
|
|
337
265
|
}, ref) => {
|
|
338
266
|
const hasError = !!error;
|
|
339
267
|
const showHelperText = helperText && !hasError;
|
|
340
|
-
return /* @__PURE__ */
|
|
341
|
-
/* @__PURE__ */
|
|
268
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
269
|
+
/* @__PURE__ */ jsxs(
|
|
342
270
|
LabelPrimitive.Root,
|
|
343
271
|
{
|
|
344
272
|
ref,
|
|
@@ -351,7 +279,7 @@ var Label = React2.forwardRef(({
|
|
|
351
279
|
...props,
|
|
352
280
|
children: [
|
|
353
281
|
children,
|
|
354
|
-
required && /* @__PURE__ */
|
|
282
|
+
required && /* @__PURE__ */ jsx(
|
|
355
283
|
"span",
|
|
356
284
|
{
|
|
357
285
|
"aria-label": "required",
|
|
@@ -365,8 +293,8 @@ var Label = React2.forwardRef(({
|
|
|
365
293
|
]
|
|
366
294
|
}
|
|
367
295
|
),
|
|
368
|
-
showHelperText && /* @__PURE__ */
|
|
369
|
-
hasError && /* @__PURE__ */
|
|
296
|
+
showHelperText && /* @__PURE__ */ jsx("p", { className: cn("text-muted-foreground", helperTextClassName), children: helperText }),
|
|
297
|
+
hasError && /* @__PURE__ */ jsx(
|
|
370
298
|
"p",
|
|
371
299
|
{
|
|
372
300
|
role: "alert",
|
|
@@ -378,11 +306,8 @@ var Label = React2.forwardRef(({
|
|
|
378
306
|
] });
|
|
379
307
|
});
|
|
380
308
|
Label.displayName = LabelPrimitive.Root.displayName;
|
|
381
|
-
|
|
382
|
-
// src/components/Textarea/Textarea.tsx
|
|
383
|
-
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
384
309
|
function Textarea({ className, variant = "default", size = "md", error, ref, ...props }) {
|
|
385
|
-
return /* @__PURE__ */
|
|
310
|
+
return /* @__PURE__ */ jsx(
|
|
386
311
|
"textarea",
|
|
387
312
|
{
|
|
388
313
|
className: cn(
|
|
@@ -407,21 +332,14 @@ function Textarea({ className, variant = "default", size = "md", error, ref, ...
|
|
|
407
332
|
);
|
|
408
333
|
}
|
|
409
334
|
Textarea.displayName = "Textarea";
|
|
410
|
-
|
|
411
|
-
// src/components/FileDisplay/FileDisplay.tsx
|
|
412
|
-
import React3, { useState as useState3, useEffect as useEffect3, useCallback as useCallback3, useRef as useRef3, useContext, useMemo } from "react";
|
|
413
|
-
import { FileText, ExternalLink } from "lucide-react";
|
|
414
|
-
|
|
415
|
-
// src/hooks/useFileUrl.ts
|
|
416
|
-
import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2, useRef as useRef2 } from "react";
|
|
417
335
|
var log = createLogger("useFileUrl");
|
|
418
336
|
function useFileUrl(fileReference, options) {
|
|
419
337
|
const { organisation_id, supabase, autoLoad = true } = options;
|
|
420
|
-
const [url, setUrl] =
|
|
421
|
-
const [isLoading, setIsLoading] =
|
|
422
|
-
const [error, setError] =
|
|
423
|
-
const fileReferenceIdRef =
|
|
424
|
-
const loadUrl =
|
|
338
|
+
const [url, setUrl] = useState(null);
|
|
339
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
340
|
+
const [error, setError] = useState(null);
|
|
341
|
+
const fileReferenceIdRef = useRef(null);
|
|
342
|
+
const loadUrl = useCallback(async () => {
|
|
425
343
|
if (!fileReference) {
|
|
426
344
|
setUrl(null);
|
|
427
345
|
setIsLoading(false);
|
|
@@ -463,13 +381,13 @@ function useFileUrl(fileReference, options) {
|
|
|
463
381
|
setIsLoading(false);
|
|
464
382
|
}
|
|
465
383
|
}, [fileReference, supabase, organisation_id, isLoading, url]);
|
|
466
|
-
const clear =
|
|
384
|
+
const clear = useCallback(() => {
|
|
467
385
|
setUrl(null);
|
|
468
386
|
setError(null);
|
|
469
387
|
setIsLoading(false);
|
|
470
388
|
fileReferenceIdRef.current = null;
|
|
471
389
|
}, []);
|
|
472
|
-
|
|
390
|
+
useEffect(() => {
|
|
473
391
|
if (autoLoad) {
|
|
474
392
|
if (fileReferenceIdRef.current !== fileReference?.id) {
|
|
475
393
|
setUrl(null);
|
|
@@ -488,9 +406,6 @@ function useFileUrl(fileReference, options) {
|
|
|
488
406
|
clear
|
|
489
407
|
};
|
|
490
408
|
}
|
|
491
|
-
|
|
492
|
-
// src/components/FileDisplay/FileDisplay.tsx
|
|
493
|
-
import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
494
409
|
var fallbackSizeClasses = {
|
|
495
410
|
xs: "size-4 text-xs",
|
|
496
411
|
sm: "size-6 text-sm",
|
|
@@ -511,7 +426,7 @@ function defaultGenerateFallbackText(fileName) {
|
|
|
511
426
|
if (words.length === 0) return "FL";
|
|
512
427
|
return words.map((word) => word.charAt(0).toUpperCase()).join("").substring(0, 3);
|
|
513
428
|
}
|
|
514
|
-
var FileDisplayContent =
|
|
429
|
+
var FileDisplayContent = React7__default.memo(function FileDisplayContent2({
|
|
515
430
|
isLoading,
|
|
516
431
|
error,
|
|
517
432
|
fileUrl,
|
|
@@ -538,21 +453,21 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
538
453
|
enableChildren = false,
|
|
539
454
|
showMetadata = true
|
|
540
455
|
}) {
|
|
541
|
-
const [imageError, setImageError] =
|
|
542
|
-
const [internalFileUrls, setInternalFileUrls] =
|
|
543
|
-
const [deleteDialogOpen, setDeleteDialogOpen] =
|
|
544
|
-
const fileReferencesRef =
|
|
545
|
-
const imgRef =
|
|
546
|
-
const currentSrcRef =
|
|
547
|
-
const isImageLoadingRef =
|
|
456
|
+
const [imageError, setImageError] = useState(false);
|
|
457
|
+
const [internalFileUrls, setInternalFileUrls] = useState(new Map(fileUrls));
|
|
458
|
+
const [deleteDialogOpen, setDeleteDialogOpen] = useState(false);
|
|
459
|
+
const fileReferencesRef = useRef([]);
|
|
460
|
+
const imgRef = useRef(null);
|
|
461
|
+
const currentSrcRef = useRef(null);
|
|
462
|
+
const isImageLoadingRef = useRef(false);
|
|
548
463
|
const stableFileUrl = useMemo(() => fileUrl, [fileUrl]);
|
|
549
|
-
const handleImageLoadStart =
|
|
464
|
+
const handleImageLoadStart = useCallback(() => {
|
|
550
465
|
isImageLoadingRef.current = true;
|
|
551
466
|
if (stableFileUrl) {
|
|
552
467
|
currentSrcRef.current = stableFileUrl;
|
|
553
468
|
}
|
|
554
469
|
}, [stableFileUrl]);
|
|
555
|
-
const handleImageLoad =
|
|
470
|
+
const handleImageLoad = useCallback(() => {
|
|
556
471
|
isImageLoadingRef.current = false;
|
|
557
472
|
if (stableFileUrl) {
|
|
558
473
|
currentSrcRef.current = stableFileUrl;
|
|
@@ -566,7 +481,7 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
566
481
|
const fallbackClasses = useMemo(() => {
|
|
567
482
|
return getFallbackClasses(fallbackSize);
|
|
568
483
|
}, [fallbackSize]);
|
|
569
|
-
|
|
484
|
+
useEffect(() => {
|
|
570
485
|
const currentIds = fileReferences.map((f) => f.id).join(",");
|
|
571
486
|
const prevIds = fileReferencesRef.current.map((f) => f.id).join(",");
|
|
572
487
|
if (currentIds !== prevIds) {
|
|
@@ -612,17 +527,17 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
612
527
|
};
|
|
613
528
|
if (error) {
|
|
614
529
|
if (ErrorComponent) {
|
|
615
|
-
return /* @__PURE__ */
|
|
530
|
+
return /* @__PURE__ */ jsx(ErrorComponent, { error, retry: clearError });
|
|
616
531
|
}
|
|
617
532
|
if (showFallback) {
|
|
618
|
-
return /* @__PURE__ */
|
|
533
|
+
return /* @__PURE__ */ jsx("figure", { className, title: "File unavailable", children: /* @__PURE__ */ jsx("p", { className: fallbackClasses, children: computedFallbackText }) });
|
|
619
534
|
}
|
|
620
|
-
return /* @__PURE__ */
|
|
621
|
-
/* @__PURE__ */
|
|
535
|
+
return /* @__PURE__ */ jsxs("figure", { className, title: "Error", children: [
|
|
536
|
+
/* @__PURE__ */ jsxs("p", { className: getFallbackClasses(fallbackSize || "md"), children: [
|
|
622
537
|
"Error loading file: ",
|
|
623
538
|
error instanceof Error ? error.message : String(error)
|
|
624
539
|
] }),
|
|
625
|
-
clearError && /* @__PURE__ */
|
|
540
|
+
clearError && /* @__PURE__ */ jsx(
|
|
626
541
|
Button,
|
|
627
542
|
{
|
|
628
543
|
onClick: clearError,
|
|
@@ -635,38 +550,38 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
635
550
|
}
|
|
636
551
|
if (fileCount === 0 && !isLoading) {
|
|
637
552
|
if (showFallback) {
|
|
638
|
-
return /* @__PURE__ */
|
|
639
|
-
/* @__PURE__ */
|
|
553
|
+
return /* @__PURE__ */ jsxs("figure", { className, title: "No file", children: [
|
|
554
|
+
/* @__PURE__ */ jsx("p", { className: fallbackClasses, children: computedFallbackText }),
|
|
640
555
|
children
|
|
641
556
|
] });
|
|
642
557
|
}
|
|
643
|
-
return /* @__PURE__ */
|
|
644
|
-
/* @__PURE__ */
|
|
558
|
+
return /* @__PURE__ */ jsxs("figure", { className: `text-sec-500 text-center p-4 ${className}`, children: [
|
|
559
|
+
/* @__PURE__ */ jsx("p", { children: "No files found" }),
|
|
645
560
|
children
|
|
646
561
|
] });
|
|
647
562
|
}
|
|
648
563
|
if (isLoading && showFallback && fileCount === 0) {
|
|
649
|
-
return /* @__PURE__ */
|
|
650
|
-
/* @__PURE__ */
|
|
564
|
+
return /* @__PURE__ */ jsxs("figure", { className, title: "Loading...", children: [
|
|
565
|
+
/* @__PURE__ */ jsx("p", { className: fallbackClasses, children: computedFallbackText }),
|
|
651
566
|
children
|
|
652
567
|
] });
|
|
653
568
|
}
|
|
654
569
|
if (isLoading) {
|
|
655
570
|
if (LoadingComponent) {
|
|
656
|
-
return /* @__PURE__ */
|
|
571
|
+
return /* @__PURE__ */ jsx(LoadingComponent, {});
|
|
657
572
|
}
|
|
658
|
-
return /* @__PURE__ */
|
|
573
|
+
return /* @__PURE__ */ jsx("figure", { className, title: "Loading", children: /* @__PURE__ */ jsx("p", { className: "flex items-center justify-center p-4", children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }) });
|
|
659
574
|
}
|
|
660
575
|
if ((category || displayOnly) && fileReference) {
|
|
661
576
|
const isImage = fileReference.file_metadata.fileType?.startsWith("image/");
|
|
662
577
|
if (displayOnly && isImage && !showDelete && !enableChildren) {
|
|
663
578
|
if (imageError && showFallback) {
|
|
664
|
-
return /* @__PURE__ */
|
|
579
|
+
return /* @__PURE__ */ jsx("figure", { className, title: fileReference.file_metadata.fileName || "File", children: /* @__PURE__ */ jsx("p", { className: fallbackClasses, children: computedFallbackText }) });
|
|
665
580
|
}
|
|
666
581
|
if (!stableFileUrl) {
|
|
667
|
-
return /* @__PURE__ */
|
|
582
|
+
return /* @__PURE__ */ jsx("figure", { className: className || "max-w-full h-48", title: "Loading", children: /* @__PURE__ */ jsx("p", { className: fallbackClasses, children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }) });
|
|
668
583
|
}
|
|
669
|
-
return /* @__PURE__ */
|
|
584
|
+
return /* @__PURE__ */ jsx("figure", { className: className || "", children: /* @__PURE__ */ jsx(
|
|
670
585
|
"img",
|
|
671
586
|
{
|
|
672
587
|
ref: imgRef,
|
|
@@ -684,8 +599,8 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
684
599
|
if (displayOnly && !isImage && stableFileUrl && fileReference && !showDelete) {
|
|
685
600
|
const fileName = fileReference.file_metadata?.fileName || "Document";
|
|
686
601
|
const ariaLabel = `Open ${fileName} in new tab`;
|
|
687
|
-
return /* @__PURE__ */
|
|
688
|
-
/* @__PURE__ */
|
|
602
|
+
return /* @__PURE__ */ jsxs("figure", { className, children: [
|
|
603
|
+
/* @__PURE__ */ jsxs(
|
|
689
604
|
"a",
|
|
690
605
|
{
|
|
691
606
|
href: stableFileUrl || void 0,
|
|
@@ -694,15 +609,15 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
694
609
|
"aria-label": ariaLabel,
|
|
695
610
|
className: "flex items-center gap-2 p-3 bg-sec-50 border border-sec-200 rounded-lg hover:bg-sec-100 transition-colors text-main-600 hover:text-main-700 focus:outline-none focus:ring-2 focus:ring-main-500 focus:ring-offset-2",
|
|
696
611
|
children: [
|
|
697
|
-
/* @__PURE__ */
|
|
698
|
-
/* @__PURE__ */
|
|
699
|
-
/* @__PURE__ */
|
|
612
|
+
/* @__PURE__ */ jsx(FileText, { className: "size-5 shrink-0", "aria-hidden": "true" }),
|
|
613
|
+
/* @__PURE__ */ jsx("span", { className: "flex-1 font-medium truncate", children: fileName }),
|
|
614
|
+
/* @__PURE__ */ jsx(ExternalLink, { className: "size-5 shrink-0", "aria-hidden": "true" })
|
|
700
615
|
]
|
|
701
616
|
}
|
|
702
617
|
),
|
|
703
|
-
showMetadata && /* @__PURE__ */
|
|
704
|
-
/* @__PURE__ */
|
|
705
|
-
fileReference.file_metadata.fileSize && /* @__PURE__ */
|
|
618
|
+
showMetadata && /* @__PURE__ */ jsxs("figcaption", { children: [
|
|
619
|
+
/* @__PURE__ */ jsx("p", { children: fileName }),
|
|
620
|
+
fileReference.file_metadata.fileSize && /* @__PURE__ */ jsxs("p", { children: [
|
|
706
621
|
formatFileSize(fileReference.file_metadata.fileSize),
|
|
707
622
|
" \u2022 ",
|
|
708
623
|
fileReference.file_metadata.fileType
|
|
@@ -711,10 +626,10 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
711
626
|
] });
|
|
712
627
|
}
|
|
713
628
|
if (displayOnly && showFallback && (!stableFileUrl || imageError || !isImage)) {
|
|
714
|
-
return /* @__PURE__ */
|
|
629
|
+
return /* @__PURE__ */ jsx("figure", { className, title: fileReference.file_metadata.fileName || "File", children: /* @__PURE__ */ jsx("p", { className: fallbackClasses, children: computedFallbackText }) });
|
|
715
630
|
}
|
|
716
|
-
return /* @__PURE__ */
|
|
717
|
-
/* @__PURE__ */
|
|
631
|
+
return /* @__PURE__ */ jsx("figure", { className: `relative ${className}`, children: isImage && stableFileUrl && !imageError ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
632
|
+
/* @__PURE__ */ jsx(
|
|
718
633
|
"img",
|
|
719
634
|
{
|
|
720
635
|
src: stableFileUrl,
|
|
@@ -725,8 +640,8 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
725
640
|
},
|
|
726
641
|
fileReference.id
|
|
727
642
|
),
|
|
728
|
-
showDelete && /* @__PURE__ */
|
|
729
|
-
/* @__PURE__ */
|
|
643
|
+
showDelete && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
644
|
+
/* @__PURE__ */ jsx(
|
|
730
645
|
Button,
|
|
731
646
|
{
|
|
732
647
|
variant: "destructive",
|
|
@@ -738,19 +653,19 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
738
653
|
children: "\xD7"
|
|
739
654
|
}
|
|
740
655
|
),
|
|
741
|
-
/* @__PURE__ */
|
|
742
|
-
/* @__PURE__ */
|
|
743
|
-
/* @__PURE__ */
|
|
744
|
-
/* @__PURE__ */
|
|
745
|
-
/* @__PURE__ */
|
|
746
|
-
/* @__PURE__ */
|
|
656
|
+
/* @__PURE__ */ jsx(Dialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: /* @__PURE__ */ jsxs(DialogContent, { size: "sm", title: "Confirm Delete", children: [
|
|
657
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx("h2", { children: "Confirm Delete" }) }),
|
|
658
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsx("p", { children: "Are you sure you want to delete this file? This action cannot be undone." }) }),
|
|
659
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
660
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setDeleteDialogOpen(false), children: "Cancel" }),
|
|
661
|
+
/* @__PURE__ */ jsx(Button, { variant: "destructive", onClick: handleDeleteConfirm, children: "Delete" })
|
|
747
662
|
] })
|
|
748
663
|
] }) })
|
|
749
664
|
] }),
|
|
750
665
|
children,
|
|
751
|
-
showMetadata && /* @__PURE__ */
|
|
752
|
-
/* @__PURE__ */
|
|
753
|
-
(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && /* @__PURE__ */
|
|
666
|
+
showMetadata && /* @__PURE__ */ jsxs("figcaption", { children: [
|
|
667
|
+
/* @__PURE__ */ jsx("p", { children: fileReference.file_metadata.fileName || "Unknown file" }),
|
|
668
|
+
(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && /* @__PURE__ */ jsxs("p", { children: [
|
|
754
669
|
fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize),
|
|
755
670
|
fileReference.file_metadata.fileSize && fileReference.file_metadata.fileType && " \u2022 ",
|
|
756
671
|
fileReference.file_metadata.fileType
|
|
@@ -758,23 +673,23 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
758
673
|
] })
|
|
759
674
|
] }) : isImage && imageError && showFallback ? (
|
|
760
675
|
// Show fallback when image fails to load and fallback is enabled
|
|
761
|
-
/* @__PURE__ */
|
|
762
|
-
/* @__PURE__ */
|
|
676
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
677
|
+
/* @__PURE__ */ jsx("p", { className: fallbackClasses, title: fileReference.file_metadata.fileName || "File", children: computedFallbackText }),
|
|
763
678
|
children,
|
|
764
|
-
showMetadata && /* @__PURE__ */
|
|
765
|
-
/* @__PURE__ */
|
|
766
|
-
(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && /* @__PURE__ */
|
|
679
|
+
showMetadata && /* @__PURE__ */ jsxs("figcaption", { children: [
|
|
680
|
+
/* @__PURE__ */ jsx("p", { children: fileReference.file_metadata.fileName || "Unknown file" }),
|
|
681
|
+
(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && /* @__PURE__ */ jsxs("p", { children: [
|
|
767
682
|
fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize),
|
|
768
683
|
fileReference.file_metadata.fileSize && fileReference.file_metadata.fileType && " \u2022 ",
|
|
769
684
|
fileReference.file_metadata.fileType
|
|
770
685
|
] })
|
|
771
686
|
] })
|
|
772
687
|
] })
|
|
773
|
-
) : /* @__PURE__ */
|
|
774
|
-
/* @__PURE__ */
|
|
775
|
-
/* @__PURE__ */
|
|
776
|
-
showDelete && /* @__PURE__ */
|
|
777
|
-
/* @__PURE__ */
|
|
688
|
+
) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
689
|
+
/* @__PURE__ */ jsxs("p", { className: "flex items-center space-x-3 p-3 bg-sec-50 rounded-lg border border-sec-200", children: [
|
|
690
|
+
/* @__PURE__ */ jsx("span", { className: "text-2xl", children: getFileIcon(fileReference.file_metadata.fileType || "") }),
|
|
691
|
+
showDelete && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
692
|
+
/* @__PURE__ */ jsx(
|
|
778
693
|
Button,
|
|
779
694
|
{
|
|
780
695
|
variant: "destructive",
|
|
@@ -786,20 +701,20 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
786
701
|
children: "\xD7"
|
|
787
702
|
}
|
|
788
703
|
),
|
|
789
|
-
/* @__PURE__ */
|
|
790
|
-
/* @__PURE__ */
|
|
791
|
-
/* @__PURE__ */
|
|
792
|
-
/* @__PURE__ */
|
|
793
|
-
/* @__PURE__ */
|
|
794
|
-
/* @__PURE__ */
|
|
704
|
+
/* @__PURE__ */ jsx(Dialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: /* @__PURE__ */ jsxs(DialogContent, { size: "sm", title: "Confirm Delete", children: [
|
|
705
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx("h2", { children: "Confirm Delete" }) }),
|
|
706
|
+
/* @__PURE__ */ jsx(DialogBody, { children: /* @__PURE__ */ jsx("p", { children: "Are you sure you want to delete this file? This action cannot be undone." }) }),
|
|
707
|
+
/* @__PURE__ */ jsxs(DialogFooter, { children: [
|
|
708
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: () => setDeleteDialogOpen(false), children: "Cancel" }),
|
|
709
|
+
/* @__PURE__ */ jsx(Button, { variant: "destructive", onClick: handleDeleteConfirm, children: "Delete" })
|
|
795
710
|
] })
|
|
796
711
|
] }) })
|
|
797
712
|
] })
|
|
798
713
|
] }),
|
|
799
714
|
children,
|
|
800
|
-
showMetadata && /* @__PURE__ */
|
|
801
|
-
/* @__PURE__ */
|
|
802
|
-
(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && /* @__PURE__ */
|
|
715
|
+
showMetadata && /* @__PURE__ */ jsxs("figcaption", { children: [
|
|
716
|
+
/* @__PURE__ */ jsx("p", { children: fileReference.file_metadata.fileName || "Unknown file" }),
|
|
717
|
+
(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && /* @__PURE__ */ jsxs("p", { children: [
|
|
803
718
|
fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize),
|
|
804
719
|
fileReference.file_metadata.fileSize && fileReference.file_metadata.fileType && " \u2022 ",
|
|
805
720
|
fileReference.file_metadata.fileType
|
|
@@ -807,13 +722,13 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
807
722
|
] })
|
|
808
723
|
] }) });
|
|
809
724
|
}
|
|
810
|
-
return /* @__PURE__ */
|
|
725
|
+
return /* @__PURE__ */ jsxs("figure", { className: `space-y-2 ${className}`, children: [
|
|
811
726
|
fileReferences.map((fileRef) => {
|
|
812
727
|
const isImage = fileRef.file_metadata.fileType?.startsWith("image/");
|
|
813
728
|
const fileUrl2 = internalFileUrls.get(fileRef.id) || null;
|
|
814
729
|
const canDownload = !isImage && fileUrl2;
|
|
815
|
-
return /* @__PURE__ */
|
|
816
|
-
isImage && fileUrl2 ? /* @__PURE__ */
|
|
730
|
+
return /* @__PURE__ */ jsxs("figure", { className: "flex items-center space-x-3 p-3 bg-sec-50 rounded-lg border border-sec-200", children: [
|
|
731
|
+
isImage && fileUrl2 ? /* @__PURE__ */ jsx(
|
|
817
732
|
"img",
|
|
818
733
|
{
|
|
819
734
|
src: fileUrl2 || void 0,
|
|
@@ -823,10 +738,10 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
823
738
|
loading: "lazy"
|
|
824
739
|
},
|
|
825
740
|
fileRef.id
|
|
826
|
-
) : /* @__PURE__ */
|
|
827
|
-
showMetadata && /* @__PURE__ */
|
|
828
|
-
/* @__PURE__ */
|
|
829
|
-
(fileRef.file_metadata.fileSize || fileRef.file_metadata.fileType || fileRef.file_metadata.category) && /* @__PURE__ */
|
|
741
|
+
) : /* @__PURE__ */ jsx("span", { className: "text-2xl", children: getFileIcon(fileRef.file_metadata.fileType || "") }),
|
|
742
|
+
showMetadata && /* @__PURE__ */ jsxs("figcaption", { className: "flex-1 min-w-0", children: [
|
|
743
|
+
/* @__PURE__ */ jsx("p", { className: "font-medium text-sec-900 truncate", children: fileRef.file_metadata.fileName || "Unknown file" }),
|
|
744
|
+
(fileRef.file_metadata.fileSize || fileRef.file_metadata.fileType || fileRef.file_metadata.category) && /* @__PURE__ */ jsxs("p", { className: "text-sm text-sec-500", children: [
|
|
830
745
|
fileRef.file_metadata.fileSize && formatFileSize(fileRef.file_metadata.fileSize),
|
|
831
746
|
fileRef.file_metadata.fileSize && fileRef.file_metadata.fileType && " \u2022 ",
|
|
832
747
|
fileRef.file_metadata.fileType,
|
|
@@ -834,8 +749,8 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
834
749
|
fileRef.file_metadata.category
|
|
835
750
|
] })
|
|
836
751
|
] }),
|
|
837
|
-
/* @__PURE__ */
|
|
838
|
-
canDownload && /* @__PURE__ */
|
|
752
|
+
/* @__PURE__ */ jsxs("p", { className: "flex items-center space-x-2", children: [
|
|
753
|
+
canDownload && /* @__PURE__ */ jsx(
|
|
839
754
|
"a",
|
|
840
755
|
{
|
|
841
756
|
href: fileRef.file_path,
|
|
@@ -845,7 +760,7 @@ var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
|
845
760
|
children: "\u2193"
|
|
846
761
|
}
|
|
847
762
|
),
|
|
848
|
-
showDelete && onDelete && /* @__PURE__ */
|
|
763
|
+
showDelete && onDelete && /* @__PURE__ */ jsx(
|
|
849
764
|
Button,
|
|
850
765
|
{
|
|
851
766
|
variant: "destructive",
|
|
@@ -884,9 +799,26 @@ function FileDisplayPublic({
|
|
|
884
799
|
}) {
|
|
885
800
|
const publicPageContext = useContext(PublicPageContext);
|
|
886
801
|
const supabase = publicPageContext?.supabase ?? null;
|
|
802
|
+
const {
|
|
803
|
+
fileUrl,
|
|
804
|
+
fileReference,
|
|
805
|
+
fileReferences,
|
|
806
|
+
fileUrls,
|
|
807
|
+
fileCount,
|
|
808
|
+
isLoading,
|
|
809
|
+
error,
|
|
810
|
+
refetch
|
|
811
|
+
} = usePublicFileDisplay(
|
|
812
|
+
table_name,
|
|
813
|
+
record_id,
|
|
814
|
+
organisation_id,
|
|
815
|
+
category,
|
|
816
|
+
{ supabase }
|
|
817
|
+
// Type assertion needed due to type mismatch between contexts
|
|
818
|
+
);
|
|
887
819
|
if (!supabase) {
|
|
888
820
|
if (showFallback) {
|
|
889
|
-
return /* @__PURE__ */
|
|
821
|
+
return /* @__PURE__ */ jsx(
|
|
890
822
|
FileDisplayContent,
|
|
891
823
|
{
|
|
892
824
|
isLoading: false,
|
|
@@ -916,24 +848,8 @@ function FileDisplayPublic({
|
|
|
916
848
|
}
|
|
917
849
|
);
|
|
918
850
|
}
|
|
919
|
-
return /* @__PURE__ */
|
|
851
|
+
return /* @__PURE__ */ jsx("figure", { className, title: "Error", children: /* @__PURE__ */ jsx("p", { className: getFallbackClasses(fallbackSize || "md"), children: "Supabase client not available in public context" }) });
|
|
920
852
|
}
|
|
921
|
-
const {
|
|
922
|
-
fileUrl,
|
|
923
|
-
fileReference,
|
|
924
|
-
fileReferences,
|
|
925
|
-
fileUrls,
|
|
926
|
-
fileCount,
|
|
927
|
-
isLoading,
|
|
928
|
-
error,
|
|
929
|
-
refetch
|
|
930
|
-
} = usePublicFileDisplay(
|
|
931
|
-
table_name,
|
|
932
|
-
record_id,
|
|
933
|
-
organisation_id,
|
|
934
|
-
category,
|
|
935
|
-
{ supabase }
|
|
936
|
-
);
|
|
937
853
|
if (error) {
|
|
938
854
|
logger.error("FileDisplayPublic", "Error fetching file", {
|
|
939
855
|
table_name,
|
|
@@ -960,7 +876,7 @@ function FileDisplayPublic({
|
|
|
960
876
|
finalFileCount = 1;
|
|
961
877
|
finalFileUrl = fileUrls.get(targetFile.id) || null;
|
|
962
878
|
}
|
|
963
|
-
return /* @__PURE__ */
|
|
879
|
+
return /* @__PURE__ */ jsx(
|
|
964
880
|
FileDisplayContent,
|
|
965
881
|
{
|
|
966
882
|
isLoading,
|
|
@@ -1011,7 +927,7 @@ function FileDisplayAuthenticated({
|
|
|
1011
927
|
showMetadata
|
|
1012
928
|
}) {
|
|
1013
929
|
const { supabase } = useUnifiedAuth();
|
|
1014
|
-
const [displayOnlyFileReference, setDisplayOnlyFileReference] =
|
|
930
|
+
const [displayOnlyFileReference, setDisplayOnlyFileReference] = useState(null);
|
|
1015
931
|
const {
|
|
1016
932
|
fileUrl,
|
|
1017
933
|
fileReference,
|
|
@@ -1038,7 +954,7 @@ function FileDisplayAuthenticated({
|
|
|
1038
954
|
}
|
|
1039
955
|
);
|
|
1040
956
|
const displayOnlyFileUrl = displayOnlyFileUrlFromMap || displayOnlyFileUrlHook.url;
|
|
1041
|
-
|
|
957
|
+
useEffect(() => {
|
|
1042
958
|
if (displayOnly && !category && fileReferences.length > 0) {
|
|
1043
959
|
const imageFiles = fileReferences.filter(
|
|
1044
960
|
(f) => f.file_metadata.fileType?.startsWith("image/")
|
|
@@ -1050,7 +966,7 @@ function FileDisplayAuthenticated({
|
|
|
1050
966
|
}
|
|
1051
967
|
}, [displayOnly, category, fileReferences, fileUrls]);
|
|
1052
968
|
if (!supabase) {
|
|
1053
|
-
return /* @__PURE__ */
|
|
969
|
+
return /* @__PURE__ */ jsx("figure", { className, title: "Error", children: /* @__PURE__ */ jsx("p", { className: getFallbackClasses(fallbackSize || "md"), children: "Supabase client not available in authenticated context" }) });
|
|
1054
970
|
}
|
|
1055
971
|
const handleDelete = async () => {
|
|
1056
972
|
};
|
|
@@ -1070,7 +986,7 @@ function FileDisplayAuthenticated({
|
|
|
1070
986
|
finalError = error || displayOnlyFileUrlHook.error;
|
|
1071
987
|
}
|
|
1072
988
|
}
|
|
1073
|
-
return /* @__PURE__ */
|
|
989
|
+
return /* @__PURE__ */ jsx(
|
|
1074
990
|
FileDisplayContent,
|
|
1075
991
|
{
|
|
1076
992
|
isLoading: finalIsLoading,
|
|
@@ -1123,7 +1039,7 @@ function FileDisplay({
|
|
|
1123
1039
|
}) {
|
|
1124
1040
|
const isPublicPage = useIsPublicPage();
|
|
1125
1041
|
if (isPublicPage) {
|
|
1126
|
-
return /* @__PURE__ */
|
|
1042
|
+
return /* @__PURE__ */ jsx(
|
|
1127
1043
|
FileDisplayPublic,
|
|
1128
1044
|
{
|
|
1129
1045
|
table_name,
|
|
@@ -1147,7 +1063,7 @@ function FileDisplay({
|
|
|
1147
1063
|
}
|
|
1148
1064
|
);
|
|
1149
1065
|
}
|
|
1150
|
-
return /* @__PURE__ */
|
|
1066
|
+
return /* @__PURE__ */ jsx(
|
|
1151
1067
|
FileDisplayAuthenticated,
|
|
1152
1068
|
{
|
|
1153
1069
|
table_name,
|
|
@@ -1171,10 +1087,7 @@ function FileDisplay({
|
|
|
1171
1087
|
}
|
|
1172
1088
|
);
|
|
1173
1089
|
}
|
|
1174
|
-
|
|
1175
|
-
// src/hooks/useFileReference.ts
|
|
1176
|
-
import { useState as useState4, useCallback as useCallback4, useEffect as useEffect4, useRef as useRef4, useMemo as useMemo2 } from "react";
|
|
1177
|
-
var log2 = createLogger("useFileReference");
|
|
1090
|
+
createLogger("useFileReference");
|
|
1178
1091
|
var urlRefreshManager = {
|
|
1179
1092
|
subscriptions: /* @__PURE__ */ new Map(),
|
|
1180
1093
|
subscribe(key, callback) {
|
|
@@ -1206,10 +1119,10 @@ var urlRefreshManager = {
|
|
|
1206
1119
|
}
|
|
1207
1120
|
};
|
|
1208
1121
|
function useFileReference(supabase) {
|
|
1209
|
-
const [isLoading, setIsLoading] =
|
|
1210
|
-
const [error, setError] =
|
|
1211
|
-
const service =
|
|
1212
|
-
const uploadFile =
|
|
1122
|
+
const [isLoading, setIsLoading] = useState(false);
|
|
1123
|
+
const [error, setError] = useState(null);
|
|
1124
|
+
const service = useMemo(() => createFileReferenceService(supabase), [supabase]);
|
|
1125
|
+
const uploadFile = useCallback(async (options, file) => {
|
|
1213
1126
|
setIsLoading(true);
|
|
1214
1127
|
setError(null);
|
|
1215
1128
|
try {
|
|
@@ -1223,7 +1136,7 @@ function useFileReference(supabase) {
|
|
|
1223
1136
|
setIsLoading(false);
|
|
1224
1137
|
}
|
|
1225
1138
|
}, [supabase]);
|
|
1226
|
-
const getFileReference =
|
|
1139
|
+
const getFileReference = useCallback(async (table_name, record_id, organisation_id) => {
|
|
1227
1140
|
setIsLoading(true);
|
|
1228
1141
|
setError(null);
|
|
1229
1142
|
try {
|
|
@@ -1236,7 +1149,7 @@ function useFileReference(supabase) {
|
|
|
1236
1149
|
setIsLoading(false);
|
|
1237
1150
|
}
|
|
1238
1151
|
}, [service]);
|
|
1239
|
-
const getFileUrl =
|
|
1152
|
+
const getFileUrl = useCallback(async (table_name, record_id, organisation_id) => {
|
|
1240
1153
|
setIsLoading(true);
|
|
1241
1154
|
setError(null);
|
|
1242
1155
|
try {
|
|
@@ -1249,7 +1162,7 @@ function useFileReference(supabase) {
|
|
|
1249
1162
|
setIsLoading(false);
|
|
1250
1163
|
}
|
|
1251
1164
|
}, [service]);
|
|
1252
|
-
const getSignedUrl3 =
|
|
1165
|
+
const getSignedUrl3 = useCallback(async (table_name, record_id, organisation_id, expires_in) => {
|
|
1253
1166
|
setIsLoading(true);
|
|
1254
1167
|
setError(null);
|
|
1255
1168
|
try {
|
|
@@ -1262,7 +1175,7 @@ function useFileReference(supabase) {
|
|
|
1262
1175
|
setIsLoading(false);
|
|
1263
1176
|
}
|
|
1264
1177
|
}, [service]);
|
|
1265
|
-
const updateFileReference =
|
|
1178
|
+
const updateFileReference = useCallback(async (id, updates) => {
|
|
1266
1179
|
setIsLoading(true);
|
|
1267
1180
|
setError(null);
|
|
1268
1181
|
try {
|
|
@@ -1275,7 +1188,7 @@ function useFileReference(supabase) {
|
|
|
1275
1188
|
setIsLoading(false);
|
|
1276
1189
|
}
|
|
1277
1190
|
}, [service]);
|
|
1278
|
-
const deleteFileReference =
|
|
1191
|
+
const deleteFileReference = useCallback(async (table_name, record_id, organisation_id, delete_file) => {
|
|
1279
1192
|
setIsLoading(true);
|
|
1280
1193
|
setError(null);
|
|
1281
1194
|
try {
|
|
@@ -1288,7 +1201,7 @@ function useFileReference(supabase) {
|
|
|
1288
1201
|
setIsLoading(false);
|
|
1289
1202
|
}
|
|
1290
1203
|
}, [service]);
|
|
1291
|
-
const listFileReferences =
|
|
1204
|
+
const listFileReferences = useCallback(async (table_name, record_id, organisation_id) => {
|
|
1292
1205
|
setIsLoading(true);
|
|
1293
1206
|
setError(null);
|
|
1294
1207
|
try {
|
|
@@ -1301,7 +1214,7 @@ function useFileReference(supabase) {
|
|
|
1301
1214
|
setIsLoading(false);
|
|
1302
1215
|
}
|
|
1303
1216
|
}, [service]);
|
|
1304
|
-
const getFileCount =
|
|
1217
|
+
const getFileCount = useCallback(async (table_name, record_id, organisation_id) => {
|
|
1305
1218
|
setIsLoading(true);
|
|
1306
1219
|
setError(null);
|
|
1307
1220
|
try {
|
|
@@ -1314,7 +1227,7 @@ function useFileReference(supabase) {
|
|
|
1314
1227
|
setIsLoading(false);
|
|
1315
1228
|
}
|
|
1316
1229
|
}, [service]);
|
|
1317
|
-
const getFileReferenceById =
|
|
1230
|
+
const getFileReferenceById = useCallback(async (id, organisation_id) => {
|
|
1318
1231
|
setIsLoading(true);
|
|
1319
1232
|
setError(null);
|
|
1320
1233
|
try {
|
|
@@ -1327,7 +1240,7 @@ function useFileReference(supabase) {
|
|
|
1327
1240
|
setIsLoading(false);
|
|
1328
1241
|
}
|
|
1329
1242
|
}, [service]);
|
|
1330
|
-
const getFilesByCategory =
|
|
1243
|
+
const getFilesByCategory = useCallback(async (table_name, record_id, category, organisation_id) => {
|
|
1331
1244
|
setIsLoading(true);
|
|
1332
1245
|
setError(null);
|
|
1333
1246
|
try {
|
|
@@ -1340,7 +1253,7 @@ function useFileReference(supabase) {
|
|
|
1340
1253
|
setIsLoading(false);
|
|
1341
1254
|
}
|
|
1342
1255
|
}, [service]);
|
|
1343
|
-
const clearError =
|
|
1256
|
+
const clearError = useCallback(() => {
|
|
1344
1257
|
setError(null);
|
|
1345
1258
|
}, []);
|
|
1346
1259
|
return {
|
|
@@ -1371,32 +1284,32 @@ function useFileReferenceForRecord(supabase, table_name, record_id, organisation
|
|
|
1371
1284
|
getFileCount,
|
|
1372
1285
|
clearError
|
|
1373
1286
|
} = useFileReference(supabase);
|
|
1374
|
-
const [fileUrl, setFileUrl] =
|
|
1375
|
-
const [fileReference, setFileReference] =
|
|
1376
|
-
const [fileReferences, setFileReferences] =
|
|
1377
|
-
const [fileCount, setFileCount] =
|
|
1378
|
-
const refreshSubscriptionRef =
|
|
1379
|
-
const loadFileReference =
|
|
1287
|
+
const [fileUrl, setFileUrl] = useState(null);
|
|
1288
|
+
const [fileReference, setFileReference] = useState(null);
|
|
1289
|
+
const [fileReferences, setFileReferences] = useState([]);
|
|
1290
|
+
const [fileCount, setFileCount] = useState(0);
|
|
1291
|
+
const refreshSubscriptionRef = useRef(null);
|
|
1292
|
+
const loadFileReference = useCallback(async () => {
|
|
1380
1293
|
const reference = await getFileReference(table_name, record_id, organisation_id);
|
|
1381
1294
|
setFileReference(reference);
|
|
1382
1295
|
return reference;
|
|
1383
1296
|
}, [getFileReference, table_name, record_id, organisation_id]);
|
|
1384
|
-
const loadFileUrl =
|
|
1297
|
+
const loadFileUrl = useCallback(async () => {
|
|
1385
1298
|
const url = await getFileUrl(table_name, record_id, organisation_id);
|
|
1386
1299
|
setFileUrl(url);
|
|
1387
1300
|
return url;
|
|
1388
1301
|
}, [getFileUrl, table_name, record_id, organisation_id]);
|
|
1389
|
-
const loadFileReferences =
|
|
1302
|
+
const loadFileReferences = useCallback(async () => {
|
|
1390
1303
|
const references = await listFileReferences(table_name, record_id, organisation_id);
|
|
1391
1304
|
setFileReferences(references);
|
|
1392
1305
|
return references;
|
|
1393
1306
|
}, [listFileReferences, table_name, record_id, organisation_id]);
|
|
1394
|
-
const loadFileCount =
|
|
1307
|
+
const loadFileCount = useCallback(async () => {
|
|
1395
1308
|
const count = await getFileCount(table_name, record_id, organisation_id);
|
|
1396
1309
|
setFileCount(count);
|
|
1397
1310
|
return count;
|
|
1398
1311
|
}, [getFileCount, table_name, record_id, organisation_id]);
|
|
1399
|
-
const deleteFile =
|
|
1312
|
+
const deleteFile = useCallback(async (delete_file) => {
|
|
1400
1313
|
const success = await deleteFileReference(table_name, record_id, organisation_id, delete_file);
|
|
1401
1314
|
if (success) {
|
|
1402
1315
|
setFileReference(null);
|
|
@@ -1405,7 +1318,7 @@ function useFileReferenceForRecord(supabase, table_name, record_id, organisation
|
|
|
1405
1318
|
}
|
|
1406
1319
|
return success;
|
|
1407
1320
|
}, [deleteFileReference, table_name, record_id, organisation_id, loadFileCount]);
|
|
1408
|
-
|
|
1321
|
+
useEffect(() => {
|
|
1409
1322
|
if (refreshSubscriptionRef.current) {
|
|
1410
1323
|
refreshSubscriptionRef.current();
|
|
1411
1324
|
refreshSubscriptionRef.current = null;
|
|
@@ -1447,9 +1360,9 @@ function useFileReferenceById(supabase, fileReferenceId, organisationId) {
|
|
|
1447
1360
|
getFileReferenceById,
|
|
1448
1361
|
clearError
|
|
1449
1362
|
} = useFileReference(supabase);
|
|
1450
|
-
const [fileReference, setFileReference] =
|
|
1451
|
-
const [fileUrl, setFileUrl] =
|
|
1452
|
-
const loadFileReference =
|
|
1363
|
+
const [fileReference, setFileReference] = useState(null);
|
|
1364
|
+
const [fileUrl, setFileUrl] = useState(null);
|
|
1365
|
+
const loadFileReference = useCallback(async () => {
|
|
1453
1366
|
if (!fileReferenceId || !organisationId) {
|
|
1454
1367
|
setFileReference(null);
|
|
1455
1368
|
setFileUrl(null);
|
|
@@ -1459,10 +1372,10 @@ function useFileReferenceById(supabase, fileReferenceId, organisationId) {
|
|
|
1459
1372
|
setFileReference(reference);
|
|
1460
1373
|
return reference;
|
|
1461
1374
|
}, [getFileReferenceById, fileReferenceId, organisationId]);
|
|
1462
|
-
|
|
1375
|
+
useEffect(() => {
|
|
1463
1376
|
loadFileReference();
|
|
1464
1377
|
}, [loadFileReference]);
|
|
1465
|
-
|
|
1378
|
+
useEffect(() => {
|
|
1466
1379
|
if (!fileReference || !fileReferenceId || !organisationId) {
|
|
1467
1380
|
setFileUrl(null);
|
|
1468
1381
|
return;
|
|
@@ -1498,9 +1411,9 @@ function useFilesByCategory(supabase, table_name, record_id, category, organisat
|
|
|
1498
1411
|
getFilesByCategory,
|
|
1499
1412
|
clearError
|
|
1500
1413
|
} = useFileReference(supabase);
|
|
1501
|
-
const [fileReferences, setFileReferences] =
|
|
1502
|
-
const [fileUrls, setFileUrls] =
|
|
1503
|
-
const loadFiles =
|
|
1414
|
+
const [fileReferences, setFileReferences] = useState([]);
|
|
1415
|
+
const [fileUrls, setFileUrls] = useState(/* @__PURE__ */ new Map());
|
|
1416
|
+
const loadFiles = useCallback(async () => {
|
|
1504
1417
|
if (!category || !organisation_id) {
|
|
1505
1418
|
setFileReferences([]);
|
|
1506
1419
|
setFileUrls(/* @__PURE__ */ new Map());
|
|
@@ -1516,7 +1429,7 @@ function useFilesByCategory(supabase, table_name, record_id, category, organisat
|
|
|
1516
1429
|
setFileUrls(urlMap);
|
|
1517
1430
|
return files;
|
|
1518
1431
|
}, [table_name, record_id, category, organisation_id, supabase, getFilesByCategory]);
|
|
1519
|
-
|
|
1432
|
+
useEffect(() => {
|
|
1520
1433
|
loadFiles();
|
|
1521
1434
|
}, [loadFiles]);
|
|
1522
1435
|
return {
|
|
@@ -1528,10 +1441,6 @@ function useFilesByCategory(supabase, table_name, record_id, category, organisat
|
|
|
1528
1441
|
clearError
|
|
1529
1442
|
};
|
|
1530
1443
|
}
|
|
1531
|
-
|
|
1532
|
-
// src/components/Avatar/Avatar.tsx
|
|
1533
|
-
import * as React4 from "react";
|
|
1534
|
-
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1535
1444
|
var sizeClasses = {
|
|
1536
1445
|
xs: "size-4 text-xs",
|
|
1537
1446
|
sm: "size-6 text-sm",
|
|
@@ -1540,7 +1449,7 @@ var sizeClasses = {
|
|
|
1540
1449
|
xl: "size-16 text-xl",
|
|
1541
1450
|
"2xl": "size-20 text-2xl"
|
|
1542
1451
|
};
|
|
1543
|
-
var Avatar =
|
|
1452
|
+
var Avatar = React7.forwardRef(
|
|
1544
1453
|
({
|
|
1545
1454
|
table_name,
|
|
1546
1455
|
record_id,
|
|
@@ -1554,7 +1463,7 @@ var Avatar = React4.forwardRef(
|
|
|
1554
1463
|
size = "md",
|
|
1555
1464
|
...props
|
|
1556
1465
|
}, ref) => {
|
|
1557
|
-
const [imageError, setImageError] =
|
|
1466
|
+
const [imageError, setImageError] = React7.useState(false);
|
|
1558
1467
|
const { supabase } = useUnifiedAuth();
|
|
1559
1468
|
const canFetchFileId = Boolean(fileId && organisation_id && supabase);
|
|
1560
1469
|
const { fileReference, fileUrl: fileIdUrl, isLoading: fileIdLoading } = useFileReferenceById(
|
|
@@ -1571,23 +1480,23 @@ var Avatar = React4.forwardRef(
|
|
|
1571
1480
|
const fallbackClasses = "size-full grid place-items-center text-center text-sec-50 bg-sec-500";
|
|
1572
1481
|
const imageClasses = "object-cover size-full";
|
|
1573
1482
|
const containerClasses = cn(baseClasses, className);
|
|
1574
|
-
const handleImageError =
|
|
1483
|
+
const handleImageError = React7.useCallback(() => {
|
|
1575
1484
|
setImageError(true);
|
|
1576
1485
|
}, []);
|
|
1577
|
-
|
|
1486
|
+
React7.useEffect(() => {
|
|
1578
1487
|
if (src) {
|
|
1579
1488
|
setImageError(false);
|
|
1580
1489
|
}
|
|
1581
1490
|
}, [src]);
|
|
1582
|
-
return /* @__PURE__ */
|
|
1491
|
+
return /* @__PURE__ */ jsx(
|
|
1583
1492
|
"figure",
|
|
1584
1493
|
{
|
|
1585
1494
|
ref,
|
|
1586
1495
|
className: containerClasses,
|
|
1587
1496
|
...props,
|
|
1588
|
-
children: showFallback ? /* @__PURE__ */
|
|
1497
|
+
children: showFallback ? /* @__PURE__ */ jsx("figcaption", { className: fallbackClasses, "aria-label": alt || fallback, children: fallback }) : hasFileProps ? (
|
|
1589
1498
|
// File reference props approach - use FileDisplay
|
|
1590
|
-
/* @__PURE__ */
|
|
1499
|
+
/* @__PURE__ */ jsx(
|
|
1591
1500
|
FileDisplay,
|
|
1592
1501
|
{
|
|
1593
1502
|
table_name,
|
|
@@ -1602,7 +1511,7 @@ var Avatar = React4.forwardRef(
|
|
|
1602
1511
|
)
|
|
1603
1512
|
) : hasFileId && fileIdUrl ? (
|
|
1604
1513
|
// File ID approach - use img tag with fetched URL
|
|
1605
|
-
/* @__PURE__ */
|
|
1514
|
+
/* @__PURE__ */ jsx(
|
|
1606
1515
|
"img",
|
|
1607
1516
|
{
|
|
1608
1517
|
src: fileIdUrl,
|
|
@@ -1613,7 +1522,7 @@ var Avatar = React4.forwardRef(
|
|
|
1613
1522
|
)
|
|
1614
1523
|
) : hasDirectUrl ? (
|
|
1615
1524
|
// Direct URL approach - use img tag
|
|
1616
|
-
/* @__PURE__ */
|
|
1525
|
+
/* @__PURE__ */ jsx(
|
|
1617
1526
|
"img",
|
|
1618
1527
|
{
|
|
1619
1528
|
src,
|
|
@@ -1624,16 +1533,13 @@ var Avatar = React4.forwardRef(
|
|
|
1624
1533
|
)
|
|
1625
1534
|
) : (
|
|
1626
1535
|
// Fallback if nothing else works
|
|
1627
|
-
/* @__PURE__ */
|
|
1536
|
+
/* @__PURE__ */ jsx("figcaption", { className: fallbackClasses, "aria-label": alt || fallback, children: fallback })
|
|
1628
1537
|
)
|
|
1629
1538
|
}
|
|
1630
1539
|
);
|
|
1631
1540
|
}
|
|
1632
1541
|
);
|
|
1633
1542
|
Avatar.displayName = "Avatar";
|
|
1634
|
-
|
|
1635
|
-
// src/components/Badge/Badge.tsx
|
|
1636
|
-
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1637
1543
|
var shadeConfig = {
|
|
1638
1544
|
muted: {
|
|
1639
1545
|
bg: 200,
|
|
@@ -1707,7 +1613,7 @@ function Badge({ className, variant = "solid-main-normal", ref, ...props }) {
|
|
|
1707
1613
|
const classesWithoutShadows = variantClasses.replace(/\bshadow-badge-soft\b/g, "").replace(/\bshadow-\w+-\d+\b/g, "").replace(/\s+/g, " ").trim();
|
|
1708
1614
|
const mergedClasses = cn(classesWithoutShadows, className);
|
|
1709
1615
|
const finalClasses = `${mergedClasses} shadow-badge-soft ${shadowColorClass}`.trim();
|
|
1710
|
-
return /* @__PURE__ */
|
|
1616
|
+
return /* @__PURE__ */ jsx(
|
|
1711
1617
|
"span",
|
|
1712
1618
|
{
|
|
1713
1619
|
ref,
|
|
@@ -1716,7 +1622,7 @@ function Badge({ className, variant = "solid-main-normal", ref, ...props }) {
|
|
|
1716
1622
|
}
|
|
1717
1623
|
);
|
|
1718
1624
|
}
|
|
1719
|
-
return /* @__PURE__ */
|
|
1625
|
+
return /* @__PURE__ */ jsx(
|
|
1720
1626
|
"span",
|
|
1721
1627
|
{
|
|
1722
1628
|
ref,
|
|
@@ -1726,12 +1632,7 @@ function Badge({ className, variant = "solid-main-normal", ref, ...props }) {
|
|
|
1726
1632
|
);
|
|
1727
1633
|
}
|
|
1728
1634
|
Badge.displayName = "Badge";
|
|
1729
|
-
|
|
1730
|
-
// src/components/Switch/Switch.tsx
|
|
1731
|
-
import * as React5 from "react";
|
|
1732
|
-
import * as SwitchPrimitive from "@radix-ui/react-switch";
|
|
1733
|
-
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1734
|
-
var Switch = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx7(
|
|
1635
|
+
var Switch = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
1735
1636
|
SwitchPrimitive.Root,
|
|
1736
1637
|
{
|
|
1737
1638
|
className: cn(
|
|
@@ -1753,7 +1654,7 @@ var Switch = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
1753
1654
|
),
|
|
1754
1655
|
...props,
|
|
1755
1656
|
ref,
|
|
1756
|
-
children: /* @__PURE__ */
|
|
1657
|
+
children: /* @__PURE__ */ jsx(
|
|
1757
1658
|
SwitchPrimitive.Thumb,
|
|
1758
1659
|
{
|
|
1759
1660
|
className: cn(
|
|
@@ -1772,14 +1673,9 @@ var Switch = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
1772
1673
|
}
|
|
1773
1674
|
));
|
|
1774
1675
|
Switch.displayName = SwitchPrimitive.Root.displayName;
|
|
1775
|
-
|
|
1776
|
-
// src/components/Tabs/Tabs.tsx
|
|
1777
|
-
import * as React6 from "react";
|
|
1778
|
-
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
1779
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1780
|
-
var Tabs = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx8(TabsPrimitive.Root, { asChild: true, ...props, children: /* @__PURE__ */ jsx8("section", { ref, className, children }) }));
|
|
1676
|
+
var Tabs = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(TabsPrimitive.Root, { asChild: true, ...props, children: /* @__PURE__ */ jsx("section", { ref, className, children }) }));
|
|
1781
1677
|
Tabs.displayName = TabsPrimitive.Root.displayName || "Tabs";
|
|
1782
|
-
var TabsList =
|
|
1678
|
+
var TabsList = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(TabsPrimitive.List, { asChild: true, ...props, children: /* @__PURE__ */ jsx(
|
|
1783
1679
|
"nav",
|
|
1784
1680
|
{
|
|
1785
1681
|
ref,
|
|
@@ -1791,8 +1687,8 @@ var TabsList = React6.forwardRef(({ className, children, ...props }, ref) => /*
|
|
|
1791
1687
|
}
|
|
1792
1688
|
) }));
|
|
1793
1689
|
TabsList.displayName = TabsPrimitive.List.displayName || "TabsList";
|
|
1794
|
-
var TabsTrigger =
|
|
1795
|
-
return /* @__PURE__ */
|
|
1690
|
+
var TabsTrigger = React7.forwardRef(({ className, variant, size, children, ...props }, ref) => {
|
|
1691
|
+
return /* @__PURE__ */ jsx(TabsPrimitive.Trigger, { asChild: true, ...props, children: /* @__PURE__ */ jsx(
|
|
1796
1692
|
Button,
|
|
1797
1693
|
{
|
|
1798
1694
|
ref,
|
|
@@ -1810,7 +1706,7 @@ var TabsTrigger = React6.forwardRef(({ className, variant, size, children, ...pr
|
|
|
1810
1706
|
) });
|
|
1811
1707
|
});
|
|
1812
1708
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName || "TabsTrigger";
|
|
1813
|
-
var TabsContent =
|
|
1709
|
+
var TabsContent = React7.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx(TabsPrimitive.Content, { asChild: true, ...props, children: /* @__PURE__ */ jsx(
|
|
1814
1710
|
"aside",
|
|
1815
1711
|
{
|
|
1816
1712
|
ref,
|
|
@@ -1822,15 +1718,6 @@ var TabsContent = React6.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
1822
1718
|
}
|
|
1823
1719
|
) }));
|
|
1824
1720
|
TabsContent.displayName = TabsPrimitive.Content.displayName || "TabsContent";
|
|
1825
|
-
|
|
1826
|
-
// src/components/Calendar/Calendar.tsx
|
|
1827
|
-
import * as React7 from "react";
|
|
1828
|
-
import {
|
|
1829
|
-
DayPicker,
|
|
1830
|
-
useDayPicker
|
|
1831
|
-
} from "react-day-picker";
|
|
1832
|
-
import { enAU } from "date-fns/locale";
|
|
1833
|
-
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1834
1721
|
var assignToRef = (ref, value) => {
|
|
1835
1722
|
if (!ref) {
|
|
1836
1723
|
return;
|
|
@@ -1896,15 +1783,15 @@ var Calendar = React7.forwardRef(
|
|
|
1896
1783
|
rootRef: dayPickerRootRef,
|
|
1897
1784
|
restProps
|
|
1898
1785
|
};
|
|
1899
|
-
return /* @__PURE__ */
|
|
1786
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1900
1787
|
});
|
|
1901
1788
|
CustomRoot.displayName = "CustomRoot";
|
|
1902
1789
|
const CustomMonths = React7.memo(({ children }) => {
|
|
1903
|
-
return /* @__PURE__ */
|
|
1790
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
1904
1791
|
});
|
|
1905
1792
|
CustomMonths.displayName = "CustomMonths";
|
|
1906
1793
|
const CustomMonthGrid = React7.forwardRef((props2, forwardedRef) => {
|
|
1907
|
-
return /* @__PURE__ */
|
|
1794
|
+
return /* @__PURE__ */ jsx("table", { ref: forwardedRef, ...props2 });
|
|
1908
1795
|
});
|
|
1909
1796
|
CustomMonthGrid.displayName = "CustomMonthGrid";
|
|
1910
1797
|
const CustomMonth = React7.memo(({ calendarMonth, displayIndex, className: className2, children }) => {
|
|
@@ -1917,7 +1804,7 @@ var Calendar = React7.forwardRef(
|
|
|
1917
1804
|
const childType = child.type;
|
|
1918
1805
|
return typeof childType === "function" && childType.displayName === "MonthGrid" || child.type === "table";
|
|
1919
1806
|
});
|
|
1920
|
-
return /* @__PURE__ */
|
|
1807
|
+
return /* @__PURE__ */ jsx(Fragment, { children: childrenArray.map((child, index) => {
|
|
1921
1808
|
if (React7.isValidElement(child) && child.type?.displayName === "MonthCaption") {
|
|
1922
1809
|
return null;
|
|
1923
1810
|
}
|
|
@@ -1978,9 +1865,9 @@ var Calendar = React7.forwardRef(
|
|
|
1978
1865
|
...tableProps,
|
|
1979
1866
|
...mergedRef ? { ref: mergedRef } : {}
|
|
1980
1867
|
},
|
|
1981
|
-
/* @__PURE__ */
|
|
1982
|
-
/* @__PURE__ */
|
|
1983
|
-
/* @__PURE__ */
|
|
1868
|
+
/* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1869
|
+
/* @__PURE__ */ jsx("caption", { className: "relative", children: /* @__PURE__ */ jsxs("nav", { className: "relative flex items-center justify-center gap-1", children: [
|
|
1870
|
+
/* @__PURE__ */ jsx(
|
|
1984
1871
|
"button",
|
|
1985
1872
|
{
|
|
1986
1873
|
type: "button",
|
|
@@ -1997,11 +1884,11 @@ var Calendar = React7.forwardRef(
|
|
|
1997
1884
|
"aria-label": previousMonth ? labels.labelPrevious(previousMonth) : void 0,
|
|
1998
1885
|
onClick: handlePreviousClick,
|
|
1999
1886
|
disabled: !previousMonth,
|
|
2000
|
-
children: Chevron ? /* @__PURE__ */
|
|
1887
|
+
children: Chevron ? /* @__PURE__ */ jsx(Chevron, { orientation: "left", className: "size-4", disabled: !previousMonth }) : /* @__PURE__ */ jsx("span", { children: "\u2039" })
|
|
2001
1888
|
}
|
|
2002
1889
|
),
|
|
2003
|
-
/* @__PURE__ */
|
|
2004
|
-
/* @__PURE__ */
|
|
1890
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: caption }),
|
|
1891
|
+
/* @__PURE__ */ jsx(
|
|
2005
1892
|
"button",
|
|
2006
1893
|
{
|
|
2007
1894
|
type: "button",
|
|
@@ -2018,7 +1905,7 @@ var Calendar = React7.forwardRef(
|
|
|
2018
1905
|
"aria-label": nextMonth ? labels.labelNext(nextMonth) : void 0,
|
|
2019
1906
|
onClick: handleNextClick,
|
|
2020
1907
|
disabled: !nextMonth,
|
|
2021
|
-
children: Chevron ? /* @__PURE__ */
|
|
1908
|
+
children: Chevron ? /* @__PURE__ */ jsx(Chevron, { orientation: "right", className: "size-4", disabled: !nextMonth }) : /* @__PURE__ */ jsx("span", { children: "\u203A" })
|
|
2022
1909
|
}
|
|
2023
1910
|
)
|
|
2024
1911
|
] }) }),
|
|
@@ -2031,7 +1918,7 @@ var Calendar = React7.forwardRef(
|
|
|
2031
1918
|
});
|
|
2032
1919
|
CustomMonth.displayName = "CustomMonth";
|
|
2033
1920
|
const CustomWeekdays = React7.memo(({ className: className2, children, ...props2 }) => {
|
|
2034
|
-
return /* @__PURE__ */
|
|
1921
|
+
return /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { className: cn("text-xs text-sec-500", className2), ...props2, children }) });
|
|
2035
1922
|
});
|
|
2036
1923
|
CustomWeekdays.displayName = "CustomWeekdays";
|
|
2037
1924
|
const defaultComponents = React7.useMemo(() => ({
|
|
@@ -2044,7 +1931,7 @@ var Calendar = React7.forwardRef(
|
|
|
2044
1931
|
// Spread user components AFTER ours so ours take precedence
|
|
2045
1932
|
...components || {}
|
|
2046
1933
|
}), [components, CustomRoot, CustomMonths, CustomMonth, CustomWeekdays]);
|
|
2047
|
-
return /* @__PURE__ */
|
|
1934
|
+
return /* @__PURE__ */ jsx(
|
|
2048
1935
|
DayPicker,
|
|
2049
1936
|
{
|
|
2050
1937
|
...mode ? { mode } : {},
|
|
@@ -2120,14 +2007,8 @@ var Calendar = React7.forwardRef(
|
|
|
2120
2007
|
}
|
|
2121
2008
|
);
|
|
2122
2009
|
Calendar.displayName = "Calendar";
|
|
2123
|
-
|
|
2124
|
-
// src/components/Toast/Toast.tsx
|
|
2125
|
-
import * as React8 from "react";
|
|
2126
|
-
import * as ToastPrimitives from "@radix-ui/react-toast";
|
|
2127
|
-
import { X } from "lucide-react";
|
|
2128
|
-
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2129
2010
|
var ToastProvider = ToastPrimitives.Provider;
|
|
2130
|
-
var ToastViewport =
|
|
2011
|
+
var ToastViewport = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2131
2012
|
ToastPrimitives.Viewport,
|
|
2132
2013
|
{
|
|
2133
2014
|
ref,
|
|
@@ -2140,8 +2021,8 @@ var ToastViewport = React8.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
2140
2021
|
}
|
|
2141
2022
|
));
|
|
2142
2023
|
ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
|
|
2143
|
-
var Toast =
|
|
2144
|
-
return /* @__PURE__ */
|
|
2024
|
+
var Toast = React7.forwardRef(({ className, ...props }, ref) => {
|
|
2025
|
+
return /* @__PURE__ */ jsx(
|
|
2145
2026
|
ToastPrimitives.Root,
|
|
2146
2027
|
{
|
|
2147
2028
|
ref,
|
|
@@ -2155,7 +2036,7 @@ var Toast = React8.forwardRef(({ className, ...props }, ref) => {
|
|
|
2155
2036
|
);
|
|
2156
2037
|
});
|
|
2157
2038
|
Toast.displayName = ToastPrimitives.Root.displayName;
|
|
2158
|
-
var ToastAction =
|
|
2039
|
+
var ToastAction = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2159
2040
|
ToastPrimitives.Action,
|
|
2160
2041
|
{
|
|
2161
2042
|
ref,
|
|
@@ -2168,7 +2049,7 @@ var ToastAction = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
2168
2049
|
}
|
|
2169
2050
|
));
|
|
2170
2051
|
ToastAction.displayName = ToastPrimitives.Action.displayName;
|
|
2171
|
-
var ToastClose =
|
|
2052
|
+
var ToastClose = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2172
2053
|
ToastPrimitives.Close,
|
|
2173
2054
|
{
|
|
2174
2055
|
ref,
|
|
@@ -2179,11 +2060,11 @@ var ToastClose = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
2179
2060
|
),
|
|
2180
2061
|
"toast-close": "",
|
|
2181
2062
|
...props,
|
|
2182
|
-
children: /* @__PURE__ */
|
|
2063
|
+
children: /* @__PURE__ */ jsx(X, { className: "size-4" })
|
|
2183
2064
|
}
|
|
2184
2065
|
));
|
|
2185
2066
|
ToastClose.displayName = ToastPrimitives.Close.displayName;
|
|
2186
|
-
var ToastTitle =
|
|
2067
|
+
var ToastTitle = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2187
2068
|
ToastPrimitives.Title,
|
|
2188
2069
|
{
|
|
2189
2070
|
ref,
|
|
@@ -2193,7 +2074,7 @@ var ToastTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
2193
2074
|
}
|
|
2194
2075
|
));
|
|
2195
2076
|
ToastTitle.displayName = ToastPrimitives.Title.displayName;
|
|
2196
|
-
var ToastDescription =
|
|
2077
|
+
var ToastDescription = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
2197
2078
|
ToastPrimitives.Description,
|
|
2198
2079
|
{
|
|
2199
2080
|
ref,
|
|
@@ -2205,24 +2086,19 @@ var ToastDescription = React8.forwardRef(({ className, ...props }, ref) => /* @_
|
|
|
2205
2086
|
ToastDescription.displayName = ToastPrimitives.Description.displayName;
|
|
2206
2087
|
function Toaster() {
|
|
2207
2088
|
const { toasts } = useToast();
|
|
2208
|
-
return /* @__PURE__ */
|
|
2209
|
-
/* @__PURE__ */
|
|
2089
|
+
return /* @__PURE__ */ jsxs(ToastProvider, { "data-testid": "toast-provider", children: [
|
|
2090
|
+
/* @__PURE__ */ jsx(ToastViewport, {}),
|
|
2210
2091
|
toasts.map((toast) => {
|
|
2211
2092
|
const { id, title, description, action, dismiss, duration, ...toastProps } = toast;
|
|
2212
|
-
return /* @__PURE__ */
|
|
2213
|
-
title && /* @__PURE__ */
|
|
2214
|
-
description && /* @__PURE__ */
|
|
2093
|
+
return /* @__PURE__ */ jsxs(Toast, { ...toastProps, duration, children: [
|
|
2094
|
+
title && /* @__PURE__ */ jsx(ToastTitle, { children: title }),
|
|
2095
|
+
description && /* @__PURE__ */ jsx(ToastDescription, { children: description }),
|
|
2215
2096
|
action && action,
|
|
2216
|
-
/* @__PURE__ */
|
|
2097
|
+
/* @__PURE__ */ jsx(ToastClose, { onClick: dismiss })
|
|
2217
2098
|
] }, id);
|
|
2218
2099
|
})
|
|
2219
2100
|
] });
|
|
2220
2101
|
}
|
|
2221
|
-
|
|
2222
|
-
// src/components/Form/Form.tsx
|
|
2223
|
-
import { useForm, FormProvider, useFormContext, Controller } from "react-hook-form";
|
|
2224
|
-
import { zodResolver } from "@hookform/resolvers/zod";
|
|
2225
|
-
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2226
2102
|
function Form({
|
|
2227
2103
|
schema,
|
|
2228
2104
|
defaultValues,
|
|
@@ -2232,14 +2108,281 @@ function Form({
|
|
|
2232
2108
|
children,
|
|
2233
2109
|
className
|
|
2234
2110
|
}) {
|
|
2111
|
+
const location = useLocation();
|
|
2112
|
+
const auth = useUnifiedAuth();
|
|
2113
|
+
const userId = auth.user?.id || null;
|
|
2114
|
+
const fieldNames = useMemo(() => {
|
|
2115
|
+
if (schema && "shape" in schema && typeof schema.shape === "object") {
|
|
2116
|
+
return Object.keys(schema.shape);
|
|
2117
|
+
}
|
|
2118
|
+
if (defaultValues) {
|
|
2119
|
+
return Object.keys(defaultValues);
|
|
2120
|
+
}
|
|
2121
|
+
return [];
|
|
2122
|
+
}, [schema, defaultValues]);
|
|
2123
|
+
const persistenceKey = useMemo(() => {
|
|
2124
|
+
return deriveFormKey(
|
|
2125
|
+
{
|
|
2126
|
+
fieldNames
|
|
2127
|
+
},
|
|
2128
|
+
null,
|
|
2129
|
+
// Parent context (Dialog) - not available yet, can be enhanced later
|
|
2130
|
+
location,
|
|
2131
|
+
userId
|
|
2132
|
+
);
|
|
2133
|
+
}, [fieldNames, location, userId]);
|
|
2134
|
+
const fieldTypes = useMemo(() => {
|
|
2135
|
+
const types = {};
|
|
2136
|
+
if (schema && "shape" in schema && typeof schema.shape === "object") {
|
|
2137
|
+
const shape = schema.shape;
|
|
2138
|
+
for (const [key, value] of Object.entries(shape)) {
|
|
2139
|
+
if (value && typeof value === "object" && "_def" in value) {
|
|
2140
|
+
const def = value._def;
|
|
2141
|
+
if (def.typeName === "ZodString") {
|
|
2142
|
+
types[key] = "text";
|
|
2143
|
+
} else if (def.typeName === "ZodNumber") {
|
|
2144
|
+
types[key] = "number";
|
|
2145
|
+
} else if (def.typeName === "ZodBoolean") {
|
|
2146
|
+
types[key] = "checkbox";
|
|
2147
|
+
}
|
|
2148
|
+
}
|
|
2149
|
+
}
|
|
2150
|
+
}
|
|
2151
|
+
return types;
|
|
2152
|
+
}, [schema]);
|
|
2153
|
+
const { state: persistedValues, setState: setPersistedValues, clearDraft } = useSessionDraft(
|
|
2154
|
+
persistenceKey || "form:no-key",
|
|
2155
|
+
{},
|
|
2156
|
+
{
|
|
2157
|
+
enabled: Boolean(persistenceKey),
|
|
2158
|
+
debounceMs: 300
|
|
2159
|
+
}
|
|
2160
|
+
);
|
|
2161
|
+
const mergedDefaultValues = useMemo(() => {
|
|
2162
|
+
if (!persistenceKey || !persistedValues || Object.keys(persistedValues).length === 0) {
|
|
2163
|
+
return defaultValues;
|
|
2164
|
+
}
|
|
2165
|
+
const filteredPersisted = filterSensitiveFields(
|
|
2166
|
+
persistedValues,
|
|
2167
|
+
fieldNames,
|
|
2168
|
+
fieldTypes
|
|
2169
|
+
);
|
|
2170
|
+
return {
|
|
2171
|
+
...defaultValues,
|
|
2172
|
+
...filteredPersisted
|
|
2173
|
+
};
|
|
2174
|
+
}, [defaultValues, persistedValues, persistenceKey, fieldNames, fieldTypes]);
|
|
2235
2175
|
const methods = useForm({
|
|
2236
2176
|
resolver: schema ? zodResolver(schema) : void 0,
|
|
2237
|
-
defaultValues,
|
|
2177
|
+
defaultValues: mergedDefaultValues,
|
|
2238
2178
|
mode,
|
|
2239
2179
|
shouldUnregister: false
|
|
2240
2180
|
});
|
|
2241
|
-
const
|
|
2242
|
-
|
|
2181
|
+
const hasRestoredRef = useRef(false);
|
|
2182
|
+
const isRestoringRef = useRef(false);
|
|
2183
|
+
const restoreTimeoutRef = useRef(null);
|
|
2184
|
+
const lastRestoredRef = useRef(null);
|
|
2185
|
+
useEffect(() => {
|
|
2186
|
+
if (restoreTimeoutRef.current) {
|
|
2187
|
+
clearTimeout(restoreTimeoutRef.current);
|
|
2188
|
+
}
|
|
2189
|
+
if (isRestoringRef.current) {
|
|
2190
|
+
return;
|
|
2191
|
+
}
|
|
2192
|
+
if (!persistenceKey || !persistedValues || Object.keys(persistedValues).length === 0) {
|
|
2193
|
+
if (!hasRestoredRef.current) {
|
|
2194
|
+
hasRestoredRef.current = true;
|
|
2195
|
+
}
|
|
2196
|
+
return;
|
|
2197
|
+
}
|
|
2198
|
+
const persistedValuesStr = JSON.stringify(persistedValues);
|
|
2199
|
+
if (lastRestoredRef.current === persistedValuesStr && hasRestoredRef.current) {
|
|
2200
|
+
return;
|
|
2201
|
+
}
|
|
2202
|
+
isRestoringRef.current = true;
|
|
2203
|
+
restoreTimeoutRef.current = setTimeout(() => {
|
|
2204
|
+
const persistedKeys = Object.keys(persistedValues);
|
|
2205
|
+
const hasNumericKeys = persistedKeys.length > 0 && persistedKeys.every((key) => /^\d+$/.test(key));
|
|
2206
|
+
let valuesToRestore;
|
|
2207
|
+
if (hasNumericKeys && fieldNames.length === persistedKeys.length) {
|
|
2208
|
+
valuesToRestore = {};
|
|
2209
|
+
for (let i = 0; i < fieldNames.length; i++) {
|
|
2210
|
+
const fieldName = fieldNames[i];
|
|
2211
|
+
const numericKey = String(i);
|
|
2212
|
+
if (numericKey in persistedValues) {
|
|
2213
|
+
valuesToRestore[fieldName] = persistedValues[numericKey];
|
|
2214
|
+
}
|
|
2215
|
+
}
|
|
2216
|
+
console.log("[Form Persistence] Mapped numeric keys to field names:", {
|
|
2217
|
+
numericKeys: persistedKeys,
|
|
2218
|
+
fieldNames,
|
|
2219
|
+
mappedValues: valuesToRestore
|
|
2220
|
+
});
|
|
2221
|
+
} else {
|
|
2222
|
+
valuesToRestore = persistedValues;
|
|
2223
|
+
}
|
|
2224
|
+
const restoreKeys = Object.keys(valuesToRestore);
|
|
2225
|
+
const filteredPersisted = filterSensitiveFields(
|
|
2226
|
+
valuesToRestore,
|
|
2227
|
+
restoreKeys.length > 0 ? restoreKeys : fieldNames,
|
|
2228
|
+
fieldTypes
|
|
2229
|
+
);
|
|
2230
|
+
const sensitiveFields = restoreKeys.filter((name) => {
|
|
2231
|
+
const type = fieldTypes?.[name];
|
|
2232
|
+
return isSensitiveField(name, type);
|
|
2233
|
+
});
|
|
2234
|
+
console.log("[Form Persistence] \u2705 Restoring persisted values:", {
|
|
2235
|
+
persistenceKey,
|
|
2236
|
+
persistedValuesKeys: persistedKeys,
|
|
2237
|
+
persistedValuesString: JSON.stringify(persistedValues),
|
|
2238
|
+
hasNumericKeys,
|
|
2239
|
+
valuesToRestoreKeys: Object.keys(valuesToRestore),
|
|
2240
|
+
filteredPersistedKeys: Object.keys(filteredPersisted),
|
|
2241
|
+
fieldNames,
|
|
2242
|
+
sensitiveFields,
|
|
2243
|
+
filteredCount: Object.keys(filteredPersisted).length,
|
|
2244
|
+
persistedCount: persistedKeys.length,
|
|
2245
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2246
|
+
});
|
|
2247
|
+
const valuesToSet = {};
|
|
2248
|
+
let hasValuesToSet = false;
|
|
2249
|
+
for (const [key, value] of Object.entries(filteredPersisted)) {
|
|
2250
|
+
const currentValue = methods.getValues(key);
|
|
2251
|
+
if (currentValue !== value) {
|
|
2252
|
+
valuesToSet[key] = value;
|
|
2253
|
+
hasValuesToSet = true;
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
if (hasValuesToSet) {
|
|
2257
|
+
console.log("[Form Persistence] \u{1F504} Setting form values via reset():", {
|
|
2258
|
+
persistenceKey,
|
|
2259
|
+
valuesToSetKeys: Object.keys(valuesToSet),
|
|
2260
|
+
valuesToSet,
|
|
2261
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2262
|
+
});
|
|
2263
|
+
methods.reset({
|
|
2264
|
+
...methods.getValues(),
|
|
2265
|
+
...valuesToSet
|
|
2266
|
+
});
|
|
2267
|
+
console.log("[Form Persistence] \u2705 Form values set successfully", {
|
|
2268
|
+
persistenceKey,
|
|
2269
|
+
currentValues: methods.getValues()
|
|
2270
|
+
});
|
|
2271
|
+
} else {
|
|
2272
|
+
console.log("[Form Persistence] \u23ED\uFE0F No values to set (all values already match)", {
|
|
2273
|
+
persistenceKey
|
|
2274
|
+
});
|
|
2275
|
+
}
|
|
2276
|
+
lastRestoredRef.current = persistedValuesStr;
|
|
2277
|
+
hasRestoredRef.current = true;
|
|
2278
|
+
isRestoringRef.current = false;
|
|
2279
|
+
restoreTimeoutRef.current = null;
|
|
2280
|
+
}, 100);
|
|
2281
|
+
return () => {
|
|
2282
|
+
if (restoreTimeoutRef.current) {
|
|
2283
|
+
clearTimeout(restoreTimeoutRef.current);
|
|
2284
|
+
restoreTimeoutRef.current = null;
|
|
2285
|
+
}
|
|
2286
|
+
};
|
|
2287
|
+
}, [persistedValues, persistenceKey]);
|
|
2288
|
+
const watchedValues = useWatch({
|
|
2289
|
+
control: methods.control
|
|
2290
|
+
// Don't pass name - we want all values as an object, not an array
|
|
2291
|
+
});
|
|
2292
|
+
const previousValuesRef = useRef(null);
|
|
2293
|
+
const persistTimeoutRef = useRef(null);
|
|
2294
|
+
useEffect(() => {
|
|
2295
|
+
if (!persistenceKey || !watchedValues || isRestoringRef.current) {
|
|
2296
|
+
return;
|
|
2297
|
+
}
|
|
2298
|
+
const currentValuesStr = JSON.stringify(watchedValues);
|
|
2299
|
+
if (currentValuesStr === previousValuesRef.current) {
|
|
2300
|
+
return;
|
|
2301
|
+
}
|
|
2302
|
+
previousValuesRef.current = currentValuesStr;
|
|
2303
|
+
if (persistTimeoutRef.current) {
|
|
2304
|
+
clearTimeout(persistTimeoutRef.current);
|
|
2305
|
+
}
|
|
2306
|
+
persistTimeoutRef.current = setTimeout(() => {
|
|
2307
|
+
const allFieldNames = Object.keys(watchedValues);
|
|
2308
|
+
const filteredValues = filterSensitiveFields(
|
|
2309
|
+
watchedValues,
|
|
2310
|
+
allFieldNames.length > 0 ? allFieldNames : fieldNames,
|
|
2311
|
+
fieldTypes
|
|
2312
|
+
);
|
|
2313
|
+
const sensitiveFields = allFieldNames.filter((name) => {
|
|
2314
|
+
const type = fieldTypes?.[name];
|
|
2315
|
+
return isSensitiveField(name, type);
|
|
2316
|
+
});
|
|
2317
|
+
console.log("[Form Persistence] \u{1F4BE} Persisting form values:", {
|
|
2318
|
+
persistenceKey,
|
|
2319
|
+
filteredValuesKeys: Object.keys(filteredValues),
|
|
2320
|
+
originalValuesKeys: Object.keys(watchedValues),
|
|
2321
|
+
allFieldNames,
|
|
2322
|
+
sensitiveFields,
|
|
2323
|
+
filteredCount: Object.keys(filteredValues).length,
|
|
2324
|
+
originalCount: allFieldNames.length,
|
|
2325
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2326
|
+
});
|
|
2327
|
+
setPersistedValues(filteredValues);
|
|
2328
|
+
if (persistenceKey) {
|
|
2329
|
+
setTimeout(() => {
|
|
2330
|
+
const storageKey = `pace-core:draft:${persistenceKey}`;
|
|
2331
|
+
const stored = sessionStorage.getItem(storageKey);
|
|
2332
|
+
console.log("[Form Persistence] \u{1F4E6} SessionStorage AFTER setPersistedValues:", {
|
|
2333
|
+
persistenceKey,
|
|
2334
|
+
storageKey,
|
|
2335
|
+
stored: stored ? JSON.parse(stored) : null
|
|
2336
|
+
});
|
|
2337
|
+
}, 100);
|
|
2338
|
+
}
|
|
2339
|
+
persistTimeoutRef.current = null;
|
|
2340
|
+
}, 300);
|
|
2341
|
+
return () => {
|
|
2342
|
+
if (persistTimeoutRef.current) {
|
|
2343
|
+
clearTimeout(persistTimeoutRef.current);
|
|
2344
|
+
persistTimeoutRef.current = null;
|
|
2345
|
+
}
|
|
2346
|
+
};
|
|
2347
|
+
}, [watchedValues, persistenceKey]);
|
|
2348
|
+
const handleSubmit = methods.handleSubmit(
|
|
2349
|
+
async (data) => {
|
|
2350
|
+
console.log("[Form Lifecycle] \u{1F4E4} Form submit started", {
|
|
2351
|
+
persistenceKey,
|
|
2352
|
+
dataKeys: Object.keys(data),
|
|
2353
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2354
|
+
});
|
|
2355
|
+
await onSubmit(data);
|
|
2356
|
+
console.log("[Form Lifecycle] \u2705 Form submit successful", {
|
|
2357
|
+
persistenceKey,
|
|
2358
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2359
|
+
});
|
|
2360
|
+
if (persistenceKey && clearDraft) {
|
|
2361
|
+
console.log("[Form Persistence] \u{1F5D1}\uFE0F Clearing draft after successful submit", {
|
|
2362
|
+
persistenceKey
|
|
2363
|
+
});
|
|
2364
|
+
clearDraft();
|
|
2365
|
+
setTimeout(() => {
|
|
2366
|
+
const storageKey = `pace-core:draft:${persistenceKey}`;
|
|
2367
|
+
const stored = sessionStorage.getItem(storageKey);
|
|
2368
|
+
console.log("[Form Persistence] \u{1F4E6} SessionStorage AFTER clearDraft (submit):", {
|
|
2369
|
+
persistenceKey,
|
|
2370
|
+
storageKey,
|
|
2371
|
+
stored: stored ? JSON.parse(stored) : null
|
|
2372
|
+
});
|
|
2373
|
+
}, 100);
|
|
2374
|
+
}
|
|
2375
|
+
},
|
|
2376
|
+
(errors) => {
|
|
2377
|
+
console.log("[Form Lifecycle] \u274C Form submit failed with errors", {
|
|
2378
|
+
persistenceKey,
|
|
2379
|
+
errors,
|
|
2380
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
2381
|
+
});
|
|
2382
|
+
onError?.(errors);
|
|
2383
|
+
}
|
|
2384
|
+
);
|
|
2385
|
+
return /* @__PURE__ */ jsx(FormProvider, { ...methods, children: /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: typeof children === "function" ? children(methods) : children }) });
|
|
2243
2386
|
}
|
|
2244
2387
|
function FormField({
|
|
2245
2388
|
name,
|
|
@@ -2253,12 +2396,12 @@ function FormField({
|
|
|
2253
2396
|
className
|
|
2254
2397
|
}) {
|
|
2255
2398
|
const { control } = useFormContext();
|
|
2256
|
-
return /* @__PURE__ */
|
|
2257
|
-
label && /* @__PURE__ */
|
|
2399
|
+
return /* @__PURE__ */ jsxs("label", { className: cn("space-y-2", className), children: [
|
|
2400
|
+
label && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2258
2401
|
label,
|
|
2259
|
-
validation?.required && /* @__PURE__ */
|
|
2402
|
+
validation?.required && /* @__PURE__ */ jsx("span", { className: "text-destructive ml-1", "aria-label": "required", children: "*" })
|
|
2260
2403
|
] }),
|
|
2261
|
-
/* @__PURE__ */
|
|
2404
|
+
/* @__PURE__ */ jsx(
|
|
2262
2405
|
Controller,
|
|
2263
2406
|
{
|
|
2264
2407
|
name,
|
|
@@ -2271,8 +2414,8 @@ function FormField({
|
|
|
2271
2414
|
if (render) {
|
|
2272
2415
|
return render(props);
|
|
2273
2416
|
}
|
|
2274
|
-
return /* @__PURE__ */
|
|
2275
|
-
/* @__PURE__ */
|
|
2417
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2418
|
+
/* @__PURE__ */ jsx(
|
|
2276
2419
|
"input",
|
|
2277
2420
|
{
|
|
2278
2421
|
...field,
|
|
@@ -2288,18 +2431,14 @@ function FormField({
|
|
|
2288
2431
|
...inputProps
|
|
2289
2432
|
}
|
|
2290
2433
|
),
|
|
2291
|
-
errorMessage && /* @__PURE__ */
|
|
2434
|
+
errorMessage && /* @__PURE__ */ jsx("p", { className: "text-destructive", role: "alert", children: errorMessage })
|
|
2292
2435
|
] });
|
|
2293
2436
|
}
|
|
2294
2437
|
}
|
|
2295
2438
|
)
|
|
2296
2439
|
] });
|
|
2297
2440
|
}
|
|
2298
|
-
|
|
2299
|
-
// src/components/LoginForm/LoginForm.tsx
|
|
2300
|
-
import React9, { useState as useState7, useCallback as useCallback7, useMemo as useMemo4 } from "react";
|
|
2301
|
-
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2302
|
-
var LoginForm = React9.memo(({
|
|
2441
|
+
var LoginForm = React7__default.memo(({
|
|
2303
2442
|
onSignIn,
|
|
2304
2443
|
onSuccess,
|
|
2305
2444
|
onError,
|
|
@@ -2311,9 +2450,9 @@ var LoginForm = React9.memo(({
|
|
|
2311
2450
|
onSignUp,
|
|
2312
2451
|
className
|
|
2313
2452
|
}) => {
|
|
2314
|
-
const [formData, setFormData] =
|
|
2315
|
-
const [error, setError] =
|
|
2316
|
-
const isFormValid =
|
|
2453
|
+
const [formData, setFormData] = useState({ email: "", password: "" });
|
|
2454
|
+
const [error, setError] = useState(null);
|
|
2455
|
+
const isFormValid = useMemo(() => {
|
|
2317
2456
|
return formData.email.length > 0 && formData.password.length > 0;
|
|
2318
2457
|
}, [formData.email, formData.password]);
|
|
2319
2458
|
const handleEmailChange = (e) => {
|
|
@@ -2322,7 +2461,7 @@ var LoginForm = React9.memo(({
|
|
|
2322
2461
|
const handlePasswordChange = (e) => {
|
|
2323
2462
|
setFormData((prev) => ({ ...prev, password: e.target.value }));
|
|
2324
2463
|
};
|
|
2325
|
-
const handleSubmit =
|
|
2464
|
+
const handleSubmit = useCallback(async (e) => {
|
|
2326
2465
|
e.preventDefault();
|
|
2327
2466
|
setError(null);
|
|
2328
2467
|
if (!isFormValid || isLoading) return;
|
|
@@ -2338,17 +2477,17 @@ var LoginForm = React9.memo(({
|
|
|
2338
2477
|
const handleSignUpClick = () => {
|
|
2339
2478
|
onSignUp?.();
|
|
2340
2479
|
};
|
|
2341
|
-
const displayTitle =
|
|
2342
|
-
const displaySubtitle =
|
|
2343
|
-
return /* @__PURE__ */
|
|
2344
|
-
/* @__PURE__ */
|
|
2345
|
-
/* @__PURE__ */
|
|
2346
|
-
/* @__PURE__ */
|
|
2480
|
+
const displayTitle = useMemo(() => title || (appName ? `Sign in to ${appName}` : "Sign In"), [title, appName]);
|
|
2481
|
+
const displaySubtitle = useMemo(() => subtitle || "Enter your credentials to continue.", [subtitle]);
|
|
2482
|
+
return /* @__PURE__ */ jsx(Card, { className: cn("w-full max-w-md mx-auto", className), children: /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, "data-testid": "login-form", children: [
|
|
2483
|
+
/* @__PURE__ */ jsxs(CardHeader, { className: "space-y-1", children: [
|
|
2484
|
+
/* @__PURE__ */ jsx(CardTitle, { className: "text-2xl text-center", children: displayTitle }),
|
|
2485
|
+
/* @__PURE__ */ jsx(CardDescription, { className: "text-center", children: displaySubtitle })
|
|
2347
2486
|
] }),
|
|
2348
|
-
/* @__PURE__ */
|
|
2349
|
-
error && /* @__PURE__ */
|
|
2350
|
-
/* @__PURE__ */
|
|
2351
|
-
/* @__PURE__ */
|
|
2487
|
+
/* @__PURE__ */ jsxs(CardContent, { className: "space-y-4", children: [
|
|
2488
|
+
error && /* @__PURE__ */ jsx(Alert, { variant: "destructive", role: "alert", "aria-live": "assertive", children: /* @__PURE__ */ jsx(AlertDescription, { children: error }) }),
|
|
2489
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "email", children: "Email" }),
|
|
2490
|
+
/* @__PURE__ */ jsx(
|
|
2352
2491
|
Input,
|
|
2353
2492
|
{
|
|
2354
2493
|
id: "email",
|
|
@@ -2360,8 +2499,8 @@ var LoginForm = React9.memo(({
|
|
|
2360
2499
|
disabled: isLoading
|
|
2361
2500
|
}
|
|
2362
2501
|
),
|
|
2363
|
-
/* @__PURE__ */
|
|
2364
|
-
/* @__PURE__ */
|
|
2502
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "password", children: "Password" }),
|
|
2503
|
+
/* @__PURE__ */ jsx(
|
|
2365
2504
|
Input,
|
|
2366
2505
|
{
|
|
2367
2506
|
id: "password",
|
|
@@ -2374,8 +2513,8 @@ var LoginForm = React9.memo(({
|
|
|
2374
2513
|
}
|
|
2375
2514
|
)
|
|
2376
2515
|
] }),
|
|
2377
|
-
/* @__PURE__ */
|
|
2378
|
-
/* @__PURE__ */
|
|
2516
|
+
/* @__PURE__ */ jsxs(CardFooter, { className: "flex flex-col space-y-4", children: [
|
|
2517
|
+
/* @__PURE__ */ jsx(
|
|
2379
2518
|
Button,
|
|
2380
2519
|
{
|
|
2381
2520
|
type: "submit",
|
|
@@ -2384,7 +2523,7 @@ var LoginForm = React9.memo(({
|
|
|
2384
2523
|
children: isLoading ? "Signing in..." : "Sign In"
|
|
2385
2524
|
}
|
|
2386
2525
|
),
|
|
2387
|
-
showSignUp && (onSignUp ? /* @__PURE__ */
|
|
2526
|
+
showSignUp && (onSignUp ? /* @__PURE__ */ jsx("p", { className: "text-sm text-center text-muted-foreground", children: /* @__PURE__ */ jsx(
|
|
2388
2527
|
"button",
|
|
2389
2528
|
{
|
|
2390
2529
|
type: "button",
|
|
@@ -2392,19 +2531,14 @@ var LoginForm = React9.memo(({
|
|
|
2392
2531
|
className: "text-primary hover:underline",
|
|
2393
2532
|
children: "Don't have an account? Sign up"
|
|
2394
2533
|
}
|
|
2395
|
-
) }) : /* @__PURE__ */
|
|
2534
|
+
) }) : /* @__PURE__ */ jsxs("p", { className: "text-center text-muted-foreground", children: [
|
|
2396
2535
|
"Don't have an account?",
|
|
2397
2536
|
" ",
|
|
2398
|
-
/* @__PURE__ */
|
|
2537
|
+
/* @__PURE__ */ jsx("a", { href: "/signup", className: "text-primary hover:underline", children: "Sign up" })
|
|
2399
2538
|
] }))
|
|
2400
2539
|
] })
|
|
2401
2540
|
] }) });
|
|
2402
2541
|
});
|
|
2403
|
-
|
|
2404
|
-
// src/components/ContextSelector/ContextSelector.tsx
|
|
2405
|
-
import { useMemo as useMemo5 } from "react";
|
|
2406
|
-
import { RefreshCw, AlertCircle, Building2, Calendar as Calendar2 } from "lucide-react";
|
|
2407
|
-
import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2408
2542
|
function ContextSelector({
|
|
2409
2543
|
placeholder = "Select organisation or event",
|
|
2410
2544
|
className,
|
|
@@ -2435,7 +2569,7 @@ function ContextSelector({
|
|
|
2435
2569
|
const isLoading = showOrganisations && orgLoading || showEvents && eventLoading;
|
|
2436
2570
|
const hasError = showOrganisations && orgError || showEvents && eventError;
|
|
2437
2571
|
const hasItems = showOrganisations && (organisations?.length || 0) > 0 || showEvents && (events?.length || 0) > 0;
|
|
2438
|
-
const currentValue =
|
|
2572
|
+
const currentValue = useMemo(() => {
|
|
2439
2573
|
if (showEvents && selectedEvent) {
|
|
2440
2574
|
return `event:${selectedEvent.event_id || selectedEvent.id}`;
|
|
2441
2575
|
}
|
|
@@ -2444,6 +2578,36 @@ function ContextSelector({
|
|
|
2444
2578
|
}
|
|
2445
2579
|
return "";
|
|
2446
2580
|
}, [showOrganisations, showEvents, selectedOrganisation?.id, selectedEvent]);
|
|
2581
|
+
const displayValue = useMemo(() => {
|
|
2582
|
+
if (showEvents && selectedEvent) {
|
|
2583
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2584
|
+
/* @__PURE__ */ jsx(Calendar$1, { className: "size-4 flex-shrink-0" }),
|
|
2585
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: selectedEvent.event_name })
|
|
2586
|
+
] });
|
|
2587
|
+
}
|
|
2588
|
+
if (showOrganisations && selectedOrganisation) {
|
|
2589
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2590
|
+
/* @__PURE__ */ jsx(Building2, { className: "size-4 flex-shrink-0" }),
|
|
2591
|
+
/* @__PURE__ */ jsx("span", { className: "truncate", children: selectedOrganisation.display_name })
|
|
2592
|
+
] });
|
|
2593
|
+
}
|
|
2594
|
+
return null;
|
|
2595
|
+
}, [showOrganisations, showEvents, selectedOrganisation, selectedEvent]);
|
|
2596
|
+
const effectivePlaceholder = useMemo(() => {
|
|
2597
|
+
if (placeholder !== "Select organisation or event") {
|
|
2598
|
+
return placeholder;
|
|
2599
|
+
}
|
|
2600
|
+
if (showOrganisations && showEvents) {
|
|
2601
|
+
return "Select organisation or event";
|
|
2602
|
+
}
|
|
2603
|
+
if (showOrganisations) {
|
|
2604
|
+
return "Select organisation";
|
|
2605
|
+
}
|
|
2606
|
+
if (showEvents) {
|
|
2607
|
+
return "Select event";
|
|
2608
|
+
}
|
|
2609
|
+
return placeholder;
|
|
2610
|
+
}, [placeholder, showOrganisations, showEvents]);
|
|
2447
2611
|
const handleValueChange = (value) => {
|
|
2448
2612
|
if (disabled || isLoading) return;
|
|
2449
2613
|
if (value.startsWith("org:") && showOrganisations) {
|
|
@@ -2474,9 +2638,9 @@ function ContextSelector({
|
|
|
2474
2638
|
};
|
|
2475
2639
|
if (isLoading && !hasItems) {
|
|
2476
2640
|
const loadingText = compact ? "Loading..." : showOrganisations && showEvents ? "Loading organisations and events..." : showOrganisations ? "Loading organisations..." : "Loading events...";
|
|
2477
|
-
return /* @__PURE__ */
|
|
2478
|
-
/* @__PURE__ */
|
|
2479
|
-
/* @__PURE__ */
|
|
2641
|
+
return /* @__PURE__ */ jsxs("div", { className: `flex items-center gap-2 ${className}`, children: [
|
|
2642
|
+
/* @__PURE__ */ jsx(LoadingSpinner, { size: "sm" }),
|
|
2643
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-muted-foreground", children: loadingText })
|
|
2480
2644
|
] });
|
|
2481
2645
|
}
|
|
2482
2646
|
if (hasError) {
|
|
@@ -2487,12 +2651,12 @@ function ContextSelector({
|
|
|
2487
2651
|
if (showEvents && eventError) {
|
|
2488
2652
|
errorMessages.push(`Failed to load events: ${eventError.message}`);
|
|
2489
2653
|
}
|
|
2490
|
-
return /* @__PURE__ */
|
|
2491
|
-
/* @__PURE__ */
|
|
2492
|
-
/* @__PURE__ */
|
|
2493
|
-
/* @__PURE__ */
|
|
2654
|
+
return /* @__PURE__ */ jsxs("div", { className: `space-y-2 ${className}`, children: [
|
|
2655
|
+
/* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
|
|
2656
|
+
/* @__PURE__ */ jsx(AlertCircle, { className: "size-4" }),
|
|
2657
|
+
/* @__PURE__ */ jsx(AlertDescription, { children: errorMessages.join(" ") })
|
|
2494
2658
|
] }),
|
|
2495
|
-
showRetryButton && /* @__PURE__ */
|
|
2659
|
+
showRetryButton && /* @__PURE__ */ jsxs(
|
|
2496
2660
|
Button,
|
|
2497
2661
|
{
|
|
2498
2662
|
variant: "outline",
|
|
@@ -2501,7 +2665,7 @@ function ContextSelector({
|
|
|
2501
2665
|
disabled: isLoading,
|
|
2502
2666
|
className: "w-full",
|
|
2503
2667
|
children: [
|
|
2504
|
-
/* @__PURE__ */
|
|
2668
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
2505
2669
|
"Retry"
|
|
2506
2670
|
]
|
|
2507
2671
|
}
|
|
@@ -2511,12 +2675,12 @@ function ContextSelector({
|
|
|
2511
2675
|
if (!hasItems) {
|
|
2512
2676
|
if (showNoItemsMessage) {
|
|
2513
2677
|
const noItemsText = showOrganisations && showEvents ? "No organisations or events available. Please contact your administrator." : showOrganisations ? "No organisations available. Please contact your administrator." : "No events available. Please contact your administrator.";
|
|
2514
|
-
return /* @__PURE__ */
|
|
2515
|
-
/* @__PURE__ */
|
|
2516
|
-
/* @__PURE__ */
|
|
2517
|
-
/* @__PURE__ */
|
|
2678
|
+
return /* @__PURE__ */ jsxs("div", { className: `space-y-2 ${className}`, children: [
|
|
2679
|
+
/* @__PURE__ */ jsxs(Alert, { children: [
|
|
2680
|
+
/* @__PURE__ */ jsx(AlertCircle, { className: "size-4" }),
|
|
2681
|
+
/* @__PURE__ */ jsx(AlertDescription, { children: noItemsText })
|
|
2518
2682
|
] }),
|
|
2519
|
-
showRetryButton && /* @__PURE__ */
|
|
2683
|
+
showRetryButton && /* @__PURE__ */ jsxs(
|
|
2520
2684
|
Button,
|
|
2521
2685
|
{
|
|
2522
2686
|
variant: "outline",
|
|
@@ -2525,7 +2689,7 @@ function ContextSelector({
|
|
|
2525
2689
|
disabled: isLoading,
|
|
2526
2690
|
className: "w-full",
|
|
2527
2691
|
children: [
|
|
2528
|
-
/* @__PURE__ */
|
|
2692
|
+
/* @__PURE__ */ jsx(RefreshCw, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
2529
2693
|
"Check Again"
|
|
2530
2694
|
]
|
|
2531
2695
|
}
|
|
@@ -2534,83 +2698,53 @@ function ContextSelector({
|
|
|
2534
2698
|
}
|
|
2535
2699
|
return null;
|
|
2536
2700
|
}
|
|
2537
|
-
|
|
2538
|
-
if (showEvents && selectedEvent) {
|
|
2539
|
-
return /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
2540
|
-
/* @__PURE__ */ jsx13(Calendar2, { className: "size-4 flex-shrink-0" }),
|
|
2541
|
-
/* @__PURE__ */ jsx13("span", { className: "truncate", children: selectedEvent.event_name })
|
|
2542
|
-
] });
|
|
2543
|
-
}
|
|
2544
|
-
if (showOrganisations && selectedOrganisation) {
|
|
2545
|
-
return /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
2546
|
-
/* @__PURE__ */ jsx13(Building2, { className: "size-4 flex-shrink-0" }),
|
|
2547
|
-
/* @__PURE__ */ jsx13("span", { className: "truncate", children: selectedOrganisation.display_name })
|
|
2548
|
-
] });
|
|
2549
|
-
}
|
|
2550
|
-
return null;
|
|
2551
|
-
}, [showOrganisations, showEvents, selectedOrganisation, selectedEvent]);
|
|
2552
|
-
const effectivePlaceholder = useMemo5(() => {
|
|
2553
|
-
if (placeholder !== "Select organisation or event") {
|
|
2554
|
-
return placeholder;
|
|
2555
|
-
}
|
|
2556
|
-
if (showOrganisations && showEvents) {
|
|
2557
|
-
return "Select organisation or event";
|
|
2558
|
-
}
|
|
2559
|
-
if (showOrganisations) {
|
|
2560
|
-
return "Select organisation";
|
|
2561
|
-
}
|
|
2562
|
-
if (showEvents) {
|
|
2563
|
-
return "Select event";
|
|
2564
|
-
}
|
|
2565
|
-
return placeholder;
|
|
2566
|
-
}, [placeholder, showOrganisations, showEvents]);
|
|
2567
|
-
return /* @__PURE__ */ jsx13("div", { className, "data-testid": "context-selector", children: /* @__PURE__ */ jsxs8(
|
|
2701
|
+
return /* @__PURE__ */ jsx("div", { className, "data-testid": "context-selector", children: /* @__PURE__ */ jsxs(
|
|
2568
2702
|
Select,
|
|
2569
2703
|
{
|
|
2570
2704
|
value: currentValue,
|
|
2571
2705
|
onValueChange: handleValueChange,
|
|
2572
2706
|
disabled: disabled || isLoading,
|
|
2573
2707
|
children: [
|
|
2574
|
-
/* @__PURE__ */
|
|
2708
|
+
/* @__PURE__ */ jsx(
|
|
2575
2709
|
SelectTrigger,
|
|
2576
2710
|
{
|
|
2577
2711
|
className: "text-left",
|
|
2578
2712
|
variant: "outline",
|
|
2579
|
-
children: /* @__PURE__ */
|
|
2713
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: effectivePlaceholder, children: displayValue })
|
|
2580
2714
|
}
|
|
2581
2715
|
),
|
|
2582
|
-
/* @__PURE__ */
|
|
2583
|
-
showOrganisations && organisations && organisations.length > 0 && /* @__PURE__ */
|
|
2584
|
-
/* @__PURE__ */
|
|
2585
|
-
/* @__PURE__ */
|
|
2586
|
-
organisations.map((org) => /* @__PURE__ */
|
|
2716
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
2717
|
+
showOrganisations && organisations && organisations.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2718
|
+
/* @__PURE__ */ jsxs(SelectGroup, { children: [
|
|
2719
|
+
/* @__PURE__ */ jsx(SelectLabel, { children: "Organisations" }),
|
|
2720
|
+
organisations.map((org) => /* @__PURE__ */ jsx(
|
|
2587
2721
|
SelectItem,
|
|
2588
2722
|
{
|
|
2589
2723
|
value: `org:${org.id}`,
|
|
2590
|
-
children: /* @__PURE__ */
|
|
2591
|
-
/* @__PURE__ */
|
|
2592
|
-
/* @__PURE__ */
|
|
2593
|
-
/* @__PURE__ */
|
|
2594
|
-
!compact && org.description && /* @__PURE__ */
|
|
2724
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2725
|
+
/* @__PURE__ */ jsx(Building2, { className: "size-4" }),
|
|
2726
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
2727
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: org.display_name }),
|
|
2728
|
+
!compact && org.description && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground truncate max-w-40", children: org.description })
|
|
2595
2729
|
] })
|
|
2596
2730
|
] })
|
|
2597
2731
|
},
|
|
2598
2732
|
org.id
|
|
2599
2733
|
))
|
|
2600
2734
|
] }),
|
|
2601
|
-
showEvents && events && events.length > 0 && /* @__PURE__ */
|
|
2735
|
+
showEvents && events && events.length > 0 && /* @__PURE__ */ jsx(SelectSeparator, {})
|
|
2602
2736
|
] }),
|
|
2603
|
-
showEvents && events && events.length > 0 && /* @__PURE__ */
|
|
2604
|
-
/* @__PURE__ */
|
|
2605
|
-
events.map((event) => /* @__PURE__ */
|
|
2737
|
+
showEvents && events && events.length > 0 && /* @__PURE__ */ jsxs(SelectGroup, { children: [
|
|
2738
|
+
/* @__PURE__ */ jsx(SelectLabel, { children: "Events" }),
|
|
2739
|
+
events.map((event) => /* @__PURE__ */ jsx(
|
|
2606
2740
|
SelectItem,
|
|
2607
2741
|
{
|
|
2608
2742
|
value: `event:${event.event_id || event.id}`,
|
|
2609
|
-
children: /* @__PURE__ */
|
|
2610
|
-
/* @__PURE__ */
|
|
2611
|
-
/* @__PURE__ */
|
|
2612
|
-
/* @__PURE__ */
|
|
2613
|
-
!compact && event.event_date && /* @__PURE__ */
|
|
2743
|
+
children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
2744
|
+
/* @__PURE__ */ jsx(Calendar$1, { className: "size-4" }),
|
|
2745
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
|
|
2746
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: event.event_name }),
|
|
2747
|
+
!compact && event.event_date && /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: new Date(event.event_date).toLocaleDateString() })
|
|
2614
2748
|
] })
|
|
2615
2749
|
] })
|
|
2616
2750
|
},
|
|
@@ -2622,15 +2756,11 @@ function ContextSelector({
|
|
|
2622
2756
|
}
|
|
2623
2757
|
) });
|
|
2624
2758
|
}
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
const [newPassword, setNewPassword] = useState8("");
|
|
2631
|
-
const [confirmPassword, setConfirmPassword] = useState8("");
|
|
2632
|
-
const [error, setError] = useState8(null);
|
|
2633
|
-
const [isSubmitting, setIsSubmitting] = useState8(false);
|
|
2759
|
+
function PasswordChangeForm({ onSubmit, onSuccess, className }) {
|
|
2760
|
+
const [newPassword, setNewPassword] = useState("");
|
|
2761
|
+
const [confirmPassword, setConfirmPassword] = useState("");
|
|
2762
|
+
const [error, setError] = useState(null);
|
|
2763
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
2634
2764
|
const handleSubmit = async (e) => {
|
|
2635
2765
|
e.preventDefault();
|
|
2636
2766
|
setError(null);
|
|
@@ -2647,6 +2777,8 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2647
2777
|
const result = await onSubmit({ newPassword, confirmPassword });
|
|
2648
2778
|
if (result && result.error) {
|
|
2649
2779
|
setError(result.error.message || "Failed to change password.");
|
|
2780
|
+
} else {
|
|
2781
|
+
onSuccess?.();
|
|
2650
2782
|
}
|
|
2651
2783
|
} catch (err) {
|
|
2652
2784
|
const errorObj = err instanceof Error ? err : new Error("An unexpected error occurred");
|
|
@@ -2655,11 +2787,11 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2655
2787
|
setIsSubmitting(false);
|
|
2656
2788
|
}
|
|
2657
2789
|
};
|
|
2658
|
-
return /* @__PURE__ */
|
|
2659
|
-
error && /* @__PURE__ */
|
|
2660
|
-
/* @__PURE__ */
|
|
2661
|
-
|
|
2662
|
-
/* @__PURE__ */
|
|
2790
|
+
return /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: [
|
|
2791
|
+
error && /* @__PURE__ */ jsx("p", { className: "grid place-items-center text-center size-full", role: "alert", children: error }),
|
|
2792
|
+
/* @__PURE__ */ jsxs(Label, { htmlFor: "new-password", className: "block mb-4", children: [
|
|
2793
|
+
"New Password",
|
|
2794
|
+
/* @__PURE__ */ jsx(
|
|
2663
2795
|
Input,
|
|
2664
2796
|
{
|
|
2665
2797
|
id: "new-password",
|
|
@@ -2667,13 +2799,14 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2667
2799
|
value: newPassword,
|
|
2668
2800
|
onChange: (e) => setNewPassword(e.target.value),
|
|
2669
2801
|
required: true,
|
|
2670
|
-
disabled: isSubmitting
|
|
2802
|
+
disabled: isSubmitting,
|
|
2803
|
+
className: "mt-2"
|
|
2671
2804
|
}
|
|
2672
2805
|
)
|
|
2673
2806
|
] }),
|
|
2674
|
-
/* @__PURE__ */
|
|
2675
|
-
|
|
2676
|
-
/* @__PURE__ */
|
|
2807
|
+
/* @__PURE__ */ jsxs(Label, { htmlFor: "confirm-password", className: "block mb-4", children: [
|
|
2808
|
+
"Confirm Password",
|
|
2809
|
+
/* @__PURE__ */ jsx(
|
|
2677
2810
|
Input,
|
|
2678
2811
|
{
|
|
2679
2812
|
id: "confirm-password",
|
|
@@ -2681,11 +2814,12 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2681
2814
|
value: confirmPassword,
|
|
2682
2815
|
onChange: (e) => setConfirmPassword(e.target.value),
|
|
2683
2816
|
required: true,
|
|
2684
|
-
disabled: isSubmitting
|
|
2817
|
+
disabled: isSubmitting,
|
|
2818
|
+
className: "mt-2"
|
|
2685
2819
|
}
|
|
2686
2820
|
)
|
|
2687
2821
|
] }),
|
|
2688
|
-
/* @__PURE__ */
|
|
2822
|
+
/* @__PURE__ */ jsx(
|
|
2689
2823
|
Button,
|
|
2690
2824
|
{
|
|
2691
2825
|
type: "submit",
|
|
@@ -2696,20 +2830,14 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2696
2830
|
)
|
|
2697
2831
|
] });
|
|
2698
2832
|
}
|
|
2699
|
-
|
|
2700
|
-
// src/components/UserMenu/UserMenu.tsx
|
|
2701
|
-
import React12, { useCallback as useCallback8, useMemo as useMemo6, useState as useState9 } from "react";
|
|
2702
|
-
import { ChevronDown, LogOut, KeyRound } from "lucide-react";
|
|
2703
|
-
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2704
|
-
var UserMenu = React12.memo(function UserMenu2({
|
|
2833
|
+
var UserMenu = React7__default.memo(function UserMenu2({
|
|
2705
2834
|
user,
|
|
2706
2835
|
onSignOut,
|
|
2707
2836
|
onChangePassword,
|
|
2708
2837
|
className,
|
|
2709
2838
|
showAvatar = true
|
|
2710
2839
|
}) {
|
|
2711
|
-
const
|
|
2712
|
-
const userInfo = useMemo6(() => {
|
|
2840
|
+
const userInfo = useMemo(() => {
|
|
2713
2841
|
if (!user) return null;
|
|
2714
2842
|
return {
|
|
2715
2843
|
email: user.email,
|
|
@@ -2718,16 +2846,23 @@ var UserMenu = React12.memo(function UserMenu2({
|
|
|
2718
2846
|
initial: (user.user_metadata?.display_name || user.user_metadata?.full_name || user.email || "U").charAt(0).toUpperCase()
|
|
2719
2847
|
};
|
|
2720
2848
|
}, [user]);
|
|
2721
|
-
const handleSignOut =
|
|
2849
|
+
const handleSignOut = useCallback(async () => {
|
|
2722
2850
|
if (onSignOut) await onSignOut();
|
|
2723
2851
|
}, [onSignOut]);
|
|
2852
|
+
const [isPasswordDialogOpen, setPasswordDialogOpen] = useState(false);
|
|
2853
|
+
const handlePasswordChange = useCallback(async (newPassword, confirmPassword) => {
|
|
2854
|
+
if (!onChangePassword) {
|
|
2855
|
+
return { error: { message: "Password change not configured" } };
|
|
2856
|
+
}
|
|
2857
|
+
return await onChangePassword(newPassword, confirmPassword);
|
|
2858
|
+
}, [onChangePassword]);
|
|
2724
2859
|
if (!user || !userInfo) {
|
|
2725
2860
|
return null;
|
|
2726
2861
|
}
|
|
2727
|
-
return /* @__PURE__ */
|
|
2728
|
-
/* @__PURE__ */
|
|
2729
|
-
/* @__PURE__ */
|
|
2730
|
-
showAvatar && /* @__PURE__ */
|
|
2862
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2863
|
+
/* @__PURE__ */ jsxs(Select, { className, children: [
|
|
2864
|
+
/* @__PURE__ */ jsx(SelectTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(Button, { variant: "outline", className: "flex items-center gap-2", "aria-label": userInfo.displayName, children: [
|
|
2865
|
+
showAvatar && /* @__PURE__ */ jsx(
|
|
2731
2866
|
Avatar,
|
|
2732
2867
|
{
|
|
2733
2868
|
src: userInfo.avatarUrl,
|
|
@@ -2736,49 +2871,49 @@ var UserMenu = React12.memo(function UserMenu2({
|
|
|
2736
2871
|
className: "size-7"
|
|
2737
2872
|
}
|
|
2738
2873
|
),
|
|
2739
|
-
/* @__PURE__ */
|
|
2740
|
-
/* @__PURE__ */
|
|
2874
|
+
/* @__PURE__ */ jsx("span", { children: userInfo.displayName }),
|
|
2875
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "size-4" })
|
|
2741
2876
|
] }) }),
|
|
2742
|
-
/* @__PURE__ */
|
|
2743
|
-
/* @__PURE__ */
|
|
2877
|
+
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
2878
|
+
/* @__PURE__ */ jsx(SelectLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs("li", { className: "pt-2", children: [
|
|
2744
2879
|
userInfo.displayName,
|
|
2745
|
-
/* @__PURE__ */
|
|
2746
|
-
/* @__PURE__ */
|
|
2880
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
2881
|
+
/* @__PURE__ */ jsx("small", { children: userInfo.email })
|
|
2747
2882
|
] }) }),
|
|
2748
|
-
/* @__PURE__ */
|
|
2749
|
-
/* @__PURE__ */
|
|
2750
|
-
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2883
|
+
/* @__PURE__ */ jsx(SelectSeparator, {}),
|
|
2884
|
+
/* @__PURE__ */ jsxs(
|
|
2885
|
+
SelectItem,
|
|
2886
|
+
{
|
|
2887
|
+
value: "change-password",
|
|
2888
|
+
onClick: () => setPasswordDialogOpen(true),
|
|
2889
|
+
children: [
|
|
2890
|
+
/* @__PURE__ */ jsx(KeyRound, { className: "inline-block mr-2 size-4" }),
|
|
2891
|
+
"Change Password"
|
|
2892
|
+
]
|
|
2893
|
+
}
|
|
2894
|
+
),
|
|
2895
|
+
/* @__PURE__ */ jsxs(SelectItem, { value: "sign-out", onClick: handleSignOut, children: [
|
|
2896
|
+
/* @__PURE__ */ jsx(LogOut, { className: "inline-block mr-2 size-4" }),
|
|
2897
|
+
"Sign out"
|
|
2756
2898
|
] })
|
|
2757
2899
|
] })
|
|
2758
2900
|
] }),
|
|
2759
|
-
/* @__PURE__ */
|
|
2760
|
-
|
|
2761
|
-
/* @__PURE__ */
|
|
2762
|
-
/* @__PURE__ */ jsx15(
|
|
2901
|
+
/* @__PURE__ */ jsx(Dialog, { open: isPasswordDialogOpen, onOpenChange: setPasswordDialogOpen, children: /* @__PURE__ */ jsxs(DialogContent, { persistOpenState: false, children: [
|
|
2902
|
+
/* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: "Change Password" }) }),
|
|
2903
|
+
/* @__PURE__ */ jsx(
|
|
2763
2904
|
PasswordChangeForm,
|
|
2764
2905
|
{
|
|
2765
2906
|
onSubmit: async ({ newPassword, confirmPassword }) => {
|
|
2766
|
-
|
|
2767
|
-
|
|
2768
|
-
|
|
2769
|
-
setPasswordDialogOpen(false);
|
|
2770
|
-
}
|
|
2771
|
-
return { error };
|
|
2772
|
-
}
|
|
2773
|
-
return {};
|
|
2774
|
-
}
|
|
2907
|
+
return await handlePasswordChange(newPassword, confirmPassword);
|
|
2908
|
+
},
|
|
2909
|
+
onSuccess: () => setPasswordDialogOpen(false)
|
|
2775
2910
|
}
|
|
2776
2911
|
)
|
|
2777
|
-
] })
|
|
2912
|
+
] }) })
|
|
2778
2913
|
] });
|
|
2779
2914
|
});
|
|
2780
|
-
var UserMenuLoading =
|
|
2781
|
-
return /* @__PURE__ */
|
|
2915
|
+
var UserMenuLoading = React7__default.memo(function UserMenuLoading2() {
|
|
2916
|
+
return /* @__PURE__ */ jsxs(
|
|
2782
2917
|
Button,
|
|
2783
2918
|
{
|
|
2784
2919
|
type: "button",
|
|
@@ -2787,46 +2922,23 @@ var UserMenuLoading = React12.memo(function UserMenuLoading2() {
|
|
|
2787
2922
|
className: "flex items-center space-x-2",
|
|
2788
2923
|
"aria-label": "Loading user menu",
|
|
2789
2924
|
children: [
|
|
2790
|
-
/* @__PURE__ */
|
|
2791
|
-
/* @__PURE__ */
|
|
2792
|
-
/* @__PURE__ */
|
|
2925
|
+
/* @__PURE__ */ jsx(LoadingSpinner, { size: "sm", className: "inline-block mr-2" }),
|
|
2926
|
+
/* @__PURE__ */ jsx("span", { className: "truncate max-w-[150px]", children: "Loading..." }),
|
|
2927
|
+
/* @__PURE__ */ jsx(ChevronDown, { className: "w-4 h-4 text-muted-foreground" })
|
|
2793
2928
|
]
|
|
2794
2929
|
}
|
|
2795
2930
|
);
|
|
2796
2931
|
});
|
|
2797
2932
|
UserMenu.Loading = UserMenuLoading;
|
|
2798
|
-
|
|
2799
|
-
// src/components/NavigationMenu/NavigationMenu.tsx
|
|
2800
|
-
import * as React14 from "react";
|
|
2801
|
-
import { ChevronDown as ChevronDown2 } from "lucide-react";
|
|
2802
|
-
|
|
2803
|
-
// src/components/NavigationMenu/useNavigationFiltering.ts
|
|
2804
|
-
import * as React13 from "react";
|
|
2805
2933
|
function useNavigationFiltering({
|
|
2806
2934
|
items,
|
|
2807
2935
|
itemsPreFiltered = false,
|
|
2808
2936
|
auditLog = true
|
|
2809
2937
|
}) {
|
|
2810
|
-
const [resolvedAppId, setResolvedAppId] =
|
|
2811
|
-
const previousFilteredItemsRef =
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
authContext = useUnifiedAuth();
|
|
2815
|
-
} catch (error) {
|
|
2816
|
-
logger.warn(
|
|
2817
|
-
"NavigationMenu",
|
|
2818
|
-
"useUnifiedAuth not available, running in unauthenticated mode"
|
|
2819
|
-
);
|
|
2820
|
-
}
|
|
2821
|
-
let rbacContext = null;
|
|
2822
|
-
try {
|
|
2823
|
-
rbacContext = useRBAC();
|
|
2824
|
-
} catch (error) {
|
|
2825
|
-
logger.warn(
|
|
2826
|
-
"NavigationMenu",
|
|
2827
|
-
"useRBAC not available, permission filtering disabled"
|
|
2828
|
-
);
|
|
2829
|
-
}
|
|
2938
|
+
const [resolvedAppId, setResolvedAppId] = React7.useState(void 0);
|
|
2939
|
+
const previousFilteredItemsRef = React7.useRef([]);
|
|
2940
|
+
const authContext = useUnifiedAuth();
|
|
2941
|
+
const rbacContext = useRBAC();
|
|
2830
2942
|
const eventLoadingRaw = authContext?.eventLoading;
|
|
2831
2943
|
const eventLoading = eventLoadingRaw ?? false;
|
|
2832
2944
|
const selectedEvent = authContext?.selectedEvent || null;
|
|
@@ -2836,16 +2948,17 @@ function useNavigationFiltering({
|
|
|
2836
2948
|
const { resolvedScope, isLoading: scopeLoading, error: scopeError } = useResolvedScope({
|
|
2837
2949
|
supabase: itemsPreFiltered ? null : supabase || null,
|
|
2838
2950
|
selectedOrganisationId: itemsPreFiltered ? null : selectedOrganisation?.id || null,
|
|
2839
|
-
selectedEventId: itemsPreFiltered ? null : selectedEvent?.event_id || null
|
|
2951
|
+
selectedEventId: itemsPreFiltered ? null : selectedEvent?.event_id || null,
|
|
2952
|
+
selectedEventOrganisationId: itemsPreFiltered ? null : selectedEvent?.organisation_id || null
|
|
2840
2953
|
});
|
|
2841
|
-
|
|
2954
|
+
React7.useEffect(() => {
|
|
2842
2955
|
if (!scopeLoading && !resolvedScope?.appId && selectedOrganisation?.id && authContext?.appName && authContext?.user?.id && !resolvedAppId) {
|
|
2843
2956
|
if (!authContext.user || !authContext.appName) {
|
|
2844
2957
|
return;
|
|
2845
2958
|
}
|
|
2846
2959
|
const userId2 = authContext.user.id;
|
|
2847
2960
|
const appName = authContext.appName;
|
|
2848
|
-
import(
|
|
2961
|
+
import('./api-Y4MQWOFW.js').then(({ resolveAppContext }) => {
|
|
2849
2962
|
resolveAppContext({
|
|
2850
2963
|
userId: userId2,
|
|
2851
2964
|
appName
|
|
@@ -2866,7 +2979,7 @@ function useNavigationFiltering({
|
|
|
2866
2979
|
authContext?.user?.id,
|
|
2867
2980
|
resolvedAppId
|
|
2868
2981
|
]);
|
|
2869
|
-
const effectiveScope =
|
|
2982
|
+
const effectiveScope = React7.useMemo(() => {
|
|
2870
2983
|
if (resolvedScope?.organisationId) {
|
|
2871
2984
|
return resolvedScope;
|
|
2872
2985
|
}
|
|
@@ -2881,7 +2994,7 @@ function useNavigationFiltering({
|
|
|
2881
2994
|
return null;
|
|
2882
2995
|
}, [resolvedScope, selectedOrganisation?.id, selectedEvent?.event_id, resolvedAppId]);
|
|
2883
2996
|
const scopeKey = effectiveScope ? `${effectiveScope.organisationId || ""}-${effectiveScope.eventId || ""}-${effectiveScope.appId || ""}` : "empty";
|
|
2884
|
-
const stableScope =
|
|
2997
|
+
const stableScope = React7.useMemo(() => {
|
|
2885
2998
|
if (effectiveScope?.organisationId) {
|
|
2886
2999
|
return {
|
|
2887
3000
|
organisationId: effectiveScope.organisationId,
|
|
@@ -2907,7 +3020,7 @@ function useNavigationFiltering({
|
|
|
2907
3020
|
itemsPreFiltered ? void 0 : stableScope.eventId,
|
|
2908
3021
|
itemsPreFiltered ? void 0 : stableScope.appId
|
|
2909
3022
|
);
|
|
2910
|
-
const filteredItems =
|
|
3023
|
+
const filteredItems = React7.useMemo(() => {
|
|
2911
3024
|
if (itemsPreFiltered && items && items.length > 0) {
|
|
2912
3025
|
const visibleItems = (items || []).filter((item) => !item.meta?.hidden);
|
|
2913
3026
|
previousFilteredItemsRef.current = visibleItems;
|
|
@@ -3086,10 +3199,7 @@ function useNavigationFiltering({
|
|
|
3086
3199
|
hasAnyPermission: hasAnyPermission || null
|
|
3087
3200
|
};
|
|
3088
3201
|
}
|
|
3089
|
-
|
|
3090
|
-
// src/components/NavigationMenu/NavigationMenu.tsx
|
|
3091
|
-
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3092
|
-
var NavigationMenu = React14.forwardRef(({
|
|
3202
|
+
var NavigationMenu = React7.forwardRef(({
|
|
3093
3203
|
items,
|
|
3094
3204
|
mode = "dropdown",
|
|
3095
3205
|
currentPath,
|
|
@@ -3107,8 +3217,8 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3107
3217
|
itemsPreFiltered = false,
|
|
3108
3218
|
...props
|
|
3109
3219
|
}, ref) => {
|
|
3110
|
-
const [expandedItems, setExpandedItems] =
|
|
3111
|
-
const buttonRef =
|
|
3220
|
+
const [expandedItems, setExpandedItems] = React7.useState(/* @__PURE__ */ new Set());
|
|
3221
|
+
const buttonRef = React7.useRef(null);
|
|
3112
3222
|
const { authContext, rbacContext, filteredItems, permissionMap, hasAnyPermission } = useNavigationFiltering({ items, itemsPreFiltered, auditLog });
|
|
3113
3223
|
const handleHierarchicalKeyDown = (event, item) => {
|
|
3114
3224
|
switch (event.key) {
|
|
@@ -3138,8 +3248,6 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3138
3248
|
setExpandedItems(newExpanded);
|
|
3139
3249
|
};
|
|
3140
3250
|
const handleItemClick = (item) => {
|
|
3141
|
-
if (auditLog) {
|
|
3142
|
-
}
|
|
3143
3251
|
if (!authContext) {
|
|
3144
3252
|
if (onNavigate) {
|
|
3145
3253
|
onNavigate(item);
|
|
@@ -3231,8 +3339,8 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3231
3339
|
const hasChildren = item.children && item.children.length > 0;
|
|
3232
3340
|
const isExpanded = expandedItems.has(item.id);
|
|
3233
3341
|
const itemIsActive = isActiveItem(item);
|
|
3234
|
-
return /* @__PURE__ */
|
|
3235
|
-
/* @__PURE__ */
|
|
3342
|
+
return /* @__PURE__ */ jsx("li", { role: "none", children: hasChildren ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
3343
|
+
/* @__PURE__ */ jsxs(
|
|
3236
3344
|
"button",
|
|
3237
3345
|
{
|
|
3238
3346
|
onClick: () => toggleExpanded(item.id),
|
|
@@ -3241,21 +3349,21 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3241
3349
|
"aria-controls": `submenu-${item.id}`,
|
|
3242
3350
|
"aria-current": itemIsActive ? "page" : void 0,
|
|
3243
3351
|
children: [
|
|
3244
|
-
/* @__PURE__ */
|
|
3245
|
-
/* @__PURE__ */
|
|
3352
|
+
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
3353
|
+
/* @__PURE__ */ jsx(ChevronDown, { "aria-hidden": "true" })
|
|
3246
3354
|
]
|
|
3247
3355
|
}
|
|
3248
3356
|
),
|
|
3249
|
-
isExpanded && item.children && /* @__PURE__ */
|
|
3357
|
+
isExpanded && item.children && /* @__PURE__ */ jsx(
|
|
3250
3358
|
"ul",
|
|
3251
3359
|
{
|
|
3252
3360
|
id: `submenu-${item.id}`,
|
|
3253
3361
|
role: "menu",
|
|
3254
3362
|
"aria-label": `${item.label} submenu`,
|
|
3255
|
-
children: item.children.map((child) => /* @__PURE__ */
|
|
3363
|
+
children: item.children.map((child) => /* @__PURE__ */ jsx(React7.Fragment, { children: renderHierarchicalItem(child, level + 1) }, child.id))
|
|
3256
3364
|
}
|
|
3257
3365
|
)
|
|
3258
|
-
] }) : /* @__PURE__ */
|
|
3366
|
+
] }) : /* @__PURE__ */ jsx(
|
|
3259
3367
|
"a",
|
|
3260
3368
|
{
|
|
3261
3369
|
href: item.href || "#",
|
|
@@ -3273,26 +3381,26 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3273
3381
|
) });
|
|
3274
3382
|
};
|
|
3275
3383
|
if (mode === "dropdown") {
|
|
3276
|
-
return /* @__PURE__ */
|
|
3384
|
+
return /* @__PURE__ */ jsxs(
|
|
3277
3385
|
Select,
|
|
3278
3386
|
{
|
|
3279
3387
|
onValueChange: handleNavigationSelect,
|
|
3280
3388
|
className,
|
|
3281
3389
|
"data-testid": "navigation-menu-root",
|
|
3282
3390
|
children: [
|
|
3283
|
-
/* @__PURE__ */
|
|
3391
|
+
/* @__PURE__ */ jsx(
|
|
3284
3392
|
SelectTrigger,
|
|
3285
3393
|
{
|
|
3286
3394
|
ref: buttonRef,
|
|
3287
3395
|
disabled,
|
|
3288
3396
|
"aria-label": buttonText,
|
|
3289
3397
|
"data-testid": "navigation-menu-trigger",
|
|
3290
|
-
children: /* @__PURE__ */
|
|
3398
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: buttonText })
|
|
3291
3399
|
}
|
|
3292
3400
|
),
|
|
3293
|
-
/* @__PURE__ */
|
|
3294
|
-
|
|
3295
|
-
return /* @__PURE__ */
|
|
3401
|
+
/* @__PURE__ */ jsx(SelectContent, { children: filteredItems.map((item) => {
|
|
3402
|
+
isActiveItem(item);
|
|
3403
|
+
return /* @__PURE__ */ jsx(
|
|
3296
3404
|
SelectItem,
|
|
3297
3405
|
{
|
|
3298
3406
|
value: item.id,
|
|
@@ -3307,22 +3415,18 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3307
3415
|
}
|
|
3308
3416
|
);
|
|
3309
3417
|
}
|
|
3310
|
-
return /* @__PURE__ */
|
|
3418
|
+
return /* @__PURE__ */ jsx(
|
|
3311
3419
|
"nav",
|
|
3312
3420
|
{
|
|
3313
3421
|
ref,
|
|
3314
3422
|
className,
|
|
3315
3423
|
"aria-label": navigationLabel,
|
|
3316
3424
|
...props,
|
|
3317
|
-
children: /* @__PURE__ */
|
|
3425
|
+
children: /* @__PURE__ */ jsx("ul", { role: "menubar", children: filteredItems.map((item) => /* @__PURE__ */ jsx(React7.Fragment, { children: renderHierarchicalItem(item, 0) }, item.id)) })
|
|
3318
3426
|
}
|
|
3319
3427
|
);
|
|
3320
3428
|
});
|
|
3321
3429
|
NavigationMenu.displayName = "NavigationMenu";
|
|
3322
|
-
|
|
3323
|
-
// src/components/Header/Header.tsx
|
|
3324
|
-
import { Link } from "react-router-dom";
|
|
3325
|
-
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3326
3430
|
function Header({
|
|
3327
3431
|
logoUrl,
|
|
3328
3432
|
logoAlt = "Logo",
|
|
@@ -3345,32 +3449,32 @@ function Header({
|
|
|
3345
3449
|
const shouldShowContextSelector = showContextSelector !== false;
|
|
3346
3450
|
const { switchOrganisation } = useOrganisations();
|
|
3347
3451
|
const { events, setSelectedEvent } = useEvents();
|
|
3348
|
-
return /* @__PURE__ */
|
|
3452
|
+
return /* @__PURE__ */ jsx("header", { className: cn(
|
|
3349
3453
|
"w-full border-b border-main-200 h-16 shadow-sm bg-main-100 ",
|
|
3350
3454
|
className
|
|
3351
|
-
), role: "banner", children: /* @__PURE__ */
|
|
3352
|
-
logo ? logoHref ? /* @__PURE__ */
|
|
3455
|
+
), role: "banner", children: /* @__PURE__ */ jsxs("nav", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto grid grid-cols-[auto_1fr_auto_auto_auto_auto] items-center gap-4 h-full", children: [
|
|
3456
|
+
logo ? logoHref ? /* @__PURE__ */ jsx(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: logo }) : logo : logoUrl ? logoHref ? /* @__PURE__ */ jsx(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx(
|
|
3353
3457
|
"img",
|
|
3354
3458
|
{
|
|
3355
3459
|
src: logoUrl,
|
|
3356
3460
|
alt: logoAlt || "Logo",
|
|
3357
3461
|
className: "h-[2.15rem] w-auto max-w-[200px] object-contain rounded-md shadow-md bg-transparent"
|
|
3358
3462
|
}
|
|
3359
|
-
) }) : /* @__PURE__ */
|
|
3463
|
+
) }) : /* @__PURE__ */ jsx(
|
|
3360
3464
|
"img",
|
|
3361
3465
|
{
|
|
3362
3466
|
src: logoUrl,
|
|
3363
3467
|
alt: logoAlt || "Logo",
|
|
3364
3468
|
className: "h-[2.15rem] w-auto max-w-[200px] object-contain rounded-md shadow-md bg-transparent"
|
|
3365
3469
|
}
|
|
3366
|
-
) : logoHref ? /* @__PURE__ */
|
|
3470
|
+
) : logoHref ? /* @__PURE__ */ jsx(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx(
|
|
3367
3471
|
"img",
|
|
3368
3472
|
{
|
|
3369
3473
|
src: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23000'/%3E%3Ctext x='16' y='20' text-anchor='middle' fill='white' font-family='Arial' font-size='14' font-weight='bold'%3EL%3C/text%3E%3C/svg%3E",
|
|
3370
3474
|
alt: logoAlt || "Logo",
|
|
3371
3475
|
className: "size-8 shadow-md"
|
|
3372
3476
|
}
|
|
3373
|
-
) }) : /* @__PURE__ */
|
|
3477
|
+
) }) : /* @__PURE__ */ jsx(
|
|
3374
3478
|
"img",
|
|
3375
3479
|
{
|
|
3376
3480
|
src: "data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 32 32'%3E%3Crect width='32' height='32' fill='%23000'/%3E%3Ctext x='16' y='20' text-anchor='middle' fill='white' font-family='Arial' font-size='14' font-weight='bold'%3EL%3C/text%3E%3C/svg%3E",
|
|
@@ -3378,7 +3482,7 @@ function Header({
|
|
|
3378
3482
|
className: "size-8 shadow-md"
|
|
3379
3483
|
}
|
|
3380
3484
|
),
|
|
3381
|
-
navItems && navItems.length > 0 && /* @__PURE__ */
|
|
3485
|
+
navItems && navItems.length > 0 && /* @__PURE__ */ jsx(
|
|
3382
3486
|
NavigationMenu,
|
|
3383
3487
|
{
|
|
3384
3488
|
items: navItems,
|
|
@@ -3389,7 +3493,7 @@ function Header({
|
|
|
3389
3493
|
itemsPreFiltered: true
|
|
3390
3494
|
}
|
|
3391
3495
|
),
|
|
3392
|
-
shouldShowContextSelector ? /* @__PURE__ */
|
|
3496
|
+
shouldShowContextSelector ? /* @__PURE__ */ jsx(
|
|
3393
3497
|
ContextSelector,
|
|
3394
3498
|
{
|
|
3395
3499
|
placeholder: "Select organisation or event",
|
|
@@ -3412,7 +3516,7 @@ function Header({
|
|
|
3412
3516
|
}
|
|
3413
3517
|
) : null,
|
|
3414
3518
|
actions,
|
|
3415
|
-
showUserMenu && (userMenu ? userMenu : /* @__PURE__ */
|
|
3519
|
+
showUserMenu && (userMenu ? userMenu : /* @__PURE__ */ jsx(
|
|
3416
3520
|
UserMenu,
|
|
3417
3521
|
{
|
|
3418
3522
|
user: user || null,
|
|
@@ -3423,10 +3527,6 @@ function Header({
|
|
|
3423
3527
|
))
|
|
3424
3528
|
] }) });
|
|
3425
3529
|
}
|
|
3426
|
-
|
|
3427
|
-
// src/components/Footer/Footer.tsx
|
|
3428
|
-
import React15 from "react";
|
|
3429
|
-
import { Fragment as Fragment8, jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3430
3530
|
var FooterComponent = ({
|
|
3431
3531
|
companyName = "Solvera Solutions Pty Ltd",
|
|
3432
3532
|
year = (/* @__PURE__ */ new Date()).getFullYear(),
|
|
@@ -3437,21 +3537,16 @@ var FooterComponent = ({
|
|
|
3437
3537
|
children
|
|
3438
3538
|
}) => {
|
|
3439
3539
|
const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
|
|
3440
|
-
return /* @__PURE__ */
|
|
3441
|
-
logo && /* @__PURE__ */
|
|
3442
|
-
children && /* @__PURE__ */
|
|
3443
|
-
/* @__PURE__ */
|
|
3444
|
-
links && links.length > 0 && /* @__PURE__ */
|
|
3540
|
+
return /* @__PURE__ */ jsx("footer", { className: cn("mt-8 py-6 flex justify-center border-t border-border bg-main-100", className), children: /* @__PURE__ */ jsxs("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
|
|
3541
|
+
logo && /* @__PURE__ */ jsx("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
|
|
3542
|
+
children && /* @__PURE__ */ jsx(Fragment, { children }),
|
|
3543
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: copyrightText }),
|
|
3544
|
+
links && links.length > 0 && /* @__PURE__ */ jsx("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
|
|
3445
3545
|
] }) });
|
|
3446
3546
|
};
|
|
3447
3547
|
FooterComponent.displayName = "Footer";
|
|
3448
|
-
var Footer =
|
|
3548
|
+
var Footer = React7__default.memo(FooterComponent);
|
|
3449
3549
|
Footer.displayName = "Footer";
|
|
3450
|
-
|
|
3451
|
-
// src/components/PaceAppLayout/PaceAppLayout.tsx
|
|
3452
|
-
import { useState as useState12, useEffect as useEffect7, useMemo as useMemo8 } from "react";
|
|
3453
|
-
import { Outlet, useNavigate, useLocation } from "react-router-dom";
|
|
3454
|
-
import { Fragment as Fragment9, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3455
3550
|
var EMPTY_PAGE_ID_MAPPING = {};
|
|
3456
3551
|
var EMPTY_ROUTE_PERMISSIONS = {};
|
|
3457
3552
|
function PaceAppLayout({
|
|
@@ -3494,9 +3589,9 @@ function PaceAppLayout({
|
|
|
3494
3589
|
isLoading: organisationLoading
|
|
3495
3590
|
} = useOrganisations();
|
|
3496
3591
|
const { isSuperAdmin: isSuperAdminFromRBAC, isLoading: rbacLoading } = useRBAC();
|
|
3497
|
-
const [isSuperAdminDirect, setIsSuperAdminDirect] =
|
|
3498
|
-
const [isCheckingSuperAdminDirect, setIsCheckingSuperAdminDirect] =
|
|
3499
|
-
|
|
3592
|
+
const [isSuperAdminDirect, setIsSuperAdminDirect] = useState(false);
|
|
3593
|
+
const [isCheckingSuperAdminDirect, setIsCheckingSuperAdminDirect] = useState(false);
|
|
3594
|
+
useEffect(() => {
|
|
3500
3595
|
const checkSuperAdminDirect = async () => {
|
|
3501
3596
|
if (!user?.id) {
|
|
3502
3597
|
setIsSuperAdminDirect(false);
|
|
@@ -3533,13 +3628,14 @@ function PaceAppLayout({
|
|
|
3533
3628
|
const { resolvedScope, isLoading: scopeLoading } = useResolvedScope({
|
|
3534
3629
|
supabase: supabase || null,
|
|
3535
3630
|
selectedOrganisationId: selectedOrganisation?.id || null,
|
|
3536
|
-
selectedEventId: selectedEvent?.event_id || null
|
|
3631
|
+
selectedEventId: selectedEvent?.event_id || null,
|
|
3632
|
+
selectedEventOrganisationId: selectedEvent?.organisation_id || null
|
|
3537
3633
|
});
|
|
3538
3634
|
const resolvedAppId = contextAppId || resolvedScope?.appId;
|
|
3539
3635
|
const scopeOrgId = resolvedScope?.organisationId || selectedOrganisation?.id || "";
|
|
3540
3636
|
const scopeEventId = resolvedScope?.eventId || selectedEvent?.event_id || void 0;
|
|
3541
3637
|
const scopeAppId = resolvedScope?.appId || resolvedAppId || void 0;
|
|
3542
|
-
const scope =
|
|
3638
|
+
const scope = useMemo(() => {
|
|
3543
3639
|
const newScope = {};
|
|
3544
3640
|
if (scopeOrgId) {
|
|
3545
3641
|
newScope.organisationId = scopeOrgId;
|
|
@@ -3552,19 +3648,19 @@ function PaceAppLayout({
|
|
|
3552
3648
|
}
|
|
3553
3649
|
return newScope;
|
|
3554
3650
|
}, [scopeOrgId, scopeEventId, scopeAppId]);
|
|
3555
|
-
const defaultNavItems =
|
|
3651
|
+
const defaultNavItems = useMemo(() => [
|
|
3556
3652
|
{ id: "home", label: "Home", href: "/", icon: "Home" },
|
|
3557
3653
|
{ id: "dashboard", label: "Dashboard", href: "/dashboard", icon: "LayoutDashboard" },
|
|
3558
3654
|
{ id: "settings", label: "Settings", href: "/settings", icon: "Settings" },
|
|
3559
3655
|
{ id: "ui-showcase", label: "UI Showcase", href: "/ui-showcase", icon: "Component" },
|
|
3560
3656
|
{ id: "data-table-showcase", label: "DataTable Showcase", href: "/data-table-showcase", icon: "Table" }
|
|
3561
3657
|
], []);
|
|
3562
|
-
const baseMenuItems =
|
|
3563
|
-
const currentRoutePermission =
|
|
3658
|
+
const baseMenuItems = useMemo(() => navItems || defaultNavItems, [navItems]);
|
|
3659
|
+
const currentRoutePermission = useMemo(() => {
|
|
3564
3660
|
const currentPath = location.pathname;
|
|
3565
3661
|
return routePermissions[currentPath] || defaultPermission;
|
|
3566
3662
|
}, [location.pathname, routePermissions, defaultPermission]);
|
|
3567
|
-
const currentPageId =
|
|
3663
|
+
const currentPageId = useMemo(() => {
|
|
3568
3664
|
const currentPath = location.pathname;
|
|
3569
3665
|
if (pageIdMapping[currentPath]) {
|
|
3570
3666
|
return pageIdMapping[currentPath];
|
|
@@ -3572,7 +3668,7 @@ function PaceAppLayout({
|
|
|
3572
3668
|
const pathSegments = currentPath.slice(1).split("/").filter(Boolean);
|
|
3573
3669
|
return pathSegments[0] || "";
|
|
3574
3670
|
}, [location.pathname, pageIdMapping]);
|
|
3575
|
-
const currentPermission =
|
|
3671
|
+
const currentPermission = useMemo(() => {
|
|
3576
3672
|
if (!enforcePermissions || !currentPageId) {
|
|
3577
3673
|
return "";
|
|
3578
3674
|
}
|
|
@@ -3595,13 +3691,13 @@ function PaceAppLayout({
|
|
|
3595
3691
|
);
|
|
3596
3692
|
const can = isSuperAdmin2 ? true : canFromHook;
|
|
3597
3693
|
const hasPermission = enforcePermissions ? can : true;
|
|
3598
|
-
const isContextError =
|
|
3694
|
+
const isContextError = useMemo(() => {
|
|
3599
3695
|
if (!permissionError) {
|
|
3600
3696
|
return false;
|
|
3601
3697
|
}
|
|
3602
3698
|
return permissionError instanceof EventContextRequiredError || permissionError instanceof OrganisationContextRequiredError || permissionError.name === "EventContextRequiredError" || permissionError.name === "OrganisationContextRequiredError";
|
|
3603
3699
|
}, [permissionError]);
|
|
3604
|
-
|
|
3700
|
+
useEffect(() => {
|
|
3605
3701
|
if (!enforcePermissions) {
|
|
3606
3702
|
return;
|
|
3607
3703
|
}
|
|
@@ -3624,8 +3720,8 @@ function PaceAppLayout({
|
|
|
3624
3720
|
onPageAccessDenied(currentPageId, currentRoutePermission);
|
|
3625
3721
|
}
|
|
3626
3722
|
}, [enforcePermissions, can, isCheckingPermission, isSuperAdmin2, currentPageId, currentRoutePermission, user?.id, strictMode, auditLog, onPageAccessDenied, onStrictModeViolation]);
|
|
3627
|
-
const [filteredMenuItems, setFilteredMenuItems] =
|
|
3628
|
-
|
|
3723
|
+
const [filteredMenuItems, setFilteredMenuItems] = useState(baseMenuItems);
|
|
3724
|
+
useEffect(() => {
|
|
3629
3725
|
let isMounted = true;
|
|
3630
3726
|
const filterItems = async () => {
|
|
3631
3727
|
if (!user?.id) {
|
|
@@ -3635,7 +3731,7 @@ function PaceAppLayout({
|
|
|
3635
3731
|
return;
|
|
3636
3732
|
}
|
|
3637
3733
|
const currentScope = scope;
|
|
3638
|
-
|
|
3734
|
+
currentScope.appId || resolvedAppId;
|
|
3639
3735
|
const hasOrganisationContext = currentScope.organisationId;
|
|
3640
3736
|
const hasUser = !!user?.id;
|
|
3641
3737
|
if (!hasUser) {
|
|
@@ -3651,7 +3747,7 @@ function PaceAppLayout({
|
|
|
3651
3747
|
return;
|
|
3652
3748
|
}
|
|
3653
3749
|
try {
|
|
3654
|
-
const { isSuperAdmin: checkSuperAdminDynamic } = await import(
|
|
3750
|
+
const { isSuperAdmin: checkSuperAdminDynamic } = await import('./api-Y4MQWOFW.js');
|
|
3655
3751
|
const isSuper = await checkSuperAdminDynamic(user.id);
|
|
3656
3752
|
if (isSuper) {
|
|
3657
3753
|
if (isMounted) {
|
|
@@ -3660,13 +3756,12 @@ function PaceAppLayout({
|
|
|
3660
3756
|
return;
|
|
3661
3757
|
}
|
|
3662
3758
|
} catch (error) {
|
|
3663
|
-
if (error && typeof error === "object" && "code" in error && error.code === "RBAC_NOT_INITIALIZED") {
|
|
3664
|
-
} else {
|
|
3759
|
+
if (error && typeof error === "object" && "code" in error && error.code === "RBAC_NOT_INITIALIZED") ; else {
|
|
3665
3760
|
throw error;
|
|
3666
3761
|
}
|
|
3667
3762
|
}
|
|
3668
3763
|
try {
|
|
3669
|
-
const { getPermissionMap } = await import(
|
|
3764
|
+
const { getPermissionMap } = await import('./api-Y4MQWOFW.js');
|
|
3670
3765
|
const permissionScope = {
|
|
3671
3766
|
organisationId: currentScope.organisationId,
|
|
3672
3767
|
eventId: currentScope.eventId,
|
|
@@ -3677,7 +3772,7 @@ function PaceAppLayout({
|
|
|
3677
3772
|
userId: user.id,
|
|
3678
3773
|
scope: permissionScope
|
|
3679
3774
|
});
|
|
3680
|
-
const { getPageScopeType } = await import(
|
|
3775
|
+
const { getPageScopeType } = await import('./api-Y4MQWOFW.js');
|
|
3681
3776
|
const effectiveAppId = currentScope.appId || resolvedAppId;
|
|
3682
3777
|
const effectiveAppName = appName;
|
|
3683
3778
|
const hasEventContext = !!currentScope.eventId;
|
|
@@ -3764,7 +3859,7 @@ function PaceAppLayout({
|
|
|
3764
3859
|
isMounted = false;
|
|
3765
3860
|
};
|
|
3766
3861
|
}, [baseMenuItems, pageIdMapping, routePermissions, defaultPermission, can, user?.id, scope, scopeLoading, contextAppId, resolvedScope?.appId, selectedOrganisation?.id, selectedEvent?.event_id, appName]);
|
|
3767
|
-
|
|
3862
|
+
useEffect(() => {
|
|
3768
3863
|
if (!roleBasedRouting || routeConfig.length === 0) return;
|
|
3769
3864
|
let isMounted = true;
|
|
3770
3865
|
const checkRouteAccess = async () => {
|
|
@@ -3786,7 +3881,7 @@ function PaceAppLayout({
|
|
|
3786
3881
|
let hasAccess = true;
|
|
3787
3882
|
if (currentRoute.pageId && currentRoute.permissions && currentRoute.permissions.length > 0) {
|
|
3788
3883
|
try {
|
|
3789
|
-
const { isPermittedCached } = await import(
|
|
3884
|
+
const { isPermittedCached } = await import('./api-Y4MQWOFW.js');
|
|
3790
3885
|
const hasPagePermission = await isPermittedCached({
|
|
3791
3886
|
userId: user?.id || "",
|
|
3792
3887
|
scope,
|
|
@@ -3802,7 +3897,7 @@ function PaceAppLayout({
|
|
|
3802
3897
|
}
|
|
3803
3898
|
}
|
|
3804
3899
|
if (hasAccess && currentRoute.roles && currentRoute.roles.length > 0 && user?.id) {
|
|
3805
|
-
const { useUnifiedAuth: useUnifiedAuth2 } = await import(
|
|
3900
|
+
const { useUnifiedAuth: useUnifiedAuth2 } = await import('./UnifiedAuthProvider-ZT6TIGM7.js');
|
|
3806
3901
|
hasAccess = true;
|
|
3807
3902
|
}
|
|
3808
3903
|
if (!isMounted) return;
|
|
@@ -3863,52 +3958,58 @@ function PaceAppLayout({
|
|
|
3863
3958
|
}
|
|
3864
3959
|
};
|
|
3865
3960
|
if (user?.id && organisationLoading && !isSuperAdmin2 && !isCheckingSuperAdminDirect && !rbacLoading && !selectedOrganisationId) {
|
|
3866
|
-
return /* @__PURE__ */
|
|
3867
|
-
/* @__PURE__ */
|
|
3868
|
-
|
|
3869
|
-
|
|
3961
|
+
return /* @__PURE__ */ jsxs("p", { className: "grid place-items-center text-center size-full", children: [
|
|
3962
|
+
/* @__PURE__ */ jsx(
|
|
3963
|
+
LoadingSpinner,
|
|
3964
|
+
{
|
|
3965
|
+
size: "lg"
|
|
3966
|
+
}
|
|
3967
|
+
),
|
|
3968
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
3969
|
+
"Loading organisation context..."
|
|
3970
|
+
] });
|
|
3870
3971
|
}
|
|
3871
3972
|
if (enforcePermissions && isCheckingPermission) {
|
|
3872
|
-
return /* @__PURE__ */
|
|
3873
|
-
/* @__PURE__ */
|
|
3874
|
-
|
|
3875
|
-
|
|
3973
|
+
return /* @__PURE__ */ jsxs("p", { className: "grid place-items-center text-center size-full", children: [
|
|
3974
|
+
/* @__PURE__ */ jsx(
|
|
3975
|
+
LoadingSpinner,
|
|
3976
|
+
{
|
|
3977
|
+
size: "lg"
|
|
3978
|
+
}
|
|
3979
|
+
),
|
|
3980
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
3981
|
+
"Checking permissions..."
|
|
3982
|
+
] });
|
|
3876
3983
|
}
|
|
3877
3984
|
if (enforcePermissions && permissionError && !isSuperAdmin2 && !isContextError) {
|
|
3878
|
-
return /* @__PURE__ */
|
|
3879
|
-
/* @__PURE__ */
|
|
3880
|
-
/* @__PURE__ */
|
|
3881
|
-
/* @__PURE__ */
|
|
3882
|
-
] })
|
|
3985
|
+
return /* @__PURE__ */ jsxs("hgroup", { className: "grid place-items-center text-center size-full", children: [
|
|
3986
|
+
/* @__PURE__ */ jsx("h2", { children: "Permission Error" }),
|
|
3987
|
+
/* @__PURE__ */ jsx("p", { children: permissionError.message }),
|
|
3988
|
+
/* @__PURE__ */ jsx(Button, { onClick: () => navigate("/"), children: "Go Home" })
|
|
3989
|
+
] });
|
|
3883
3990
|
}
|
|
3884
3991
|
if (enforcePermissions && hasPermission === false && !isCheckingSuperAdminDirect && !isSuperAdmin2 && !isContextError) {
|
|
3885
3992
|
if (enforcePagePermissions && pagePermissionFallback) {
|
|
3886
|
-
return /* @__PURE__ */
|
|
3993
|
+
return /* @__PURE__ */ jsx(Fragment, { children: pagePermissionFallback });
|
|
3887
3994
|
}
|
|
3888
3995
|
if (permissionFallback) {
|
|
3889
|
-
return /* @__PURE__ */
|
|
3890
|
-
}
|
|
3891
|
-
return /* @__PURE__ */
|
|
3892
|
-
|
|
3893
|
-
|
|
3894
|
-
|
|
3895
|
-
|
|
3896
|
-
|
|
3897
|
-
|
|
3898
|
-
|
|
3899
|
-
|
|
3900
|
-
|
|
3901
|
-
|
|
3902
|
-
|
|
3903
|
-
},
|
|
3904
|
-
children: "Sign out"
|
|
3905
|
-
}
|
|
3906
|
-
)
|
|
3907
|
-
] })
|
|
3908
|
-
] }) });
|
|
3996
|
+
return /* @__PURE__ */ jsx(Fragment, { children: permissionFallback });
|
|
3997
|
+
}
|
|
3998
|
+
return /* @__PURE__ */ jsx(
|
|
3999
|
+
AccessDenied,
|
|
4000
|
+
{
|
|
4001
|
+
message: "You don't have permission to access this page.",
|
|
4002
|
+
onGoBack: () => navigate("/"),
|
|
4003
|
+
onSignOut: async () => {
|
|
4004
|
+
await handleSignOut();
|
|
4005
|
+
navigate("/login");
|
|
4006
|
+
},
|
|
4007
|
+
showSignOut: true
|
|
4008
|
+
}
|
|
4009
|
+
);
|
|
3909
4010
|
}
|
|
3910
|
-
return /* @__PURE__ */
|
|
3911
|
-
/* @__PURE__ */
|
|
4011
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4012
|
+
/* @__PURE__ */ jsx(
|
|
3912
4013
|
Header,
|
|
3913
4014
|
{
|
|
3914
4015
|
logo: customLogo || void 0,
|
|
@@ -3934,38 +4035,39 @@ function PaceAppLayout({
|
|
|
3934
4035
|
className: headerClassName || "sticky top-0 z-[40] w-full"
|
|
3935
4036
|
}
|
|
3936
4037
|
),
|
|
3937
|
-
/* @__PURE__ */
|
|
3938
|
-
/* @__PURE__ */
|
|
4038
|
+
/* @__PURE__ */ jsx("main", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: /* @__PURE__ */ jsx(Outlet, {}) }),
|
|
4039
|
+
/* @__PURE__ */ jsx(Footer, {})
|
|
3939
4040
|
] });
|
|
3940
4041
|
}
|
|
3941
|
-
|
|
3942
|
-
// src/components/PaceLoginPage/PaceLoginPage.tsx
|
|
3943
|
-
import { useEffect as useEffect8, useState as useState13, useContext as useContext2 } from "react";
|
|
3944
|
-
import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
|
|
3945
|
-
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3946
4042
|
var PaceLoginPage = ({
|
|
3947
4043
|
appName = "Pace",
|
|
3948
4044
|
onSuccessRedirectPath = "/",
|
|
3949
4045
|
requireAppAccess = false
|
|
3950
4046
|
}) => {
|
|
3951
|
-
const
|
|
3952
|
-
const navigate =
|
|
3953
|
-
const location =
|
|
3954
|
-
const [isSigningIn, setIsSigningIn] =
|
|
3955
|
-
const [accessError, setAccessError] =
|
|
3956
|
-
const [isCheckingAccess, setIsCheckingAccess] =
|
|
3957
|
-
const eventServiceContext =
|
|
4047
|
+
const authContext = useContext(UnifiedAuthContext);
|
|
4048
|
+
const navigate = useNavigate();
|
|
4049
|
+
const location = useLocation();
|
|
4050
|
+
const [isSigningIn, setIsSigningIn] = useState(false);
|
|
4051
|
+
const [accessError, setAccessError] = useState(null);
|
|
4052
|
+
const [isCheckingAccess, setIsCheckingAccess] = useState(false);
|
|
4053
|
+
const eventServiceContext = useContext(EventServiceContext);
|
|
3958
4054
|
const eventService = eventServiceContext?.eventService || null;
|
|
3959
|
-
|
|
4055
|
+
const signIn = authContext?.signIn || (async () => ({ error: null }));
|
|
4056
|
+
const isAuthenticated = authContext?.isAuthenticated ?? false;
|
|
4057
|
+
const isLoading = authContext?.isLoading ?? false;
|
|
4058
|
+
const authError = authContext?.authError ?? null;
|
|
4059
|
+
const user = authContext?.user ?? null;
|
|
4060
|
+
const supabase = authContext?.supabase ?? null;
|
|
4061
|
+
useEffect(() => {
|
|
3960
4062
|
clearPalette();
|
|
3961
4063
|
}, []);
|
|
3962
|
-
|
|
4064
|
+
useEffect(() => {
|
|
3963
4065
|
const isOnLoginPage = location.pathname === "/login" || location.pathname.startsWith("/login");
|
|
3964
4066
|
if (isOnLoginPage) {
|
|
3965
4067
|
clearPalette();
|
|
3966
4068
|
}
|
|
3967
4069
|
}, [location.pathname]);
|
|
3968
|
-
|
|
4070
|
+
useEffect(() => {
|
|
3969
4071
|
const restoreEvent = async () => {
|
|
3970
4072
|
try {
|
|
3971
4073
|
const isOnLoginPage = window.location.pathname === "/login" || window.location.pathname.startsWith("/login");
|
|
@@ -3980,7 +4082,7 @@ var PaceLoginPage = ({
|
|
|
3980
4082
|
}, 100);
|
|
3981
4083
|
return () => clearTimeout(timeoutId);
|
|
3982
4084
|
}, [eventService]);
|
|
3983
|
-
|
|
4085
|
+
useEffect(() => {
|
|
3984
4086
|
if (!requireAppAccess || !isAuthenticated || isLoading || !user || !supabase) {
|
|
3985
4087
|
return;
|
|
3986
4088
|
}
|
|
@@ -4068,8 +4170,11 @@ var PaceLoginPage = ({
|
|
|
4068
4170
|
setIsSigningIn(false);
|
|
4069
4171
|
}
|
|
4070
4172
|
};
|
|
4071
|
-
|
|
4072
|
-
/* @__PURE__ */
|
|
4173
|
+
if (!authContext) {
|
|
4174
|
+
return /* @__PURE__ */ jsx("main", { className: "min-h-screen flex items-center justify-center", children: /* @__PURE__ */ jsx("section", { className: "text-center", children: /* @__PURE__ */ jsx("p", { children: "Loading..." }) }) });
|
|
4175
|
+
}
|
|
4176
|
+
return /* @__PURE__ */ jsxs("main", { className: "min-h-screen grid mx-auto w-fit content-center justify-items-center gap-y-8", "aria-label": `${appName} Login Page`, children: [
|
|
4177
|
+
/* @__PURE__ */ jsx(
|
|
4073
4178
|
"img",
|
|
4074
4179
|
{
|
|
4075
4180
|
src: `/${appName.toLowerCase()}_logo_square.svg`,
|
|
@@ -4077,7 +4182,7 @@ var PaceLoginPage = ({
|
|
|
4077
4182
|
className: "h-48"
|
|
4078
4183
|
}
|
|
4079
4184
|
),
|
|
4080
|
-
/* @__PURE__ */
|
|
4185
|
+
/* @__PURE__ */ jsx(
|
|
4081
4186
|
LoginForm,
|
|
4082
4187
|
{
|
|
4083
4188
|
className: "w-md",
|
|
@@ -4091,20 +4196,17 @@ var PaceLoginPage = ({
|
|
|
4091
4196
|
),
|
|
4092
4197
|
(() => {
|
|
4093
4198
|
const benign = !!(authError && (authError.name === "AuthSessionMissingError" || /Auth session missing/i.test(authError.message)));
|
|
4094
|
-
return authError && !benign ? /* @__PURE__ */
|
|
4199
|
+
return authError && !benign ? /* @__PURE__ */ jsx("em", { className: "mt-4 text-destructive text-center", children: authError.message }) : null;
|
|
4095
4200
|
})(),
|
|
4096
|
-
accessError && /* @__PURE__ */
|
|
4097
|
-
isCheckingAccess && /* @__PURE__ */
|
|
4201
|
+
accessError && /* @__PURE__ */ jsx("em", { className: "mt-4 text-destructive text-center", children: accessError }),
|
|
4202
|
+
isCheckingAccess && /* @__PURE__ */ jsx("em", { className: "mt-4 text-muted-foreground text-center", children: "Checking permissions..." })
|
|
4098
4203
|
] });
|
|
4099
4204
|
};
|
|
4100
|
-
|
|
4101
|
-
// src/components/SessionRestorationLoader/SessionRestorationLoader.tsx
|
|
4102
|
-
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4103
4205
|
var SessionRestorationLoader = ({
|
|
4104
4206
|
message = "Restoring session...",
|
|
4105
4207
|
className
|
|
4106
4208
|
}) => {
|
|
4107
|
-
return /* @__PURE__ */
|
|
4209
|
+
return /* @__PURE__ */ jsxs(
|
|
4108
4210
|
Alert,
|
|
4109
4211
|
{
|
|
4110
4212
|
className: cn(
|
|
@@ -4115,17 +4217,12 @@ var SessionRestorationLoader = ({
|
|
|
4115
4217
|
"aria-live": "polite",
|
|
4116
4218
|
"aria-label": message,
|
|
4117
4219
|
children: [
|
|
4118
|
-
/* @__PURE__ */
|
|
4119
|
-
/* @__PURE__ */
|
|
4220
|
+
/* @__PURE__ */ jsx(LoadingSpinner, { size: "lg" }),
|
|
4221
|
+
/* @__PURE__ */ jsx("span", { className: "text-sm text-sec-600", children: message })
|
|
4120
4222
|
]
|
|
4121
4223
|
}
|
|
4122
4224
|
);
|
|
4123
4225
|
};
|
|
4124
|
-
|
|
4125
|
-
// src/components/ProtectedRoute/ProtectedRoute.tsx
|
|
4126
|
-
import { useMemo as useMemo9, useEffect as useEffect9, useRef as useRef8, useState as useState14 } from "react";
|
|
4127
|
-
import { Navigate, Outlet as Outlet2 } from "react-router-dom";
|
|
4128
|
-
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4129
4226
|
function ProtectedRoute({
|
|
4130
4227
|
requireEvent = false,
|
|
4131
4228
|
noEventsFallback,
|
|
@@ -4139,17 +4236,17 @@ function ProtectedRoute({
|
|
|
4139
4236
|
const eventLoading = requireEvent ? eventsContext.isLoading || false : false;
|
|
4140
4237
|
const sessionRestoration = useSessionRestoration();
|
|
4141
4238
|
usePreventTabReload({ enabled: true, gracePeriodMs: 2e3 });
|
|
4142
|
-
const wasAuthenticatedRef =
|
|
4143
|
-
const [shouldRedirect, setShouldRedirect] =
|
|
4144
|
-
const tabJustBecameVisibleRef =
|
|
4145
|
-
|
|
4239
|
+
const wasAuthenticatedRef = useRef(false);
|
|
4240
|
+
const [shouldRedirect, setShouldRedirect] = useState(false);
|
|
4241
|
+
const tabJustBecameVisibleRef = useRef(false);
|
|
4242
|
+
useEffect(() => {
|
|
4146
4243
|
if (isAuthenticated) {
|
|
4147
4244
|
wasAuthenticatedRef.current = true;
|
|
4148
4245
|
setShouldRedirect(false);
|
|
4149
4246
|
tabJustBecameVisibleRef.current = false;
|
|
4150
4247
|
}
|
|
4151
4248
|
}, [isAuthenticated]);
|
|
4152
|
-
|
|
4249
|
+
useEffect(() => {
|
|
4153
4250
|
if (typeof document === "undefined") return;
|
|
4154
4251
|
let timeoutId = null;
|
|
4155
4252
|
let wasHidden = document.hidden;
|
|
@@ -4193,13 +4290,13 @@ function ProtectedRoute({
|
|
|
4193
4290
|
}
|
|
4194
4291
|
};
|
|
4195
4292
|
}, [isAuthenticated]);
|
|
4196
|
-
|
|
4293
|
+
useEffect(() => {
|
|
4197
4294
|
if (isAuthenticated) {
|
|
4198
4295
|
setShouldRedirect(false);
|
|
4199
4296
|
tabJustBecameVisibleRef.current = false;
|
|
4200
4297
|
}
|
|
4201
4298
|
}, [isAuthenticated]);
|
|
4202
|
-
const isRestoringSession =
|
|
4299
|
+
const isRestoringSession = useMemo(() => {
|
|
4203
4300
|
return sessionRestoration.isRestoring && !sessionRestoration.restorationComplete && !sessionRestoration.restorationError && !sessionRestoration.hasTimedOut;
|
|
4204
4301
|
}, [
|
|
4205
4302
|
sessionRestoration.isRestoring,
|
|
@@ -4208,13 +4305,13 @@ function ProtectedRoute({
|
|
|
4208
4305
|
sessionRestoration.hasTimedOut
|
|
4209
4306
|
]);
|
|
4210
4307
|
if (isRestoringSession) {
|
|
4211
|
-
return /* @__PURE__ */
|
|
4308
|
+
return /* @__PURE__ */ jsx(SessionRestorationLoader, {});
|
|
4212
4309
|
}
|
|
4213
4310
|
if (requireEvent && eventLoading) {
|
|
4214
|
-
return /* @__PURE__ */
|
|
4311
|
+
return /* @__PURE__ */ jsx(Outlet, {});
|
|
4215
4312
|
}
|
|
4216
4313
|
if (isLoading && !sessionRestoration.hasTimedOut) {
|
|
4217
|
-
return loadingFallback || /* @__PURE__ */
|
|
4314
|
+
return loadingFallback || /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx(LoadingSpinner, {}) });
|
|
4218
4315
|
}
|
|
4219
4316
|
if (!isAuthenticated) {
|
|
4220
4317
|
if (sessionRestoration.hasTimedOut || sessionRestoration.restorationError) {
|
|
@@ -4222,41 +4319,37 @@ function ProtectedRoute({
|
|
|
4222
4319
|
timedOut: sessionRestoration.hasTimedOut,
|
|
4223
4320
|
error: sessionRestoration.restorationError?.message
|
|
4224
4321
|
});
|
|
4225
|
-
return /* @__PURE__ */
|
|
4322
|
+
return /* @__PURE__ */ jsx(Navigate, { to: loginPath, replace: true });
|
|
4226
4323
|
}
|
|
4227
4324
|
if (!wasAuthenticatedRef.current) {
|
|
4228
|
-
return /* @__PURE__ */
|
|
4325
|
+
return /* @__PURE__ */ jsx(Navigate, { to: loginPath, replace: true });
|
|
4229
4326
|
}
|
|
4230
4327
|
const isTabVisible = typeof document !== "undefined" && !document.hidden;
|
|
4231
4328
|
if (tabJustBecameVisibleRef.current || isTabVisible && wasAuthenticatedRef.current && isLoading) {
|
|
4232
|
-
return loadingFallback || /* @__PURE__ */
|
|
4329
|
+
return loadingFallback || /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx(LoadingSpinner, {}) });
|
|
4233
4330
|
}
|
|
4234
4331
|
if (shouldRedirect) {
|
|
4235
|
-
return /* @__PURE__ */
|
|
4332
|
+
return /* @__PURE__ */ jsx(Navigate, { to: loginPath, replace: true });
|
|
4236
4333
|
}
|
|
4237
4334
|
if (isLoading) {
|
|
4238
|
-
return loadingFallback || /* @__PURE__ */
|
|
4335
|
+
return loadingFallback || /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx(LoadingSpinner, {}) });
|
|
4239
4336
|
}
|
|
4240
|
-
return /* @__PURE__ */
|
|
4337
|
+
return /* @__PURE__ */ jsx(Navigate, { to: loginPath, replace: true });
|
|
4241
4338
|
}
|
|
4242
4339
|
if (!requireEvent) {
|
|
4243
|
-
return /* @__PURE__ */
|
|
4340
|
+
return /* @__PURE__ */ jsx(Outlet, {});
|
|
4244
4341
|
}
|
|
4245
4342
|
if (!events || events.length === 0) {
|
|
4246
|
-
return noEventsFallback || /* @__PURE__ */
|
|
4247
|
-
/* @__PURE__ */
|
|
4248
|
-
/* @__PURE__ */
|
|
4343
|
+
return noEventsFallback || /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "100vh", padding: "2rem" }, children: /* @__PURE__ */ jsxs(Alert, { variant: "destructive", className: "max-w-md", children: [
|
|
4344
|
+
/* @__PURE__ */ jsx(AlertTitle, { children: "No Events Available" }),
|
|
4345
|
+
/* @__PURE__ */ jsx(AlertDescription, { children: "You don't have access to any events. Please contact your administrator if you believe this is an error." })
|
|
4249
4346
|
] }) });
|
|
4250
4347
|
}
|
|
4251
4348
|
if (!selectedEvent) {
|
|
4252
|
-
return /* @__PURE__ */
|
|
4349
|
+
return /* @__PURE__ */ jsx(Outlet, {});
|
|
4253
4350
|
}
|
|
4254
|
-
return /* @__PURE__ */
|
|
4351
|
+
return /* @__PURE__ */ jsx(Outlet, {});
|
|
4255
4352
|
}
|
|
4256
|
-
|
|
4257
|
-
// src/components/FileUpload/FileUpload.tsx
|
|
4258
|
-
import { useState as useState15, useCallback as useCallback10, useRef as useRef9, useEffect as useEffect10, useMemo as useMemo10 } from "react";
|
|
4259
|
-
import { Fragment as Fragment10, jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4260
4353
|
function FileUpload({
|
|
4261
4354
|
supabase,
|
|
4262
4355
|
table_name,
|
|
@@ -4289,14 +4382,14 @@ function FileUpload({
|
|
|
4289
4382
|
}
|
|
4290
4383
|
throw new Error(errorMsg);
|
|
4291
4384
|
}
|
|
4292
|
-
const [isDragging, setIsDragging] =
|
|
4293
|
-
const [uploadStates, setUploadStates] =
|
|
4294
|
-
const [resolvedAppId, setResolvedAppId] =
|
|
4295
|
-
const [isResolvingAppId, setIsResolvingAppId] =
|
|
4296
|
-
const [appIdError, setAppIdError] =
|
|
4297
|
-
const fileInputRef =
|
|
4385
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
4386
|
+
const [uploadStates, setUploadStates] = useState(/* @__PURE__ */ new Map());
|
|
4387
|
+
const [resolvedAppId, setResolvedAppId] = useState(app_id || null);
|
|
4388
|
+
const [isResolvingAppId, setIsResolvingAppId] = useState(!app_id);
|
|
4389
|
+
const [appIdError, setAppIdError] = useState(null);
|
|
4390
|
+
const fileInputRef = useRef(null);
|
|
4298
4391
|
const { uploadFile, isLoading, error } = useFileReference(supabase);
|
|
4299
|
-
|
|
4392
|
+
useEffect(() => {
|
|
4300
4393
|
if (app_id) {
|
|
4301
4394
|
setResolvedAppId(app_id);
|
|
4302
4395
|
setIsResolvingAppId(false);
|
|
@@ -4331,15 +4424,15 @@ function FileUpload({
|
|
|
4331
4424
|
};
|
|
4332
4425
|
resolveAppId();
|
|
4333
4426
|
}, [app_id, supabase]);
|
|
4334
|
-
const isUploading =
|
|
4427
|
+
const isUploading = useMemo(() => {
|
|
4335
4428
|
return uploadStates.size > 0 && Array.from(uploadStates.values()).some(
|
|
4336
4429
|
(state) => state.progress.status === "uploading" || state.progress.status === "processing"
|
|
4337
4430
|
);
|
|
4338
4431
|
}, [uploadStates]);
|
|
4339
|
-
const isDisabled =
|
|
4432
|
+
const isDisabled = useMemo(() => {
|
|
4340
4433
|
return disabled || isUploading || isResolvingAppId || !resolvedAppId;
|
|
4341
4434
|
}, [disabled, isUploading, isResolvingAppId, resolvedAppId]);
|
|
4342
|
-
const generatePreview =
|
|
4435
|
+
const generatePreview = useCallback((file) => {
|
|
4343
4436
|
return new Promise((resolve) => {
|
|
4344
4437
|
if (!file.type.startsWith("image/")) {
|
|
4345
4438
|
resolve(null);
|
|
@@ -4353,7 +4446,7 @@ function FileUpload({
|
|
|
4353
4446
|
reader.readAsDataURL(file);
|
|
4354
4447
|
});
|
|
4355
4448
|
}, []);
|
|
4356
|
-
const validateFile =
|
|
4449
|
+
const validateFile = useCallback((file) => {
|
|
4357
4450
|
if (file.size > maxSize) {
|
|
4358
4451
|
return `File "${file.name}" exceeds maximum size of ${Math.round(maxSize / 1024 / 1024)}MB`;
|
|
4359
4452
|
}
|
|
@@ -4377,15 +4470,13 @@ function FileUpload({
|
|
|
4377
4470
|
}
|
|
4378
4471
|
return null;
|
|
4379
4472
|
}, [accept, maxSize]);
|
|
4380
|
-
const handleFileSelect =
|
|
4473
|
+
const handleFileSelect = useCallback(async (files) => {
|
|
4381
4474
|
if (!files || files.length === 0) return;
|
|
4382
4475
|
const fileArray = Array.from(files);
|
|
4383
|
-
const validationErrors = [];
|
|
4384
4476
|
const validFiles = [];
|
|
4385
4477
|
for (const file of fileArray) {
|
|
4386
4478
|
const error2 = validateFile(file);
|
|
4387
4479
|
if (error2) {
|
|
4388
|
-
validationErrors.push(error2);
|
|
4389
4480
|
onUploadError?.(error2, file);
|
|
4390
4481
|
} else {
|
|
4391
4482
|
validFiles.push(file);
|
|
@@ -4558,19 +4649,19 @@ function FileUpload({
|
|
|
4558
4649
|
}
|
|
4559
4650
|
}
|
|
4560
4651
|
}, [uploadFile, table_name, record_id, organisation_id, resolvedAppId, category, folder, isPublic, maxSize, onUploadSuccess, onUploadError, onProgress, validateFile, generatePreview, showPreview, appIdError, pageContext]);
|
|
4561
|
-
const handleDragOver =
|
|
4652
|
+
const handleDragOver = useCallback((e) => {
|
|
4562
4653
|
e.preventDefault();
|
|
4563
4654
|
e.stopPropagation();
|
|
4564
4655
|
if (!isDisabled) {
|
|
4565
4656
|
setIsDragging(true);
|
|
4566
4657
|
}
|
|
4567
4658
|
}, [isDisabled]);
|
|
4568
|
-
const handleDragLeave =
|
|
4659
|
+
const handleDragLeave = useCallback((e) => {
|
|
4569
4660
|
e.preventDefault();
|
|
4570
4661
|
e.stopPropagation();
|
|
4571
4662
|
setIsDragging(false);
|
|
4572
4663
|
}, []);
|
|
4573
|
-
const handleDrop =
|
|
4664
|
+
const handleDrop = useCallback((e) => {
|
|
4574
4665
|
e.preventDefault();
|
|
4575
4666
|
e.stopPropagation();
|
|
4576
4667
|
setIsDragging(false);
|
|
@@ -4578,13 +4669,13 @@ function FileUpload({
|
|
|
4578
4669
|
const files = e.dataTransfer.files;
|
|
4579
4670
|
handleFileSelect(files);
|
|
4580
4671
|
}, [isDisabled, handleFileSelect]);
|
|
4581
|
-
const handleFileInputChange =
|
|
4672
|
+
const handleFileInputChange = useCallback((e) => {
|
|
4582
4673
|
handleFileSelect(e.target.files);
|
|
4583
4674
|
if (e.target) {
|
|
4584
4675
|
e.target.value = "";
|
|
4585
4676
|
}
|
|
4586
4677
|
}, [handleFileSelect]);
|
|
4587
|
-
const handleClick =
|
|
4678
|
+
const handleClick = useCallback(() => {
|
|
4588
4679
|
if (!isDisabled && fileInputRef.current) {
|
|
4589
4680
|
fileInputRef.current.click();
|
|
4590
4681
|
}
|
|
@@ -4598,8 +4689,8 @@ function FileUpload({
|
|
|
4598
4689
|
};
|
|
4599
4690
|
const dragClasses = isDragging ? "border-main-500 bg-main-50" : "border-sec-300 hover:border-sec-400";
|
|
4600
4691
|
const disabledClasses = isDisabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-sec-50";
|
|
4601
|
-
return /* @__PURE__ */
|
|
4602
|
-
/* @__PURE__ */
|
|
4692
|
+
return /* @__PURE__ */ jsxs("div", { className: `space-y-4 ${className}`, children: [
|
|
4693
|
+
/* @__PURE__ */ jsxs(
|
|
4603
4694
|
"div",
|
|
4604
4695
|
{
|
|
4605
4696
|
role: "button",
|
|
@@ -4618,8 +4709,8 @@ function FileUpload({
|
|
|
4618
4709
|
}
|
|
4619
4710
|
} : void 0,
|
|
4620
4711
|
children: [
|
|
4621
|
-
children || /* @__PURE__ */
|
|
4622
|
-
/* @__PURE__ */
|
|
4712
|
+
children || /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
4713
|
+
/* @__PURE__ */ jsx(
|
|
4623
4714
|
"input",
|
|
4624
4715
|
{
|
|
4625
4716
|
ref: fileInputRef,
|
|
@@ -4633,64 +4724,64 @@ function FileUpload({
|
|
|
4633
4724
|
"aria-label": accept ? `Upload file${multiple ? "s" : ""} (${accept})` : `Upload file${multiple ? "s" : ""}`
|
|
4634
4725
|
}
|
|
4635
4726
|
),
|
|
4636
|
-
/* @__PURE__ */
|
|
4637
|
-
/* @__PURE__ */
|
|
4727
|
+
/* @__PURE__ */ jsx("div", { className: "text-sec-600", children: isResolvingAppId ? "Resolving app configuration..." : isDragging ? "Drop files here..." : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4728
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium", children: "Click to upload" }),
|
|
4638
4729
|
" ",
|
|
4639
4730
|
"or drag and drop"
|
|
4640
4731
|
] }) }),
|
|
4641
|
-
/* @__PURE__ */
|
|
4732
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm text-sec-500", children: [
|
|
4642
4733
|
!isResolvingAppId && accept !== "*/*" && `Accepted formats: ${accept}`,
|
|
4643
4734
|
!isResolvingAppId && maxSize && ` \u2022 Max size: ${Math.round(maxSize / 1024 / 1024)}MB`,
|
|
4644
4735
|
!isResolvingAppId && multiple && " \u2022 Multiple files allowed"
|
|
4645
4736
|
] })
|
|
4646
4737
|
] }),
|
|
4647
|
-
isUploading && !showProgress && /* @__PURE__ */
|
|
4738
|
+
isUploading && !showProgress && /* @__PURE__ */ jsx(
|
|
4648
4739
|
"div",
|
|
4649
4740
|
{
|
|
4650
4741
|
className: "absolute inset-0 bg-white bg-opacity-75 flex items-center justify-center",
|
|
4651
4742
|
role: "status",
|
|
4652
4743
|
"aria-live": "polite",
|
|
4653
4744
|
"aria-label": "Uploading file",
|
|
4654
|
-
children: /* @__PURE__ */
|
|
4745
|
+
children: /* @__PURE__ */ jsx("div", { className: "animate-spin rounded-full size-8 border-b-2 border-main-500", "aria-hidden": "true" })
|
|
4655
4746
|
}
|
|
4656
4747
|
)
|
|
4657
4748
|
]
|
|
4658
4749
|
}
|
|
4659
4750
|
),
|
|
4660
|
-
showProgress && uploadStates.size > 0 && /* @__PURE__ */
|
|
4751
|
+
showProgress && uploadStates.size > 0 && /* @__PURE__ */ jsx("div", { className: "space-y-2", children: Array.from(uploadStates.entries()).map(([fileId, uploadState]) => {
|
|
4661
4752
|
const { file, progress, preview, result } = uploadState;
|
|
4662
4753
|
const isError = progress.status === "error";
|
|
4663
4754
|
const isCompleted = progress.status === "completed";
|
|
4664
4755
|
const isUploading2 = progress.status === "uploading" || progress.status === "processing";
|
|
4665
|
-
return /* @__PURE__ */
|
|
4756
|
+
return /* @__PURE__ */ jsxs(
|
|
4666
4757
|
"div",
|
|
4667
4758
|
{
|
|
4668
4759
|
className: `flex items-center space-x-3 p-3 rounded-lg border ${isError ? "bg-acc-50 border-acc-200" : isCompleted ? "bg-success-50 border-success-200" : "bg-sec-50 border-sec-200"}`,
|
|
4669
4760
|
children: [
|
|
4670
|
-
/* @__PURE__ */
|
|
4761
|
+
/* @__PURE__ */ jsx("div", { className: "flex-shrink-0", children: preview ? /* @__PURE__ */ jsx(
|
|
4671
4762
|
"img",
|
|
4672
4763
|
{
|
|
4673
4764
|
src: preview,
|
|
4674
4765
|
alt: file.name,
|
|
4675
4766
|
className: "w-12 h-12 object-cover rounded"
|
|
4676
4767
|
}
|
|
4677
|
-
) : /* @__PURE__ */
|
|
4678
|
-
/* @__PURE__ */
|
|
4679
|
-
/* @__PURE__ */
|
|
4680
|
-
/* @__PURE__ */
|
|
4768
|
+
) : /* @__PURE__ */ jsx("div", { className: "w-12 h-12 flex items-center justify-center bg-sec-200 rounded", children: /* @__PURE__ */ jsx("span", { className: "text-2xl", children: "\u{1F4C4}" }) }) }),
|
|
4769
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-1 min-w-0", children: [
|
|
4770
|
+
/* @__PURE__ */ jsx("div", { className: "font-medium text-sec-900 truncate", children: file.name }),
|
|
4771
|
+
/* @__PURE__ */ jsxs("div", { className: "text-sm text-sec-500", children: [
|
|
4681
4772
|
formatFileSize(file.size),
|
|
4682
4773
|
isCompleted && result && " \u2022 Uploaded",
|
|
4683
4774
|
isError && progress.error && ` \u2022 ${progress.error}`
|
|
4684
4775
|
] }),
|
|
4685
|
-
showProgress && (isUploading2 || isError) && /* @__PURE__ */
|
|
4686
|
-
/* @__PURE__ */
|
|
4776
|
+
showProgress && (isUploading2 || isError) && /* @__PURE__ */ jsxs("div", { className: "mt-2", children: [
|
|
4777
|
+
/* @__PURE__ */ jsx("div", { className: "w-full bg-sec-200 rounded-full h-2", children: /* @__PURE__ */ jsx(
|
|
4687
4778
|
"div",
|
|
4688
4779
|
{
|
|
4689
4780
|
className: `h-2 rounded-full transition-all duration-300 ${isError ? "bg-acc-500" : "bg-main-500"}`,
|
|
4690
4781
|
style: { width: `${progress.percentage}%` }
|
|
4691
4782
|
}
|
|
4692
4783
|
) }),
|
|
4693
|
-
isUploading2 && /* @__PURE__ */
|
|
4784
|
+
isUploading2 && /* @__PURE__ */ jsxs("div", { className: "text-xs text-sec-500 mt-1", children: [
|
|
4694
4785
|
progress.percentage,
|
|
4695
4786
|
"% \u2022 ",
|
|
4696
4787
|
formatFileSize(progress.loaded),
|
|
@@ -4699,10 +4790,10 @@ function FileUpload({
|
|
|
4699
4790
|
] })
|
|
4700
4791
|
] })
|
|
4701
4792
|
] }),
|
|
4702
|
-
/* @__PURE__ */
|
|
4703
|
-
isCompleted && /* @__PURE__ */
|
|
4704
|
-
isError && /* @__PURE__ */
|
|
4705
|
-
isUploading2 && /* @__PURE__ */
|
|
4793
|
+
/* @__PURE__ */ jsxs("div", { className: "flex-shrink-0", children: [
|
|
4794
|
+
isCompleted && /* @__PURE__ */ jsx("span", { className: "text-success-500 text-xl", children: "\u2713" }),
|
|
4795
|
+
isError && /* @__PURE__ */ jsx("span", { className: "text-acc-500 text-xl", children: "\u2715" }),
|
|
4796
|
+
isUploading2 && /* @__PURE__ */ jsx(
|
|
4706
4797
|
"div",
|
|
4707
4798
|
{
|
|
4708
4799
|
className: "animate-spin rounded-full size-5 border-b-2 border-main-500",
|
|
@@ -4717,7 +4808,7 @@ function FileUpload({
|
|
|
4717
4808
|
fileId
|
|
4718
4809
|
);
|
|
4719
4810
|
}) }),
|
|
4720
|
-
appIdError && /* @__PURE__ */
|
|
4811
|
+
appIdError && /* @__PURE__ */ jsx(
|
|
4721
4812
|
"div",
|
|
4722
4813
|
{
|
|
4723
4814
|
className: "p-3 bg-acc-50 border border-acc-200 rounded-lg text-sm text-acc-600",
|
|
@@ -4726,7 +4817,7 @@ function FileUpload({
|
|
|
4726
4817
|
children: appIdError
|
|
4727
4818
|
}
|
|
4728
4819
|
),
|
|
4729
|
-
error && /* @__PURE__ */
|
|
4820
|
+
error && /* @__PURE__ */ jsx(
|
|
4730
4821
|
"div",
|
|
4731
4822
|
{
|
|
4732
4823
|
className: "p-3 bg-acc-50 border border-acc-200 rounded-lg text-sm text-acc-600",
|
|
@@ -4737,11 +4828,7 @@ function FileUpload({
|
|
|
4737
4828
|
)
|
|
4738
4829
|
] });
|
|
4739
4830
|
}
|
|
4740
|
-
|
|
4741
|
-
// src/components/Table/Table.tsx
|
|
4742
|
-
import * as React20 from "react";
|
|
4743
|
-
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
4744
|
-
var Table = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
4831
|
+
var Table = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4745
4832
|
"table",
|
|
4746
4833
|
{
|
|
4747
4834
|
ref,
|
|
@@ -4750,9 +4837,9 @@ var Table = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
4750
4837
|
}
|
|
4751
4838
|
));
|
|
4752
4839
|
Table.displayName = "Table";
|
|
4753
|
-
var TableHeader =
|
|
4840
|
+
var TableHeader = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
|
|
4754
4841
|
TableHeader.displayName = "TableHeader";
|
|
4755
|
-
var TableBody =
|
|
4842
|
+
var TableBody = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4756
4843
|
"tbody",
|
|
4757
4844
|
{
|
|
4758
4845
|
ref,
|
|
@@ -4761,7 +4848,7 @@ var TableBody = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
4761
4848
|
}
|
|
4762
4849
|
));
|
|
4763
4850
|
TableBody.displayName = "TableBody";
|
|
4764
|
-
var TableFooter =
|
|
4851
|
+
var TableFooter = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4765
4852
|
"tfoot",
|
|
4766
4853
|
{
|
|
4767
4854
|
ref,
|
|
@@ -4773,7 +4860,7 @@ var TableFooter = React20.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
4773
4860
|
}
|
|
4774
4861
|
));
|
|
4775
4862
|
TableFooter.displayName = "TableFooter";
|
|
4776
|
-
var TableRow =
|
|
4863
|
+
var TableRow = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4777
4864
|
"tr",
|
|
4778
4865
|
{
|
|
4779
4866
|
ref,
|
|
@@ -4785,7 +4872,7 @@ var TableRow = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
4785
4872
|
}
|
|
4786
4873
|
));
|
|
4787
4874
|
TableRow.displayName = "TableRow";
|
|
4788
|
-
var TableHead =
|
|
4875
|
+
var TableHead = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4789
4876
|
"th",
|
|
4790
4877
|
{
|
|
4791
4878
|
ref,
|
|
@@ -4797,7 +4884,7 @@ var TableHead = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
4797
4884
|
}
|
|
4798
4885
|
));
|
|
4799
4886
|
TableHead.displayName = "TableHead";
|
|
4800
|
-
var TableCell =
|
|
4887
|
+
var TableCell = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4801
4888
|
"td",
|
|
4802
4889
|
{
|
|
4803
4890
|
ref,
|
|
@@ -4806,7 +4893,7 @@ var TableCell = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
4806
4893
|
}
|
|
4807
4894
|
));
|
|
4808
4895
|
TableCell.displayName = "TableCell";
|
|
4809
|
-
var TableCaption =
|
|
4896
|
+
var TableCaption = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx(
|
|
4810
4897
|
"caption",
|
|
4811
4898
|
{
|
|
4812
4899
|
ref,
|
|
@@ -4815,9 +4902,6 @@ var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
4815
4902
|
}
|
|
4816
4903
|
));
|
|
4817
4904
|
TableCaption.displayName = "TableCaption";
|
|
4818
|
-
|
|
4819
|
-
// src/components/PublicLayout/PublicPageLayout.tsx
|
|
4820
|
-
import { Fragment as Fragment11, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4821
4905
|
function PublicPageHeader({
|
|
4822
4906
|
event,
|
|
4823
4907
|
eventCode,
|
|
@@ -4830,11 +4914,11 @@ function PublicPageHeader({
|
|
|
4830
4914
|
customEventLogo
|
|
4831
4915
|
}) {
|
|
4832
4916
|
const { appName } = useAppConfig();
|
|
4833
|
-
return /* @__PURE__ */
|
|
4917
|
+
return /* @__PURE__ */ jsxs("header", { className: cn(
|
|
4834
4918
|
"w-full px-[max(0rem,calc((100vw-var(--app-width))/2-0.5rem))] grid grid-cols-[auto_1fr_auto] place-items-center gap-2",
|
|
4835
4919
|
className
|
|
4836
4920
|
), children: [
|
|
4837
|
-
showAppLogo && appName && /* @__PURE__ */
|
|
4921
|
+
showAppLogo && appName && /* @__PURE__ */ jsx(
|
|
4838
4922
|
"img",
|
|
4839
4923
|
{
|
|
4840
4924
|
className: "ml-4 max-w-36 object-contain row-span-2",
|
|
@@ -4842,9 +4926,9 @@ function PublicPageHeader({
|
|
|
4842
4926
|
alt: appName
|
|
4843
4927
|
}
|
|
4844
4928
|
),
|
|
4845
|
-
event && /* @__PURE__ */
|
|
4846
|
-
/* @__PURE__ */
|
|
4847
|
-
showEventLogo && event && /* @__PURE__ */
|
|
4929
|
+
event && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4930
|
+
/* @__PURE__ */ jsx("h1", { children: event.event_name }),
|
|
4931
|
+
showEventLogo && event && /* @__PURE__ */ jsx(Fragment, { children: customEventLogo || /* @__PURE__ */ jsx(
|
|
4848
4932
|
FileDisplay,
|
|
4849
4933
|
{
|
|
4850
4934
|
table_name: "event",
|
|
@@ -4861,13 +4945,13 @@ function PublicPageHeader({
|
|
|
4861
4945
|
}
|
|
4862
4946
|
}
|
|
4863
4947
|
) }),
|
|
4864
|
-
event.event_venue && /* @__PURE__ */
|
|
4948
|
+
event.event_venue && /* @__PURE__ */ jsx("h4", { children: event.event_venue })
|
|
4865
4949
|
] }),
|
|
4866
|
-
title && /* @__PURE__ */
|
|
4867
|
-
/* @__PURE__ */
|
|
4868
|
-
description && /* @__PURE__ */
|
|
4950
|
+
title && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4951
|
+
/* @__PURE__ */ jsx("h1", { children: title }),
|
|
4952
|
+
description && /* @__PURE__ */ jsx("p", { className: "text-lg text-sec-600 max-w-3xl mx-auto", children: description })
|
|
4869
4953
|
] }),
|
|
4870
|
-
children && /* @__PURE__ */
|
|
4954
|
+
children && /* @__PURE__ */ jsx(Fragment, { children })
|
|
4871
4955
|
] });
|
|
4872
4956
|
}
|
|
4873
4957
|
function PublicPageFooter({
|
|
@@ -4881,11 +4965,11 @@ function PublicPageFooter({
|
|
|
4881
4965
|
children
|
|
4882
4966
|
}) {
|
|
4883
4967
|
const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
|
|
4884
|
-
return /* @__PURE__ */
|
|
4885
|
-
logo && /* @__PURE__ */
|
|
4886
|
-
children && /* @__PURE__ */
|
|
4887
|
-
/* @__PURE__ */
|
|
4888
|
-
links && links.length > 0 && /* @__PURE__ */
|
|
4968
|
+
return /* @__PURE__ */ jsx("footer", { className: cn("mt-8 py-6 flex justify-center", className), children: /* @__PURE__ */ jsxs("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
|
|
4969
|
+
logo && /* @__PURE__ */ jsx("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
|
|
4970
|
+
children && /* @__PURE__ */ jsx(Fragment, { children }),
|
|
4971
|
+
/* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: copyrightText }),
|
|
4972
|
+
links && links.length > 0 && /* @__PURE__ */ jsx("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
|
|
4889
4973
|
] }) });
|
|
4890
4974
|
}
|
|
4891
4975
|
function PublicPageLayout({
|
|
@@ -4908,96 +4992,51 @@ function PublicPageLayout({
|
|
|
4908
4992
|
});
|
|
4909
4993
|
if (isLoading) {
|
|
4910
4994
|
if (LoadingFallback) {
|
|
4911
|
-
return /* @__PURE__ */
|
|
4995
|
+
return /* @__PURE__ */ jsx(LoadingFallback, {});
|
|
4912
4996
|
}
|
|
4913
|
-
return /* @__PURE__ */
|
|
4914
|
-
/* @__PURE__ */
|
|
4915
|
-
|
|
4916
|
-
|
|
4997
|
+
return /* @__PURE__ */ jsxs("p", { className: "grid place-items-center text-center size-full", children: [
|
|
4998
|
+
/* @__PURE__ */ jsx(
|
|
4999
|
+
LoadingSpinner,
|
|
5000
|
+
{
|
|
5001
|
+
size: "lg"
|
|
5002
|
+
}
|
|
5003
|
+
),
|
|
5004
|
+
/* @__PURE__ */ jsx("br", {}),
|
|
5005
|
+
loadingMessage || "Loading..."
|
|
5006
|
+
] });
|
|
4917
5007
|
}
|
|
4918
5008
|
if (error && showValidationErrors) {
|
|
4919
5009
|
if (ErrorFallback) {
|
|
4920
|
-
return /* @__PURE__ */
|
|
5010
|
+
return /* @__PURE__ */ jsx(ErrorFallback, { error, retry: handleRefetch });
|
|
4921
5011
|
}
|
|
4922
|
-
return /* @__PURE__ */
|
|
4923
|
-
/* @__PURE__ */
|
|
4924
|
-
/* @__PURE__ */
|
|
5012
|
+
return /* @__PURE__ */ jsxs("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
|
|
5013
|
+
/* @__PURE__ */ jsx("h1", { children: "Event Not Found" }),
|
|
5014
|
+
/* @__PURE__ */ jsxs("p", { children: [
|
|
4925
5015
|
'The event code "',
|
|
4926
5016
|
eventCode,
|
|
4927
5017
|
'" is invalid or the event is not available for public viewing.'
|
|
4928
5018
|
] }),
|
|
4929
|
-
/* @__PURE__ */
|
|
5019
|
+
/* @__PURE__ */ jsx(Button, { onClick: handleRefetch, children: "Try Again" })
|
|
4930
5020
|
] });
|
|
4931
5021
|
}
|
|
4932
5022
|
if (!event && showValidationErrors) {
|
|
4933
|
-
return /* @__PURE__ */
|
|
4934
|
-
/* @__PURE__ */
|
|
4935
|
-
/* @__PURE__ */
|
|
4936
|
-
handleRefetch && /* @__PURE__ */
|
|
5023
|
+
return /* @__PURE__ */ jsxs("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
|
|
5024
|
+
/* @__PURE__ */ jsx("h1", { children: "Event Not Available" }),
|
|
5025
|
+
/* @__PURE__ */ jsx("p", { children: "This event is not available for public viewing." }),
|
|
5026
|
+
handleRefetch && /* @__PURE__ */ jsx(Button, { onClick: handleRefetch, children: "Try Again" })
|
|
4937
5027
|
] });
|
|
4938
5028
|
}
|
|
4939
|
-
return /* @__PURE__ */
|
|
4940
|
-
customHeader || /* @__PURE__ */
|
|
5029
|
+
return /* @__PURE__ */ jsx(ErrorBoundary, { componentName: "PublicPageLayout", children: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5030
|
+
customHeader || /* @__PURE__ */ jsx(
|
|
4941
5031
|
PublicPageHeader,
|
|
4942
5032
|
{
|
|
4943
5033
|
event: event || void 0,
|
|
4944
5034
|
eventCode
|
|
4945
5035
|
}
|
|
4946
5036
|
),
|
|
4947
|
-
/* @__PURE__ */
|
|
4948
|
-
showFooter && event && (customFooter || /* @__PURE__ */
|
|
5037
|
+
/* @__PURE__ */ jsx("main", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children }),
|
|
5038
|
+
showFooter && event && (customFooter || /* @__PURE__ */ jsx(PublicPageFooter, { event }))
|
|
4949
5039
|
] }) });
|
|
4950
5040
|
}
|
|
4951
5041
|
|
|
4952
|
-
export {
|
|
4953
|
-
AddressField,
|
|
4954
|
-
Label,
|
|
4955
|
-
Textarea,
|
|
4956
|
-
FileDisplay,
|
|
4957
|
-
useFileReference,
|
|
4958
|
-
useFileReferenceForRecord,
|
|
4959
|
-
useFileReferenceById,
|
|
4960
|
-
useFilesByCategory,
|
|
4961
|
-
Avatar,
|
|
4962
|
-
Badge,
|
|
4963
|
-
Switch,
|
|
4964
|
-
Tabs,
|
|
4965
|
-
TabsList,
|
|
4966
|
-
TabsTrigger,
|
|
4967
|
-
TabsContent,
|
|
4968
|
-
Calendar,
|
|
4969
|
-
ToastProvider,
|
|
4970
|
-
ToastViewport,
|
|
4971
|
-
Toast,
|
|
4972
|
-
ToastAction,
|
|
4973
|
-
ToastClose,
|
|
4974
|
-
ToastTitle,
|
|
4975
|
-
ToastDescription,
|
|
4976
|
-
Toaster,
|
|
4977
|
-
Form,
|
|
4978
|
-
FormField,
|
|
4979
|
-
LoginForm,
|
|
4980
|
-
ContextSelector,
|
|
4981
|
-
PasswordChangeForm,
|
|
4982
|
-
UserMenu,
|
|
4983
|
-
NavigationMenu,
|
|
4984
|
-
Header,
|
|
4985
|
-
Footer,
|
|
4986
|
-
PaceAppLayout,
|
|
4987
|
-
PaceLoginPage,
|
|
4988
|
-
SessionRestorationLoader,
|
|
4989
|
-
ProtectedRoute,
|
|
4990
|
-
FileUpload,
|
|
4991
|
-
Table,
|
|
4992
|
-
TableHeader,
|
|
4993
|
-
TableBody,
|
|
4994
|
-
TableFooter,
|
|
4995
|
-
TableRow,
|
|
4996
|
-
TableHead,
|
|
4997
|
-
TableCell,
|
|
4998
|
-
TableCaption,
|
|
4999
|
-
PublicPageHeader,
|
|
5000
|
-
PublicPageFooter,
|
|
5001
|
-
PublicPageLayout
|
|
5002
|
-
};
|
|
5003
|
-
//# sourceMappingURL=chunk-I6DAQMWX.js.map
|
|
5042
|
+
export { AddressField, Avatar, Badge, Calendar, ContextSelector, FileDisplay, FileUpload, Footer, Form, FormField, Header, Label, LoginForm, NavigationMenu, PaceAppLayout, PaceLoginPage, PasswordChangeForm, ProtectedRoute, PublicPageFooter, PublicPageHeader, PublicPageLayout, SessionRestorationLoader, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, Textarea, Toast, ToastAction, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport, Toaster, UserMenu, useFileReference, useFileReferenceById, useFileReferenceForRecord, useFilesByCategory };
|