@jmruthers/pace-core 0.5.189 → 0.5.191
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/core-usage-manifest.json +0 -4
- package/dist/{AuthService-B-cd2MA4.d.ts → AuthService-CbP_utw2.d.ts} +7 -3
- package/dist/{DataTable-IVYljGJ6.d.ts → DataTable-Be6dH_dR.d.ts} +1 -1
- package/dist/{DataTable-GUFUNZ3N.js → DataTable-WKRZD47S.js} +8 -8
- package/dist/{PublicPageProvider-B8HaLe69.d.ts → PublicPageProvider-ULXC_u6U.d.ts} +84 -25
- package/dist/{UnifiedAuthProvider-BG0AL5eE.d.ts → UnifiedAuthProvider-BYA9qB-o.d.ts} +4 -3
- package/dist/{UnifiedAuthProvider-643PUAIM.js → UnifiedAuthProvider-FTSG5XH7.js} +4 -2
- package/dist/{api-YP7XD5L6.js → api-IHKALJZD.js} +4 -2
- package/dist/{chunk-VGZZXKBR.js → chunk-6LTQQAT6.js} +351 -157
- package/dist/chunk-6LTQQAT6.js.map +1 -0
- package/dist/{chunk-MX64ZF6I.js → chunk-6TQDD426.js} +15 -15
- package/dist/chunk-6TQDD426.js.map +1 -0
- package/dist/{chunk-YHCN776L.js → chunk-G37KK66H.js} +2 -75
- package/dist/chunk-G37KK66H.js.map +1 -0
- package/dist/{chunk-THRPYOFK.js → chunk-HW3OVDUF.js} +5 -5
- package/dist/chunk-HW3OVDUF.js.map +1 -0
- package/dist/{chunk-F2IMUDXZ.js → chunk-I7PSE6JW.js} +75 -2
- package/dist/chunk-I7PSE6JW.js.map +1 -0
- package/dist/{chunk-IM4QE42D.js → chunk-LOMZXPSN.js} +141 -326
- package/dist/chunk-LOMZXPSN.js.map +1 -0
- package/dist/chunk-OETXORNB.js +614 -0
- package/dist/chunk-OETXORNB.js.map +1 -0
- package/dist/{chunk-HESYZWZW.js → chunk-QWWZ5CAQ.js} +2 -2
- package/dist/{chunk-HEHYGYOX.js → chunk-ROXMHMY2.js} +403 -46
- package/dist/chunk-ROXMHMY2.js.map +1 -0
- package/dist/{chunk-2UUZZJFT.js → chunk-ULHIJK66.js} +228 -177
- package/dist/{chunk-2UUZZJFT.js.map → chunk-ULHIJK66.js.map} +1 -1
- package/dist/{chunk-YGPFYGA6.js → chunk-VKB2CO4Z.js} +838 -503
- package/dist/chunk-VKB2CO4Z.js.map +1 -0
- package/dist/{chunk-3GOZZZYH.js → chunk-VRGWKHDB.js} +238 -301
- package/dist/chunk-VRGWKHDB.js.map +1 -0
- package/dist/{chunk-UCQSRW7Z.js → chunk-XNYQOL3Z.js} +431 -384
- package/dist/chunk-XNYQOL3Z.js.map +1 -0
- package/dist/{chunk-DDM4CCYT.js → chunk-XYXSXPUK.js} +79 -59
- package/dist/chunk-XYXSXPUK.js.map +1 -0
- package/dist/{chunk-SAUPYVLF.js → chunk-ZSAAAMVR.js} +1 -1
- package/dist/chunk-ZSAAAMVR.js.map +1 -0
- package/dist/components.d.ts +5 -6
- package/dist/components.js +19 -19
- package/dist/components.js.map +1 -1
- package/dist/{database.generated-DI89OQeI.d.ts → database.generated-CzIvgcPu.d.ts} +165 -201
- package/dist/eslint-rules/pace-core-compliance.cjs +0 -2
- package/dist/{file-reference-D037xOFK.d.ts → file-reference-BavO2eQj.d.ts} +13 -10
- package/dist/hooks.d.ts +20 -15
- package/dist/hooks.js +14 -8
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +17 -15
- package/dist/index.js +86 -81
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +3 -1
- package/dist/rbac/index.d.ts +77 -13
- package/dist/rbac/index.js +12 -9
- package/dist/{types-Bwgl--Xo.d.ts → types-CEpcvwwF.d.ts} +1 -1
- package/dist/types.d.ts +3 -3
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-CTDELQ7H.d.ts → usePublicRouteParams-TZe0gy-4.d.ts} +17 -10
- package/dist/utils.d.ts +8 -8
- package/dist/utils.js +16 -16
- package/docs/README.md +2 -2
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +2 -2
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +2 -2
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +5 -5
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +2 -2
- package/docs/api/classes/SecureSupabaseClient.md +25 -20
- package/docs/api/classes/StorageUtils.md +7 -4
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +1 -1
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AddressFieldProps.md +1 -1
- package/docs/api/interfaces/AddressFieldRef.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/AutocompleteOptions.md +1 -1
- package/docs/api/interfaces/AvatarProps.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.md +20 -6
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +9 -9
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +62 -16
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +2 -2
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +26 -12
- package/docs/api/interfaces/FileUploadProps.md +30 -19
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
- package/docs/api/interfaces/NavigationContextType.md +9 -9
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +7 -7
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +8 -8
- package/docs/api/interfaces/PagePermissionContextType.md +8 -8
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.md +2 -2
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProgressProps.md +3 -11
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/QuickFix.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +2 -2
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
- package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +10 -10
- package/docs/api/interfaces/RouteConfig.md +10 -10
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +9 -9
- package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- package/docs/api/interfaces/SetupIssue.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +4 -4
- package/docs/api/interfaces/StorageFileInfo.md +7 -7
- package/docs/api/interfaces/StorageFileMetadata.md +25 -14
- package/docs/api/interfaces/StorageListOptions.md +22 -9
- package/docs/api/interfaces/StorageListResult.md +4 -4
- package/docs/api/interfaces/StorageUploadOptions.md +21 -8
- package/docs/api/interfaces/StorageUploadResult.md +6 -6
- package/docs/api/interfaces/StorageUrlOptions.md +19 -6
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +1 -1
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +5 -5
- package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +11 -11
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +165 -106
- package/docs/api-reference/components.md +15 -7
- package/docs/api-reference/providers.md +2 -2
- package/docs/api-reference/rpc-functions.md +1 -0
- package/docs/best-practices/README.md +1 -1
- package/docs/best-practices/deployment.md +8 -8
- package/docs/getting-started/examples/README.md +2 -2
- package/docs/getting-started/installation-guide.md +4 -4
- package/docs/getting-started/quick-start.md +3 -3
- package/docs/migration/MIGRATION_GUIDE.md +3 -3
- package/docs/migration/README.md +18 -0
- package/docs/migration/database-changes-december-2025.md +767 -0
- package/docs/migration/person-scoped-profiles-migration-guide.md +472 -0
- package/docs/rbac/compliance/compliance-guide.md +2 -2
- package/docs/rbac/event-based-apps.md +2 -2
- package/docs/rbac/getting-started.md +2 -2
- package/docs/rbac/quick-start.md +2 -2
- package/docs/security/README.md +4 -4
- package/docs/standards/07-rbac-and-rls-standard.md +430 -7
- package/docs/troubleshooting/README.md +2 -2
- package/docs/troubleshooting/migration.md +3 -3
- package/package.json +1 -3
- package/scripts/check-pace-core-compliance.cjs +1 -1
- package/scripts/check-pace-core-compliance.js +1 -1
- package/src/__tests__/fixtures/supabase.ts +301 -0
- package/src/__tests__/public-recipe-view.test.ts +19 -19
- package/src/__tests__/rls-policies.test.ts +210 -74
- package/src/components/AddressField/AddressField.test.tsx +42 -0
- package/src/components/AddressField/AddressField.tsx +71 -60
- package/src/components/AddressField/README.md +7 -6
- package/src/components/Alert/Alert.test.tsx +50 -10
- package/src/components/Alert/Alert.tsx +5 -3
- package/src/components/Avatar/Avatar.test.tsx +95 -43
- package/src/components/Avatar/Avatar.tsx +16 -16
- package/src/components/Button/Button.test.tsx +2 -1
- package/src/components/Button/Button.tsx +3 -3
- package/src/components/Calendar/Calendar.test.tsx +53 -37
- package/src/components/Calendar/Calendar.tsx +409 -82
- package/src/components/Card/Card.test.tsx +7 -4
- package/src/components/Card/Card.tsx +3 -6
- package/src/components/Checkbox/Checkbox.tsx +2 -2
- package/src/components/DataTable/components/ActionButtons.tsx +5 -5
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
- package/src/components/DataTable/components/ColumnFilter.tsx +1 -1
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +3 -3
- package/src/components/DataTable/components/DataTableBody.tsx +12 -12
- package/src/components/DataTable/components/DataTableCore.tsx +3 -3
- package/src/components/DataTable/components/DataTableToolbar.tsx +5 -5
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +3 -3
- package/src/components/DataTable/components/EditableRow.tsx +2 -2
- package/src/components/DataTable/components/EmptyState.tsx +3 -3
- package/src/components/DataTable/components/GroupHeader.tsx +2 -2
- package/src/components/DataTable/components/GroupingDropdown.tsx +1 -1
- package/src/components/DataTable/components/ImportModal.tsx +4 -4
- package/src/components/DataTable/components/LoadingState.tsx +1 -1
- package/src/components/DataTable/components/PaginationControls.tsx +11 -11
- package/src/components/DataTable/components/UnifiedTableBody.tsx +9 -9
- package/src/components/DataTable/components/ViewRowModal.tsx +2 -2
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +11 -37
- package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +157 -0
- package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +2 -1
- package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +128 -0
- package/src/components/DataTable/core/__tests__/ActionManager.test.ts +19 -0
- package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +51 -0
- package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +84 -0
- package/src/components/DataTable/core/__tests__/DataManager.test.ts +14 -0
- package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +136 -0
- package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +16 -0
- package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +18 -0
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +28 -7
- package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +30 -1
- package/src/components/DataTable/utils/hierarchicalUtils.ts +38 -10
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -3
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +4 -4
- package/src/components/Dialog/Dialog.tsx +2 -2
- package/src/components/EventSelector/EventSelector.tsx +7 -7
- package/src/components/FileDisplay/FileDisplay.tsx +291 -179
- package/src/components/FileUpload/FileUpload.tsx +7 -4
- package/src/components/Header/Header.test.tsx +28 -0
- package/src/components/Header/Header.tsx +22 -9
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +2 -2
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +19 -14
- package/src/components/LoadingSpinner/LoadingSpinner.tsx +5 -5
- package/src/components/NavigationMenu/NavigationMenu.test.tsx +127 -1
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +42 -22
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +4 -0
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +3 -0
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +3 -0
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +16 -6
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +37 -3
- package/src/components/PaceAppLayout/test-setup.tsx +1 -0
- package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +66 -45
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +6 -4
- package/src/components/Progress/Progress.test.tsx +18 -19
- package/src/components/Progress/Progress.tsx +31 -32
- package/src/components/PublicLayout/PublicLayout.test.tsx +6 -6
- package/src/components/PublicLayout/PublicPageProvider.tsx +5 -3
- package/src/components/Select/Select.test.tsx +4 -1
- package/src/components/Select/Select.tsx +65 -20
- package/src/components/Switch/Switch.test.tsx +2 -1
- package/src/components/Switch/Switch.tsx +1 -1
- package/src/components/Toast/Toast.tsx +1 -1
- package/src/components/Tooltip/Tooltip.test.tsx +8 -2
- package/src/components/UserMenu/UserMenu.tsx +3 -3
- package/src/eslint-rules/pace-core-compliance.cjs +0 -2
- package/src/eslint-rules/pace-core-compliance.js +0 -2
- package/src/hooks/__tests__/hooks.integration.test.tsx +4 -1
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +76 -5
- package/src/hooks/__tests__/useDataTableState.test.ts +76 -0
- package/src/hooks/__tests__/useFileUrl.unit.test.ts +25 -69
- package/src/hooks/__tests__/useFileUrlCache.test.ts +129 -0
- package/src/hooks/__tests__/usePreventTabReload.test.ts +88 -0
- package/src/hooks/__tests__/usePublicEvent.simple.test.ts +1 -1
- package/src/hooks/__tests__/usePublicEvent.test.ts +608 -0
- package/src/hooks/__tests__/useQueryCache.test.ts +144 -0
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +67 -24
- package/src/hooks/index.ts +1 -1
- package/src/hooks/public/usePublicEvent.ts +10 -10
- package/src/hooks/public/usePublicFileDisplay.ts +173 -87
- package/src/hooks/useAppConfig.ts +24 -5
- package/src/hooks/useFileDisplay.ts +298 -36
- package/src/hooks/useFileReference.ts +56 -11
- package/src/hooks/useFileUrl.ts +1 -1
- package/src/hooks/useInactivityTracker.ts +16 -7
- package/src/hooks/usePermissionCache.test.ts +85 -8
- package/src/hooks/useQueryCache.ts +27 -6
- package/src/hooks/useSecureDataAccess.test.ts +87 -42
- package/src/hooks/useSecureDataAccess.ts +95 -48
- package/src/providers/__tests__/OrganisationProvider.test.tsx +27 -21
- package/src/providers/services/EventServiceProvider.tsx +37 -17
- package/src/providers/services/InactivityServiceProvider.tsx +4 -4
- package/src/providers/services/OrganisationServiceProvider.tsx +8 -1
- package/src/providers/services/UnifiedAuthProvider.tsx +115 -29
- package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +451 -0
- package/src/rbac/__tests__/engine.comprehensive.test.ts +12 -0
- package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +8 -0
- package/src/rbac/__tests__/rbac-engine-simplified.test.ts +4 -0
- package/src/rbac/api.ts +240 -36
- package/src/rbac/cache-invalidation.ts +21 -7
- package/src/rbac/compliance/quick-fix-suggestions.ts +1 -1
- package/src/rbac/components/NavigationGuard.tsx +23 -63
- package/src/rbac/components/NavigationProvider.test.tsx +52 -23
- package/src/rbac/components/NavigationProvider.tsx +13 -11
- package/src/rbac/components/PagePermissionGuard.tsx +77 -203
- package/src/rbac/components/PagePermissionProvider.tsx +13 -11
- package/src/rbac/components/PermissionEnforcer.tsx +24 -62
- package/src/rbac/components/RoleBasedRouter.tsx +14 -12
- package/src/rbac/components/SecureDataProvider.tsx +13 -11
- package/src/rbac/components/__tests__/NavigationGuard.test.tsx +104 -41
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +49 -12
- package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +22 -1
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +161 -82
- package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +22 -1
- package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +77 -30
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +39 -5
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +47 -4
- package/src/rbac/engine.ts +4 -2
- package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +144 -52
- package/src/rbac/hooks/index.ts +3 -0
- package/src/rbac/hooks/useCan.test.ts +101 -53
- package/src/rbac/hooks/usePermissions.ts +108 -41
- package/src/rbac/hooks/useRBAC.test.ts +11 -3
- package/src/rbac/hooks/useRBAC.ts +83 -40
- package/src/rbac/hooks/useResolvedScope.test.ts +189 -63
- package/src/rbac/hooks/useResolvedScope.ts +128 -70
- package/src/rbac/hooks/useSecureSupabase.ts +36 -19
- package/src/rbac/hooks/useSuperAdminBypass.ts +126 -0
- package/src/rbac/request-deduplication.ts +1 -1
- package/src/rbac/secureClient.ts +72 -12
- package/src/rbac/security.ts +29 -23
- package/src/rbac/types.ts +10 -0
- package/src/rbac/utils/__tests__/contextValidator.test.ts +150 -0
- package/src/rbac/utils/__tests__/deep-equal.test.ts +53 -0
- package/src/rbac/utils/__tests__/eventContext.test.ts +8 -3
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +74 -12
- package/src/rbac/utils/contextValidator.ts +288 -0
- package/src/rbac/utils/eventContext.ts +52 -3
- package/src/services/AuthService.ts +37 -8
- package/src/services/EventService.ts +165 -21
- package/src/services/OrganisationService.ts +125 -137
- package/src/services/__tests__/EventService.test.ts +26 -21
- package/src/services/__tests__/OrganisationService.pagination.test.ts +34 -8
- package/src/services/__tests__/OrganisationService.test.ts +218 -86
- package/src/types/database.generated.ts +166 -201
- package/src/types/file-reference.ts +13 -10
- package/src/types/supabase.ts +2 -2
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +3 -2
- package/src/utils/app/appNameResolver.test.ts +346 -73
- package/src/utils/context/superAdminOverride.ts +58 -0
- package/src/utils/file-reference/index.ts +65 -37
- package/src/utils/google-places/googlePlacesUtils.test.ts +98 -0
- package/src/utils/google-places/googlePlacesUtils.ts +1 -1
- package/src/utils/google-places/loadGoogleMapsScript.test.ts +83 -0
- package/src/utils/google-places/types.ts +1 -1
- package/src/utils/request-deduplication.ts +4 -4
- package/src/utils/security/secureDataAccess.test.ts +1 -1
- package/src/utils/security/secureDataAccess.ts +7 -4
- package/src/utils/storage/README.md +1 -1
- package/src/utils/storage/helpers.test.ts +1 -1
- package/src/utils/storage/helpers.ts +38 -19
- package/src/utils/storage/types.ts +15 -8
- package/src/utils/validation/__tests__/csrf.test.ts +105 -0
- package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +92 -0
- package/src/vite-env.d.ts +2 -2
- package/dist/chunk-3GOZZZYH.js.map +0 -1
- package/dist/chunk-DDM4CCYT.js.map +0 -1
- package/dist/chunk-E7UAOUMY.js +0 -75
- package/dist/chunk-E7UAOUMY.js.map +0 -1
- package/dist/chunk-F2IMUDXZ.js.map +0 -1
- package/dist/chunk-HEHYGYOX.js.map +0 -1
- package/dist/chunk-IM4QE42D.js.map +0 -1
- package/dist/chunk-MX64ZF6I.js.map +0 -1
- package/dist/chunk-SAUPYVLF.js.map +0 -1
- package/dist/chunk-THRPYOFK.js.map +0 -1
- package/dist/chunk-UCQSRW7Z.js.map +0 -1
- package/dist/chunk-VGZZXKBR.js.map +0 -1
- package/dist/chunk-YGPFYGA6.js.map +0 -1
- package/dist/chunk-YHCN776L.js.map +0 -1
- /package/dist/{DataTable-GUFUNZ3N.js.map → DataTable-WKRZD47S.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-643PUAIM.js.map → UnifiedAuthProvider-FTSG5XH7.js.map} +0 -0
- /package/dist/{api-YP7XD5L6.js.map → api-IHKALJZD.js.map} +0 -0
- /package/dist/{chunk-HESYZWZW.js.map → chunk-QWWZ5CAQ.js.map} +0 -0
|
@@ -25,57 +25,57 @@ import {
|
|
|
25
25
|
SelectSeparator,
|
|
26
26
|
SelectTrigger,
|
|
27
27
|
SelectValue
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-ULHIJK66.js";
|
|
29
29
|
import {
|
|
30
30
|
useCan,
|
|
31
31
|
usePermissions,
|
|
32
|
-
useRBAC
|
|
33
|
-
|
|
34
|
-
} from "./chunk-3GOZZZYH.js";
|
|
35
|
-
import {
|
|
36
|
-
isSuperAdmin
|
|
37
|
-
} from "./chunk-HEHYGYOX.js";
|
|
32
|
+
useRBAC
|
|
33
|
+
} from "./chunk-VRGWKHDB.js";
|
|
38
34
|
import {
|
|
39
|
-
ErrorBoundary,
|
|
40
|
-
PublicPageContext,
|
|
41
35
|
createFileReferenceService,
|
|
42
36
|
generateFileUrlsBatch,
|
|
43
37
|
getPublicUrl,
|
|
44
38
|
getSignedUrl,
|
|
45
39
|
uploadFileWithReference,
|
|
46
40
|
useAddressAutocomplete,
|
|
47
|
-
useAppConfig,
|
|
48
41
|
useEventTheme,
|
|
49
42
|
useFileDisplay,
|
|
50
|
-
useIsPublicPage,
|
|
51
43
|
usePreventTabReload,
|
|
52
44
|
usePublicFileDisplay
|
|
53
|
-
} from "./chunk-
|
|
45
|
+
} from "./chunk-XNYQOL3Z.js";
|
|
54
46
|
import {
|
|
55
47
|
useToast
|
|
56
48
|
} from "./chunk-6C4YBBJM.js";
|
|
57
49
|
import {
|
|
50
|
+
ErrorBoundary,
|
|
51
|
+
PublicPageContext,
|
|
52
|
+
useAppConfig,
|
|
58
53
|
useEvents,
|
|
59
|
-
|
|
60
|
-
|
|
54
|
+
useIsPublicPage,
|
|
55
|
+
useResolvedScope
|
|
56
|
+
} from "./chunk-OETXORNB.js";
|
|
61
57
|
import {
|
|
62
58
|
EventServiceContext,
|
|
59
|
+
useOrganisations,
|
|
63
60
|
useSessionRestoration,
|
|
64
61
|
useUnifiedAuth
|
|
65
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-6LTQQAT6.js";
|
|
63
|
+
import {
|
|
64
|
+
isSuperAdmin
|
|
65
|
+
} from "./chunk-ROXMHMY2.js";
|
|
66
66
|
import {
|
|
67
67
|
assertAppId
|
|
68
68
|
} from "./chunk-QXHPKYJV.js";
|
|
69
69
|
import {
|
|
70
70
|
LoadingSpinner,
|
|
71
71
|
getAppId
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-HW3OVDUF.js";
|
|
73
73
|
import {
|
|
74
74
|
cn
|
|
75
75
|
} from "./chunk-R77UEZ4E.js";
|
|
76
76
|
import {
|
|
77
77
|
getCurrentAppName
|
|
78
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-I7PSE6JW.js";
|
|
79
79
|
import {
|
|
80
80
|
clearPalette
|
|
81
81
|
} from "./chunk-SQGMNID3.js";
|
|
@@ -229,47 +229,47 @@ var AddressField = React.forwardRef(
|
|
|
229
229
|
};
|
|
230
230
|
}
|
|
231
231
|
}, [isOpen]);
|
|
232
|
+
const suggestionsId = React.useId();
|
|
232
233
|
React.useEffect(() => {
|
|
233
|
-
if (selectedIndex >= 0
|
|
234
|
-
const selectedItem =
|
|
234
|
+
if (selectedIndex >= 0) {
|
|
235
|
+
const selectedItem = document.getElementById(
|
|
236
|
+
`${suggestionsId}-item-${selectedIndex}`
|
|
237
|
+
);
|
|
235
238
|
if (selectedItem && typeof selectedItem.scrollIntoView === "function") {
|
|
236
239
|
selectedItem.scrollIntoView({ block: "nearest", behavior: "smooth" });
|
|
237
240
|
}
|
|
238
241
|
}
|
|
239
|
-
}, [selectedIndex]);
|
|
242
|
+
}, [selectedIndex, suggestionsId]);
|
|
240
243
|
React.useImperativeHandle(ref, () => inputRef.current);
|
|
241
|
-
const suggestionsId = React.useId();
|
|
242
244
|
const hasError = error || !!autocompleteError;
|
|
243
|
-
return /* @__PURE__ */ jsxs("
|
|
244
|
-
/* @__PURE__ */
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
isLoading && /* @__PURE__ */ jsx("div", { className: "absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ jsx(LoadingSpinner, { size: "sm" }) })
|
|
270
|
-
] }),
|
|
245
|
+
return /* @__PURE__ */ jsxs("form", { ref: containerRef, className: cn("relative w-full", className), children: [
|
|
246
|
+
/* @__PURE__ */ jsx(
|
|
247
|
+
Input,
|
|
248
|
+
{
|
|
249
|
+
ref: inputRef,
|
|
250
|
+
type: "text",
|
|
251
|
+
value,
|
|
252
|
+
onChange: handleInputChange,
|
|
253
|
+
onKeyDown: handleKeyDown,
|
|
254
|
+
onFocus: handleFocus,
|
|
255
|
+
onBlur: handleBlur,
|
|
256
|
+
placeholder,
|
|
257
|
+
disabled,
|
|
258
|
+
error: hasError,
|
|
259
|
+
size,
|
|
260
|
+
variant,
|
|
261
|
+
role: "combobox",
|
|
262
|
+
"aria-expanded": isOpen,
|
|
263
|
+
"aria-autocomplete": "list",
|
|
264
|
+
"aria-controls": suggestionsId,
|
|
265
|
+
"aria-haspopup": "listbox",
|
|
266
|
+
"aria-activedescendant": selectedIndex >= 0 ? `${suggestionsId}-item-${selectedIndex}` : void 0,
|
|
267
|
+
...props
|
|
268
|
+
}
|
|
269
|
+
),
|
|
270
|
+
isLoading && /* @__PURE__ */ jsx("p", { className: "absolute right-3 top-1/2 -translate-y-1/2 pointer-events-none", children: /* @__PURE__ */ jsx(LoadingSpinner, { size: "sm" }) }),
|
|
271
271
|
isOpen && suggestions.length > 0 && /* @__PURE__ */ jsx(
|
|
272
|
-
"
|
|
272
|
+
"dl",
|
|
273
273
|
{
|
|
274
274
|
ref: suggestionsRef,
|
|
275
275
|
id: suggestionsId,
|
|
@@ -280,28 +280,28 @@ var AddressField = React.forwardRef(
|
|
|
280
280
|
"list-none p-0 m-0"
|
|
281
281
|
),
|
|
282
282
|
"data-testid": "address-suggestions",
|
|
283
|
-
children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsxs(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
suggestion.structured_formatting?.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
suggestion.
|
|
304
|
-
))
|
|
283
|
+
children: suggestions.map((suggestion, index) => /* @__PURE__ */ jsxs(React.Fragment, { children: [
|
|
284
|
+
/* @__PURE__ */ jsx(
|
|
285
|
+
"dt",
|
|
286
|
+
{
|
|
287
|
+
id: `${suggestionsId}-item-${index}`,
|
|
288
|
+
role: "option",
|
|
289
|
+
"aria-selected": selectedIndex === index,
|
|
290
|
+
className: cn(
|
|
291
|
+
"px-3 py-2 cursor-pointer text-sm",
|
|
292
|
+
"hover:bg-main-100 focus:bg-main-100",
|
|
293
|
+
"border-b border-main-200 last:border-b-0",
|
|
294
|
+
selectedIndex === index && "bg-main-100",
|
|
295
|
+
"font-medium text-main-900"
|
|
296
|
+
),
|
|
297
|
+
onClick: () => handleSelectAddress(suggestion.place_id),
|
|
298
|
+
onMouseEnter: () => setSelectedIndex(index),
|
|
299
|
+
"data-testid": `address-suggestion-${index}`,
|
|
300
|
+
children: suggestion.structured_formatting?.main_text || suggestion.description
|
|
301
|
+
}
|
|
302
|
+
),
|
|
303
|
+
suggestion.structured_formatting?.secondary_text && /* @__PURE__ */ jsx("dd", { className: "px-3 pb-2 text-xs text-main-600 mt-0.5", children: suggestion.structured_formatting.secondary_text })
|
|
304
|
+
] }, suggestion.place_id))
|
|
305
305
|
}
|
|
306
306
|
),
|
|
307
307
|
autocompleteError && /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-destructive", role: "alert", children: autocompleteError.message })
|
|
@@ -313,7 +313,7 @@ AddressField.displayName = "AddressField";
|
|
|
313
313
|
// src/components/Label/Label.tsx
|
|
314
314
|
import * as React2 from "react";
|
|
315
315
|
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
316
|
-
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
316
|
+
import { Fragment as Fragment2, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
317
317
|
var getLabelClasses = () => {
|
|
318
318
|
return "font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70";
|
|
319
319
|
};
|
|
@@ -332,7 +332,7 @@ var Label = React2.forwardRef(({
|
|
|
332
332
|
}, ref) => {
|
|
333
333
|
const hasError = !!error;
|
|
334
334
|
const showHelperText = helperText && !hasError;
|
|
335
|
-
return /* @__PURE__ */ jsxs2(
|
|
335
|
+
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
336
336
|
/* @__PURE__ */ jsxs2(
|
|
337
337
|
LabelPrimitive.Root,
|
|
338
338
|
{
|
|
@@ -482,15 +482,20 @@ function useFileUrl(fileReference, options) {
|
|
|
482
482
|
}
|
|
483
483
|
|
|
484
484
|
// src/components/FileDisplay/FileDisplay.tsx
|
|
485
|
-
import { Fragment as
|
|
485
|
+
import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
486
486
|
var fallbackSizeClasses = {
|
|
487
|
-
xs: "
|
|
488
|
-
sm: "
|
|
489
|
-
md: "
|
|
490
|
-
lg: "
|
|
491
|
-
xl: "
|
|
492
|
-
"2xl": "
|
|
487
|
+
xs: "size-4 text-xs",
|
|
488
|
+
sm: "size-6 text-sm",
|
|
489
|
+
md: "size-8 text-base",
|
|
490
|
+
lg: "size-12 text-lg",
|
|
491
|
+
xl: "size-16 text-xl",
|
|
492
|
+
"2xl": "size-20 text-2xl"
|
|
493
493
|
};
|
|
494
|
+
var fallbackBaseClasses = "size-full grid place-items-center text-center text-sec-600 font-semibold";
|
|
495
|
+
function getFallbackClasses(size = "md") {
|
|
496
|
+
const sizeClass = fallbackSizeClasses[size];
|
|
497
|
+
return `${fallbackBaseClasses} ${sizeClass}`.trim();
|
|
498
|
+
}
|
|
494
499
|
function defaultGenerateFallbackText(fileName) {
|
|
495
500
|
if (!fileName) return "FL";
|
|
496
501
|
const baseName = fileName.replace(/\.[^/.]+$/, "");
|
|
@@ -519,7 +524,10 @@ function FileDisplayContent({
|
|
|
519
524
|
showFallback = false,
|
|
520
525
|
generateFallbackText = defaultGenerateFallbackText,
|
|
521
526
|
fallbackText,
|
|
522
|
-
|
|
527
|
+
fallbackSourceText,
|
|
528
|
+
fallbackSize = "md",
|
|
529
|
+
enableChildren = false,
|
|
530
|
+
showMetadata = true
|
|
523
531
|
}) {
|
|
524
532
|
const [imageError, setImageError] = useState3(false);
|
|
525
533
|
const [internalFileUrls, setInternalFileUrls] = useState3(new Map(fileUrls));
|
|
@@ -527,14 +535,12 @@ function FileDisplayContent({
|
|
|
527
535
|
const fileReferencesRef = useRef3([]);
|
|
528
536
|
const computedFallbackText = useMemo(() => {
|
|
529
537
|
if (fallbackText) return fallbackText;
|
|
530
|
-
const
|
|
531
|
-
return generateFallbackText(
|
|
532
|
-
}, [fallbackText, fileReference, generateFallbackText]);
|
|
538
|
+
const sourceText = fallbackSourceText ?? fileReference?.file_metadata?.fileName;
|
|
539
|
+
return generateFallbackText(sourceText);
|
|
540
|
+
}, [fallbackText, fallbackSourceText, fileReference, generateFallbackText]);
|
|
533
541
|
const fallbackClasses = useMemo(() => {
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
return `${baseClasses} ${sizeClass} ${className}`.trim();
|
|
537
|
-
}, [fallbackSize, className]);
|
|
542
|
+
return getFallbackClasses(fallbackSize);
|
|
543
|
+
}, [fallbackSize]);
|
|
538
544
|
useEffect3(() => {
|
|
539
545
|
const currentIds = fileReferences.map((f) => f.id).join(",");
|
|
540
546
|
const prevIds = fileReferencesRef.current.map((f) => f.id).join(",");
|
|
@@ -555,20 +561,8 @@ function FileDisplayContent({
|
|
|
555
561
|
}
|
|
556
562
|
setImageError(false);
|
|
557
563
|
};
|
|
558
|
-
const handleImageError = (
|
|
564
|
+
const handleImageError = () => {
|
|
559
565
|
setImageError(true);
|
|
560
|
-
if (showFallback && e) {
|
|
561
|
-
const target = e.target;
|
|
562
|
-
target.style.display = "none";
|
|
563
|
-
if (target.nextSibling && target.nextSibling.className.includes("bg-sec-100")) {
|
|
564
|
-
return;
|
|
565
|
-
}
|
|
566
|
-
const fallback = document.createElement("div");
|
|
567
|
-
fallback.className = fallbackClasses;
|
|
568
|
-
fallback.textContent = computedFallbackText;
|
|
569
|
-
fallback.title = fileReference?.file_metadata?.fileName || "File";
|
|
570
|
-
target.parentNode?.insertBefore(fallback, target.nextSibling);
|
|
571
|
-
}
|
|
572
566
|
};
|
|
573
567
|
const getFileIcon = (fileType) => {
|
|
574
568
|
if (fileType.startsWith("image/")) return "\u{1F5BC}\uFE0F";
|
|
@@ -592,18 +586,18 @@ function FileDisplayContent({
|
|
|
592
586
|
return /* @__PURE__ */ jsx4(ErrorComponent, { error, retry: clearError });
|
|
593
587
|
}
|
|
594
588
|
if (showFallback) {
|
|
595
|
-
return /* @__PURE__ */ jsx4("
|
|
589
|
+
return /* @__PURE__ */ jsx4("figure", { className, title: "File unavailable", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: computedFallbackText }) });
|
|
596
590
|
}
|
|
597
|
-
return /* @__PURE__ */ jsxs3("
|
|
598
|
-
/* @__PURE__ */ jsxs3("
|
|
591
|
+
return /* @__PURE__ */ jsxs3("figure", { className, title: "Error", children: [
|
|
592
|
+
/* @__PURE__ */ jsxs3("p", { className: getFallbackClasses(fallbackSize || "md"), children: [
|
|
599
593
|
"Error loading file: ",
|
|
600
594
|
error instanceof Error ? error.message : String(error)
|
|
601
595
|
] }),
|
|
602
596
|
clearError && /* @__PURE__ */ jsx4(
|
|
603
|
-
|
|
597
|
+
Button,
|
|
604
598
|
{
|
|
605
599
|
onClick: clearError,
|
|
606
|
-
className: "mt-2
|
|
600
|
+
className: "mt-2",
|
|
607
601
|
"aria-label": "Retry loading file",
|
|
608
602
|
children: "Try again"
|
|
609
603
|
}
|
|
@@ -612,19 +606,19 @@ function FileDisplayContent({
|
|
|
612
606
|
}
|
|
613
607
|
if (fileCount === 0 && !isLoading) {
|
|
614
608
|
if (showFallback) {
|
|
615
|
-
return /* @__PURE__ */ jsxs3("
|
|
616
|
-
computedFallbackText,
|
|
609
|
+
return /* @__PURE__ */ jsxs3("figure", { className, title: "No file", children: [
|
|
610
|
+
/* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: computedFallbackText }),
|
|
617
611
|
children
|
|
618
612
|
] });
|
|
619
613
|
}
|
|
620
|
-
return /* @__PURE__ */ jsxs3("
|
|
621
|
-
"No files found",
|
|
614
|
+
return /* @__PURE__ */ jsxs3("figure", { className: `text-sec-500 text-center p-4 ${className}`, children: [
|
|
615
|
+
/* @__PURE__ */ jsx4("p", { children: "No files found" }),
|
|
622
616
|
children
|
|
623
617
|
] });
|
|
624
618
|
}
|
|
625
619
|
if (isLoading && showFallback && fileCount === 0) {
|
|
626
|
-
return /* @__PURE__ */ jsxs3("
|
|
627
|
-
computedFallbackText,
|
|
620
|
+
return /* @__PURE__ */ jsxs3("figure", { className, title: "Loading...", children: [
|
|
621
|
+
/* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: computedFallbackText }),
|
|
628
622
|
children
|
|
629
623
|
] });
|
|
630
624
|
}
|
|
@@ -632,98 +626,125 @@ function FileDisplayContent({
|
|
|
632
626
|
if (LoadingComponent) {
|
|
633
627
|
return /* @__PURE__ */ jsx4(LoadingComponent, {});
|
|
634
628
|
}
|
|
635
|
-
return /* @__PURE__ */ jsx4("
|
|
629
|
+
return /* @__PURE__ */ jsx4("figure", { className, title: "Loading", children: /* @__PURE__ */ jsx4("p", { className: "flex items-center justify-center p-4", children: /* @__PURE__ */ jsx4(LoadingSpinner, {}) }) });
|
|
636
630
|
}
|
|
637
631
|
if ((category || displayOnly) && fileReference) {
|
|
638
632
|
const isImage = fileReference.file_metadata.fileType?.startsWith("image/");
|
|
639
|
-
if (displayOnly && isImage && !showDelete) {
|
|
633
|
+
if (displayOnly && isImage && !showDelete && !enableChildren) {
|
|
640
634
|
if (imageError && showFallback) {
|
|
641
|
-
return /* @__PURE__ */ jsx4("
|
|
635
|
+
return /* @__PURE__ */ jsx4("figure", { className, title: fileReference.file_metadata.fileName || "File", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: computedFallbackText }) });
|
|
642
636
|
}
|
|
643
637
|
if (!fileUrl) {
|
|
644
|
-
return /* @__PURE__ */ jsx4("
|
|
638
|
+
return /* @__PURE__ */ jsx4("figure", { className: className || "max-w-full h-48", title: "Loading", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: /* @__PURE__ */ jsx4(LoadingSpinner, {}) }) });
|
|
645
639
|
}
|
|
646
|
-
return /* @__PURE__ */ jsx4(
|
|
640
|
+
return /* @__PURE__ */ jsx4("figure", { className: className || "max-w-full h-auto", children: /* @__PURE__ */ jsx4(
|
|
647
641
|
"img",
|
|
648
642
|
{
|
|
649
643
|
src: fileUrl,
|
|
650
644
|
alt: fileReference.file_metadata.fileName || "File",
|
|
651
|
-
className:
|
|
645
|
+
className: "max-w-full h-auto",
|
|
652
646
|
onError: handleImageError
|
|
653
647
|
}
|
|
654
|
-
);
|
|
648
|
+
) });
|
|
655
649
|
}
|
|
656
650
|
if (displayOnly && !isImage && fileUrl && fileReference && !showDelete) {
|
|
657
651
|
const fileName = fileReference.file_metadata?.fileName || "Document";
|
|
658
652
|
const ariaLabel = `Open ${fileName} in new tab`;
|
|
659
|
-
return /* @__PURE__ */ jsxs3(
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
653
|
+
return /* @__PURE__ */ jsxs3("figure", { className, children: [
|
|
654
|
+
/* @__PURE__ */ jsxs3(
|
|
655
|
+
"a",
|
|
656
|
+
{
|
|
657
|
+
href: fileUrl,
|
|
658
|
+
target: "_blank",
|
|
659
|
+
rel: "noopener noreferrer",
|
|
660
|
+
"aria-label": ariaLabel,
|
|
661
|
+
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",
|
|
662
|
+
children: [
|
|
663
|
+
/* @__PURE__ */ jsx4(FileText, { className: "size-5 shrink-0", "aria-hidden": "true" }),
|
|
664
|
+
/* @__PURE__ */ jsx4("span", { className: "flex-1 font-medium truncate", children: fileName }),
|
|
665
|
+
/* @__PURE__ */ jsx4(ExternalLink, { className: "size-5 shrink-0", "aria-hidden": "true" })
|
|
666
|
+
]
|
|
667
|
+
}
|
|
668
|
+
),
|
|
669
|
+
showMetadata && /* @__PURE__ */ jsxs3("figcaption", { children: [
|
|
670
|
+
/* @__PURE__ */ jsx4("p", { children: fileName }),
|
|
671
|
+
fileReference.file_metadata.fileSize && /* @__PURE__ */ jsxs3("p", { children: [
|
|
672
|
+
formatFileSize(fileReference.file_metadata.fileSize),
|
|
673
|
+
" \u2022 ",
|
|
674
|
+
fileReference.file_metadata.fileType
|
|
675
|
+
] })
|
|
676
|
+
] })
|
|
677
|
+
] });
|
|
674
678
|
}
|
|
675
679
|
if (displayOnly && showFallback && (!fileUrl || imageError || !isImage)) {
|
|
676
|
-
return /* @__PURE__ */ jsx4("
|
|
680
|
+
return /* @__PURE__ */ jsx4("figure", { className, title: fileReference.file_metadata.fileName || "File", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: computedFallbackText }) });
|
|
677
681
|
}
|
|
678
|
-
return /* @__PURE__ */
|
|
679
|
-
|
|
682
|
+
return /* @__PURE__ */ jsx4("figure", { className: `relative ${className}`, children: isImage && fileUrl && !imageError ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
683
|
+
/* @__PURE__ */ jsx4(
|
|
684
|
+
"img",
|
|
685
|
+
{
|
|
686
|
+
src: fileUrl,
|
|
687
|
+
alt: fileReference.file_metadata.fileName || "File",
|
|
688
|
+
className: "max-w-full h-auto",
|
|
689
|
+
onError: handleImageError
|
|
690
|
+
}
|
|
691
|
+
),
|
|
692
|
+
showDelete && /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
680
693
|
/* @__PURE__ */ jsx4(
|
|
681
|
-
|
|
694
|
+
Button,
|
|
682
695
|
{
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
696
|
+
variant: "destructive",
|
|
697
|
+
size: "icon",
|
|
698
|
+
onClick: handleDeleteClick,
|
|
699
|
+
className: "absolute top-2 right-2",
|
|
700
|
+
title: "Delete file",
|
|
701
|
+
"aria-label": "Delete file",
|
|
702
|
+
children: "\xD7"
|
|
687
703
|
}
|
|
688
704
|
),
|
|
689
|
-
|
|
690
|
-
/* @__PURE__ */ jsx4(
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
/* @__PURE__ */ jsx4(Button, { variant: "destructive", onClick: handleDeleteConfirm, children: "Delete" })
|
|
706
|
-
] })
|
|
707
|
-
] }) })
|
|
705
|
+
/* @__PURE__ */ jsx4(Dialog, { open: deleteDialogOpen, onOpenChange: setDeleteDialogOpen, children: /* @__PURE__ */ jsxs3(DialogContent, { size: "sm", children: [
|
|
706
|
+
/* @__PURE__ */ jsx4(DialogHeader, { children: /* @__PURE__ */ jsx4(DialogTitle, { children: "Confirm Delete" }) }),
|
|
707
|
+
/* @__PURE__ */ jsx4(DialogBody, { children: /* @__PURE__ */ jsx4("p", { children: "Are you sure you want to delete this file? This action cannot be undone." }) }),
|
|
708
|
+
/* @__PURE__ */ jsxs3(DialogFooter, { children: [
|
|
709
|
+
/* @__PURE__ */ jsx4(Button, { variant: "outline", onClick: () => setDeleteDialogOpen(false), children: "Cancel" }),
|
|
710
|
+
/* @__PURE__ */ jsx4(Button, { variant: "destructive", onClick: handleDeleteConfirm, children: "Delete" })
|
|
711
|
+
] })
|
|
712
|
+
] }) })
|
|
713
|
+
] }),
|
|
714
|
+
children,
|
|
715
|
+
showMetadata && /* @__PURE__ */ jsxs3("figcaption", { children: [
|
|
716
|
+
/* @__PURE__ */ jsx4("p", { children: fileReference.file_metadata.fileName || "Unknown file" }),
|
|
717
|
+
(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && /* @__PURE__ */ jsxs3("p", { children: [
|
|
718
|
+
fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize),
|
|
719
|
+
fileReference.file_metadata.fileSize && fileReference.file_metadata.fileType && " \u2022 ",
|
|
720
|
+
fileReference.file_metadata.fileType
|
|
708
721
|
] })
|
|
709
|
-
] })
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
/* @__PURE__ */ jsx4("
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
/* @__PURE__ */
|
|
722
|
+
] })
|
|
723
|
+
] }) : isImage && imageError && showFallback ? (
|
|
724
|
+
// Show fallback when image fails to load and fallback is enabled
|
|
725
|
+
/* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
726
|
+
/* @__PURE__ */ jsx4("p", { className: fallbackClasses, title: fileReference.file_metadata.fileName || "File", children: computedFallbackText }),
|
|
727
|
+
children,
|
|
728
|
+
showMetadata && /* @__PURE__ */ jsxs3("figcaption", { children: [
|
|
729
|
+
/* @__PURE__ */ jsx4("p", { children: fileReference.file_metadata.fileName || "Unknown file" }),
|
|
730
|
+
(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && /* @__PURE__ */ jsxs3("p", { children: [
|
|
717
731
|
fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize),
|
|
718
|
-
fileReference.file_metadata.fileType &&
|
|
732
|
+
fileReference.file_metadata.fileSize && fileReference.file_metadata.fileType && " \u2022 ",
|
|
733
|
+
fileReference.file_metadata.fileType
|
|
719
734
|
] })
|
|
720
|
-
] })
|
|
721
|
-
|
|
735
|
+
] })
|
|
736
|
+
] })
|
|
737
|
+
) : /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
738
|
+
/* @__PURE__ */ jsxs3("p", { className: "flex items-center space-x-3 p-3 bg-sec-50 rounded-lg border border-sec-200", children: [
|
|
739
|
+
/* @__PURE__ */ jsx4("span", { className: "text-2xl", children: getFileIcon(fileReference.file_metadata.fileType || "") }),
|
|
740
|
+
showDelete && /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
722
741
|
/* @__PURE__ */ jsx4(
|
|
723
|
-
|
|
742
|
+
Button,
|
|
724
743
|
{
|
|
744
|
+
variant: "destructive",
|
|
745
|
+
size: "icon",
|
|
725
746
|
onClick: handleDeleteClick,
|
|
726
|
-
className: "
|
|
747
|
+
className: "ml-auto",
|
|
727
748
|
title: "Delete file",
|
|
728
749
|
"aria-label": "Delete file",
|
|
729
750
|
children: "\xD7"
|
|
@@ -739,15 +760,23 @@ function FileDisplayContent({
|
|
|
739
760
|
] }) })
|
|
740
761
|
] })
|
|
741
762
|
] }),
|
|
742
|
-
children
|
|
743
|
-
|
|
763
|
+
children,
|
|
764
|
+
showMetadata && /* @__PURE__ */ jsxs3("figcaption", { children: [
|
|
765
|
+
/* @__PURE__ */ jsx4("p", { children: fileReference.file_metadata.fileName || "Unknown file" }),
|
|
766
|
+
(fileReference.file_metadata.fileSize || fileReference.file_metadata.fileType) && /* @__PURE__ */ jsxs3("p", { children: [
|
|
767
|
+
fileReference.file_metadata.fileSize && formatFileSize(fileReference.file_metadata.fileSize),
|
|
768
|
+
fileReference.file_metadata.fileSize && fileReference.file_metadata.fileType && " \u2022 ",
|
|
769
|
+
fileReference.file_metadata.fileType
|
|
770
|
+
] })
|
|
771
|
+
] })
|
|
772
|
+
] }) });
|
|
744
773
|
}
|
|
745
|
-
return /* @__PURE__ */ jsxs3("
|
|
774
|
+
return /* @__PURE__ */ jsxs3("figure", { className: `space-y-2 ${className}`, children: [
|
|
746
775
|
fileReferences.map((fileRef) => {
|
|
747
776
|
const isImage = fileRef.file_metadata.fileType?.startsWith("image/");
|
|
748
777
|
const fileUrl2 = internalFileUrls.get(fileRef.id) || null;
|
|
749
778
|
const canDownload = !isImage && fileUrl2;
|
|
750
|
-
return /* @__PURE__ */ jsxs3("
|
|
779
|
+
return /* @__PURE__ */ jsxs3("figure", { className: "flex items-center space-x-3 p-3 bg-sec-50 rounded-lg border border-sec-200", children: [
|
|
751
780
|
isImage && fileUrl2 ? /* @__PURE__ */ jsx4(
|
|
752
781
|
"img",
|
|
753
782
|
{
|
|
@@ -757,15 +786,17 @@ function FileDisplayContent({
|
|
|
757
786
|
onError: handleImageError
|
|
758
787
|
}
|
|
759
788
|
) : /* @__PURE__ */ jsx4("span", { className: "text-2xl", children: getFileIcon(fileRef.file_metadata.fileType || "") }),
|
|
760
|
-
/* @__PURE__ */ jsxs3("
|
|
761
|
-
/* @__PURE__ */ jsx4("
|
|
762
|
-
/* @__PURE__ */ jsxs3("
|
|
789
|
+
showMetadata && /* @__PURE__ */ jsxs3("figcaption", { className: "flex-1 min-w-0", children: [
|
|
790
|
+
/* @__PURE__ */ jsx4("p", { className: "font-medium text-sec-900 truncate", children: fileRef.file_metadata.fileName || "Unknown file" }),
|
|
791
|
+
(fileRef.file_metadata.fileSize || fileRef.file_metadata.fileType || fileRef.file_metadata.category) && /* @__PURE__ */ jsxs3("p", { className: "text-sm text-sec-500", children: [
|
|
763
792
|
fileRef.file_metadata.fileSize && formatFileSize(fileRef.file_metadata.fileSize),
|
|
764
|
-
fileRef.file_metadata.fileType &&
|
|
765
|
-
fileRef.file_metadata.
|
|
793
|
+
fileRef.file_metadata.fileSize && fileRef.file_metadata.fileType && " \u2022 ",
|
|
794
|
+
fileRef.file_metadata.fileType,
|
|
795
|
+
(fileRef.file_metadata.fileSize || fileRef.file_metadata.fileType) && fileRef.file_metadata.category && " \u2022 ",
|
|
796
|
+
fileRef.file_metadata.category
|
|
766
797
|
] })
|
|
767
798
|
] }),
|
|
768
|
-
/* @__PURE__ */ jsxs3("
|
|
799
|
+
/* @__PURE__ */ jsxs3("p", { className: "flex items-center space-x-2", children: [
|
|
769
800
|
canDownload && /* @__PURE__ */ jsx4(
|
|
770
801
|
"a",
|
|
771
802
|
{
|
|
@@ -777,10 +808,11 @@ function FileDisplayContent({
|
|
|
777
808
|
}
|
|
778
809
|
),
|
|
779
810
|
showDelete && onDelete && /* @__PURE__ */ jsx4(
|
|
780
|
-
|
|
811
|
+
Button,
|
|
781
812
|
{
|
|
813
|
+
variant: "destructive",
|
|
814
|
+
size: "icon",
|
|
782
815
|
onClick: handleDeleteClick,
|
|
783
|
-
className: "text-acc-500 hover:text-acc-700 p-1",
|
|
784
816
|
title: "Delete file",
|
|
785
817
|
"aria-label": "Delete file",
|
|
786
818
|
children: "\xD7"
|
|
@@ -806,7 +838,10 @@ function FileDisplayPublic({
|
|
|
806
838
|
showFallback,
|
|
807
839
|
generateFallbackText,
|
|
808
840
|
fallbackText,
|
|
809
|
-
|
|
841
|
+
fallbackSourceText,
|
|
842
|
+
fallbackSize,
|
|
843
|
+
enableChildren,
|
|
844
|
+
showMetadata
|
|
810
845
|
}) {
|
|
811
846
|
const publicPageContext = useContext(PublicPageContext);
|
|
812
847
|
const supabase = publicPageContext?.supabase ?? null;
|
|
@@ -834,11 +869,14 @@ function FileDisplayPublic({
|
|
|
834
869
|
showFallback,
|
|
835
870
|
generateFallbackText,
|
|
836
871
|
fallbackText,
|
|
837
|
-
|
|
872
|
+
fallbackSourceText,
|
|
873
|
+
fallbackSize,
|
|
874
|
+
enableChildren,
|
|
875
|
+
showMetadata
|
|
838
876
|
}
|
|
839
877
|
);
|
|
840
878
|
}
|
|
841
|
-
return /* @__PURE__ */ jsx4("
|
|
879
|
+
return /* @__PURE__ */ jsx4("figure", { className, title: "Error", children: /* @__PURE__ */ jsx4("p", { className: getFallbackClasses(fallbackSize || "md"), children: "Supabase client not available in public context" }) });
|
|
842
880
|
}
|
|
843
881
|
const {
|
|
844
882
|
fileUrl,
|
|
@@ -904,7 +942,10 @@ function FileDisplayPublic({
|
|
|
904
942
|
showFallback,
|
|
905
943
|
generateFallbackText,
|
|
906
944
|
fallbackText,
|
|
907
|
-
|
|
945
|
+
fallbackSourceText,
|
|
946
|
+
fallbackSize,
|
|
947
|
+
enableChildren,
|
|
948
|
+
showMetadata
|
|
908
949
|
}
|
|
909
950
|
);
|
|
910
951
|
}
|
|
@@ -922,11 +963,14 @@ function FileDisplayAuthenticated({
|
|
|
922
963
|
showFallback,
|
|
923
964
|
generateFallbackText,
|
|
924
965
|
fallbackText,
|
|
925
|
-
|
|
966
|
+
fallbackSourceText,
|
|
967
|
+
fallbackSize,
|
|
968
|
+
enableChildren,
|
|
969
|
+
showMetadata
|
|
926
970
|
}) {
|
|
927
971
|
const { supabase } = useUnifiedAuth();
|
|
928
972
|
if (!supabase) {
|
|
929
|
-
return /* @__PURE__ */ jsx4("
|
|
973
|
+
return /* @__PURE__ */ jsx4("figure", { className, title: "Error", children: /* @__PURE__ */ jsx4("p", { className: getFallbackClasses(fallbackSize || "md"), children: "Supabase client not available in authenticated context" }) });
|
|
930
974
|
}
|
|
931
975
|
const {
|
|
932
976
|
fileUrl,
|
|
@@ -1007,7 +1051,10 @@ function FileDisplayAuthenticated({
|
|
|
1007
1051
|
showFallback,
|
|
1008
1052
|
generateFallbackText,
|
|
1009
1053
|
fallbackText,
|
|
1010
|
-
|
|
1054
|
+
fallbackSourceText,
|
|
1055
|
+
fallbackSize,
|
|
1056
|
+
enableChildren,
|
|
1057
|
+
showMetadata
|
|
1011
1058
|
}
|
|
1012
1059
|
);
|
|
1013
1060
|
}
|
|
@@ -1025,7 +1072,10 @@ function FileDisplay({
|
|
|
1025
1072
|
showFallback,
|
|
1026
1073
|
generateFallbackText,
|
|
1027
1074
|
fallbackText,
|
|
1028
|
-
|
|
1075
|
+
fallbackSourceText,
|
|
1076
|
+
fallbackSize,
|
|
1077
|
+
enableChildren,
|
|
1078
|
+
showMetadata
|
|
1029
1079
|
}) {
|
|
1030
1080
|
const isPublicPage = useIsPublicPage();
|
|
1031
1081
|
if (isPublicPage) {
|
|
@@ -1045,7 +1095,10 @@ function FileDisplay({
|
|
|
1045
1095
|
showFallback,
|
|
1046
1096
|
generateFallbackText,
|
|
1047
1097
|
fallbackText,
|
|
1048
|
-
|
|
1098
|
+
fallbackSourceText,
|
|
1099
|
+
fallbackSize,
|
|
1100
|
+
enableChildren,
|
|
1101
|
+
showMetadata
|
|
1049
1102
|
}
|
|
1050
1103
|
);
|
|
1051
1104
|
}
|
|
@@ -1065,7 +1118,10 @@ function FileDisplay({
|
|
|
1065
1118
|
showFallback,
|
|
1066
1119
|
generateFallbackText,
|
|
1067
1120
|
fallbackText,
|
|
1068
|
-
|
|
1121
|
+
fallbackSourceText,
|
|
1122
|
+
fallbackSize,
|
|
1123
|
+
enableChildren,
|
|
1124
|
+
showMetadata
|
|
1069
1125
|
}
|
|
1070
1126
|
);
|
|
1071
1127
|
}
|
|
@@ -1073,6 +1129,36 @@ function FileDisplay({
|
|
|
1073
1129
|
// src/hooks/useFileReference.ts
|
|
1074
1130
|
import { useState as useState4, useCallback as useCallback4, useEffect as useEffect4, useRef as useRef4, useMemo as useMemo2 } from "react";
|
|
1075
1131
|
var log2 = createLogger("useFileReference");
|
|
1132
|
+
var urlRefreshManager = {
|
|
1133
|
+
subscriptions: /* @__PURE__ */ new Map(),
|
|
1134
|
+
subscribe(key, callback) {
|
|
1135
|
+
let entry = this.subscriptions.get(key);
|
|
1136
|
+
if (!entry) {
|
|
1137
|
+
entry = { callbacks: /* @__PURE__ */ new Set(), intervalId: null };
|
|
1138
|
+
this.subscriptions.set(key, entry);
|
|
1139
|
+
}
|
|
1140
|
+
entry.callbacks.add(callback);
|
|
1141
|
+
if (!entry.intervalId) {
|
|
1142
|
+
entry.intervalId = setInterval(() => {
|
|
1143
|
+
entry?.callbacks.forEach((cb) => cb());
|
|
1144
|
+
}, 55 * 60 * 1e3);
|
|
1145
|
+
}
|
|
1146
|
+
return () => {
|
|
1147
|
+
this.unsubscribe(key, callback);
|
|
1148
|
+
};
|
|
1149
|
+
},
|
|
1150
|
+
unsubscribe(key, callback) {
|
|
1151
|
+
const entry = this.subscriptions.get(key);
|
|
1152
|
+
if (!entry) return;
|
|
1153
|
+
entry.callbacks.delete(callback);
|
|
1154
|
+
if (entry.callbacks.size === 0) {
|
|
1155
|
+
if (entry.intervalId) {
|
|
1156
|
+
clearInterval(entry.intervalId);
|
|
1157
|
+
}
|
|
1158
|
+
this.subscriptions.delete(key);
|
|
1159
|
+
}
|
|
1160
|
+
}
|
|
1161
|
+
};
|
|
1076
1162
|
function useFileReference(supabase) {
|
|
1077
1163
|
const [isLoading, setIsLoading] = useState4(false);
|
|
1078
1164
|
const [error, setError] = useState4(null);
|
|
@@ -1243,7 +1329,7 @@ function useFileReferenceForRecord(supabase, table_name, record_id, organisation
|
|
|
1243
1329
|
const [fileReference, setFileReference] = useState4(null);
|
|
1244
1330
|
const [fileReferences, setFileReferences] = useState4([]);
|
|
1245
1331
|
const [fileCount, setFileCount] = useState4(0);
|
|
1246
|
-
const
|
|
1332
|
+
const refreshSubscriptionRef = useRef4(null);
|
|
1247
1333
|
const loadFileReference = useCallback4(async () => {
|
|
1248
1334
|
const reference = await getFileReference(table_name, record_id, organisation_id);
|
|
1249
1335
|
setFileReference(reference);
|
|
@@ -1274,23 +1360,24 @@ function useFileReferenceForRecord(supabase, table_name, record_id, organisation
|
|
|
1274
1360
|
return success;
|
|
1275
1361
|
}, [deleteFileReference, table_name, record_id, organisation_id, loadFileCount]);
|
|
1276
1362
|
useEffect4(() => {
|
|
1363
|
+
if (refreshSubscriptionRef.current) {
|
|
1364
|
+
refreshSubscriptionRef.current();
|
|
1365
|
+
refreshSubscriptionRef.current = null;
|
|
1366
|
+
}
|
|
1277
1367
|
if (!fileReference || fileReference.is_public) {
|
|
1278
|
-
if (urlRefreshIntervalRef.current) {
|
|
1279
|
-
clearInterval(urlRefreshIntervalRef.current);
|
|
1280
|
-
urlRefreshIntervalRef.current = null;
|
|
1281
|
-
}
|
|
1282
1368
|
return;
|
|
1283
1369
|
}
|
|
1284
|
-
|
|
1370
|
+
const key = `${fileReference.table_name}:${fileReference.record_id}:${organisation_id}`;
|
|
1371
|
+
refreshSubscriptionRef.current = urlRefreshManager.subscribe(key, () => {
|
|
1285
1372
|
loadFileUrl();
|
|
1286
|
-
}
|
|
1373
|
+
});
|
|
1287
1374
|
return () => {
|
|
1288
|
-
if (
|
|
1289
|
-
|
|
1290
|
-
|
|
1375
|
+
if (refreshSubscriptionRef.current) {
|
|
1376
|
+
refreshSubscriptionRef.current();
|
|
1377
|
+
refreshSubscriptionRef.current = null;
|
|
1291
1378
|
}
|
|
1292
1379
|
};
|
|
1293
|
-
}, [fileReference, loadFileUrl]);
|
|
1380
|
+
}, [fileReference, loadFileUrl, organisation_id]);
|
|
1294
1381
|
return {
|
|
1295
1382
|
isLoading,
|
|
1296
1383
|
error,
|
|
@@ -1396,12 +1483,12 @@ function useFilesByCategory(supabase, table_name, record_id, category, organisat
|
|
|
1396
1483
|
import * as React5 from "react";
|
|
1397
1484
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1398
1485
|
var sizeClasses = {
|
|
1399
|
-
xs: "
|
|
1400
|
-
sm: "
|
|
1401
|
-
md: "
|
|
1402
|
-
lg: "
|
|
1403
|
-
xl: "
|
|
1404
|
-
"2xl": "
|
|
1486
|
+
xs: "size-4 text-xs",
|
|
1487
|
+
sm: "size-6 text-sm",
|
|
1488
|
+
md: "size-10 text-base",
|
|
1489
|
+
lg: "size-12 text-lg",
|
|
1490
|
+
xl: "size-16 text-xl",
|
|
1491
|
+
"2xl": "size-20 text-2xl"
|
|
1405
1492
|
};
|
|
1406
1493
|
var Avatar = React5.forwardRef(
|
|
1407
1494
|
({
|
|
@@ -1430,9 +1517,9 @@ var Avatar = React5.forwardRef(
|
|
|
1430
1517
|
const hasFileId = canFetchFileId && fileIdUrl && !fileIdLoading;
|
|
1431
1518
|
const hasDirectUrl = src && !imageError;
|
|
1432
1519
|
const showFallback = !hasDirectUrl && (!hasFileProps && !hasFileId) || imageError || canFetchFileId && !fileIdUrl && !fileIdLoading;
|
|
1433
|
-
const baseClasses = size === "md" ? "
|
|
1434
|
-
const fallbackClasses = "
|
|
1435
|
-
const imageClasses = "object-cover
|
|
1520
|
+
const baseClasses = size === "md" ? " size-10 overflow-hidden rounded-full" : ` ${sizeClasses[size]} overflow-hidden rounded-full`;
|
|
1521
|
+
const fallbackClasses = "size-full grid place-items-center text-center text-sec-50 bg-sec-500";
|
|
1522
|
+
const imageClasses = "object-cover size-full";
|
|
1436
1523
|
const containerClasses = cn(baseClasses, className);
|
|
1437
1524
|
const handleImageError = React5.useCallback(() => {
|
|
1438
1525
|
setImageError(true);
|
|
@@ -1443,12 +1530,12 @@ var Avatar = React5.forwardRef(
|
|
|
1443
1530
|
}
|
|
1444
1531
|
}, [src]);
|
|
1445
1532
|
return /* @__PURE__ */ jsx5(
|
|
1446
|
-
"
|
|
1533
|
+
"figure",
|
|
1447
1534
|
{
|
|
1448
1535
|
ref,
|
|
1449
1536
|
className: containerClasses,
|
|
1450
1537
|
...props,
|
|
1451
|
-
children: showFallback ? /* @__PURE__ */ jsx5("
|
|
1538
|
+
children: showFallback ? /* @__PURE__ */ jsx5("figcaption", { className: fallbackClasses, "aria-label": alt || fallback, children: fallback }) : hasFileProps ? (
|
|
1452
1539
|
// File reference props approach - use FileDisplay
|
|
1453
1540
|
/* @__PURE__ */ jsx5(
|
|
1454
1541
|
FileDisplay,
|
|
@@ -1487,7 +1574,7 @@ var Avatar = React5.forwardRef(
|
|
|
1487
1574
|
)
|
|
1488
1575
|
) : (
|
|
1489
1576
|
// Fallback if nothing else works
|
|
1490
|
-
/* @__PURE__ */ jsx5("
|
|
1577
|
+
/* @__PURE__ */ jsx5("figcaption", { className: fallbackClasses, "aria-label": alt || fallback, children: fallback })
|
|
1491
1578
|
)
|
|
1492
1579
|
}
|
|
1493
1580
|
);
|
|
@@ -1624,7 +1711,7 @@ var Switch = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
1624
1711
|
{
|
|
1625
1712
|
className: cn(
|
|
1626
1713
|
// Base styles
|
|
1627
|
-
"pointer-events-none block
|
|
1714
|
+
"pointer-events-none block size-5 rounded-full",
|
|
1628
1715
|
// Background and shadow
|
|
1629
1716
|
"bg-background shadow-lg ring-0",
|
|
1630
1717
|
// Transition
|
|
@@ -1691,86 +1778,298 @@ TabsContent.displayName = TabsPrimitive.Content.displayName || "TabsContent";
|
|
|
1691
1778
|
|
|
1692
1779
|
// src/components/Calendar/Calendar.tsx
|
|
1693
1780
|
import * as React9 from "react";
|
|
1694
|
-
import {
|
|
1695
|
-
|
|
1781
|
+
import {
|
|
1782
|
+
DayPicker,
|
|
1783
|
+
useDayPicker
|
|
1784
|
+
} from "react-day-picker";
|
|
1785
|
+
import { enAU } from "date-fns/locale";
|
|
1786
|
+
import { Fragment as Fragment4, jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
1787
|
+
var assignToRef = (ref, value) => {
|
|
1788
|
+
if (!ref) {
|
|
1789
|
+
return;
|
|
1790
|
+
}
|
|
1791
|
+
if (typeof ref === "function") {
|
|
1792
|
+
ref(value);
|
|
1793
|
+
return;
|
|
1794
|
+
}
|
|
1795
|
+
ref.current = value;
|
|
1796
|
+
};
|
|
1696
1797
|
var Calendar = React9.forwardRef(
|
|
1697
|
-
({ className, classNames, mode, components, ...props }, ref) => {
|
|
1698
|
-
const
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
fill: "none",
|
|
1705
|
-
stroke: "currentColor",
|
|
1706
|
-
strokeWidth: "2",
|
|
1707
|
-
strokeLinecap: "round",
|
|
1708
|
-
strokeLinejoin: "round",
|
|
1709
|
-
className: "h-4 w-4",
|
|
1710
|
-
...iconProps,
|
|
1711
|
-
children: /* @__PURE__ */ jsx9("path", { d: "m15 18-6-6 6-6" })
|
|
1798
|
+
({ className, classNames, mode, components, locale, month: controlledMonth, onMonthChange: controlledOnMonthChange, onSelect, ...props }, ref) => {
|
|
1799
|
+
const tableRef = React9.useRef(null);
|
|
1800
|
+
const setForwardedRef = React9.useCallback(
|
|
1801
|
+
(node) => {
|
|
1802
|
+
tableRef.current = node;
|
|
1803
|
+
if (!ref) {
|
|
1804
|
+
return;
|
|
1712
1805
|
}
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
1718
|
-
viewBox: "0 0 24 24",
|
|
1719
|
-
fill: "none",
|
|
1720
|
-
stroke: "currentColor",
|
|
1721
|
-
strokeWidth: "2",
|
|
1722
|
-
strokeLinecap: "round",
|
|
1723
|
-
strokeLinejoin: "round",
|
|
1724
|
-
className: "h-4 w-4",
|
|
1725
|
-
...iconProps,
|
|
1726
|
-
children: /* @__PURE__ */ jsx9("path", { d: "m9 18 6-6-6-6" })
|
|
1806
|
+
if (typeof ref === "function") {
|
|
1807
|
+
ref(node);
|
|
1808
|
+
} else {
|
|
1809
|
+
ref.current = node;
|
|
1727
1810
|
}
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1811
|
+
},
|
|
1812
|
+
[ref]
|
|
1813
|
+
);
|
|
1814
|
+
const rootPropsRef = React9.useRef(null);
|
|
1815
|
+
const selected = props.selected;
|
|
1816
|
+
const isMonthControlled = controlledMonth !== void 0;
|
|
1817
|
+
const [internalMonth, setInternalMonth] = React9.useState(() => {
|
|
1818
|
+
const now = /* @__PURE__ */ new Date();
|
|
1819
|
+
return new Date(now.getFullYear(), now.getMonth(), 1);
|
|
1820
|
+
});
|
|
1821
|
+
const month = React9.useMemo(() => {
|
|
1822
|
+
const monthToUse = isMonthControlled ? controlledMonth : internalMonth;
|
|
1823
|
+
if (!monthToUse) {
|
|
1824
|
+
const now = /* @__PURE__ */ new Date();
|
|
1825
|
+
return new Date(now.getFullYear(), now.getMonth(), 1);
|
|
1826
|
+
}
|
|
1827
|
+
const normalized = new Date(monthToUse.getFullYear(), monthToUse.getMonth(), 1);
|
|
1828
|
+
return normalized;
|
|
1829
|
+
}, [isMonthControlled, controlledMonth, internalMonth]);
|
|
1830
|
+
const handleMonthChange = React9.useCallback((newMonth) => {
|
|
1831
|
+
if (!isMonthControlled) {
|
|
1832
|
+
setInternalMonth(newMonth);
|
|
1833
|
+
}
|
|
1834
|
+
controlledOnMonthChange?.(newMonth);
|
|
1835
|
+
}, [isMonthControlled, controlledOnMonthChange]);
|
|
1836
|
+
const wrappedHandleMonthChange = React9.useCallback((newMonth) => {
|
|
1837
|
+
handleMonthChange(newMonth);
|
|
1838
|
+
}, [handleMonthChange]);
|
|
1839
|
+
const CustomRoot = React9.memo(({ children, rootRef: dayPickerRootRef, ...rootProps }) => {
|
|
1840
|
+
const {
|
|
1841
|
+
className: rootClassName,
|
|
1842
|
+
style: rootStyle,
|
|
1843
|
+
children: _ignoredChildren,
|
|
1844
|
+
...restProps
|
|
1845
|
+
} = rootProps;
|
|
1846
|
+
rootPropsRef.current = {
|
|
1847
|
+
className: rootClassName,
|
|
1848
|
+
style: rootStyle,
|
|
1849
|
+
rootRef: dayPickerRootRef,
|
|
1850
|
+
restProps
|
|
1851
|
+
};
|
|
1852
|
+
return /* @__PURE__ */ jsx9(Fragment4, { children });
|
|
1853
|
+
});
|
|
1854
|
+
CustomRoot.displayName = "CustomRoot";
|
|
1855
|
+
const CustomMonths = React9.memo(({ children }) => {
|
|
1856
|
+
return /* @__PURE__ */ jsx9(Fragment4, { children });
|
|
1857
|
+
});
|
|
1858
|
+
CustomMonths.displayName = "CustomMonths";
|
|
1859
|
+
const CustomMonthGrid = React9.forwardRef((props2, forwardedRef) => {
|
|
1860
|
+
return /* @__PURE__ */ jsx9("table", { ref: forwardedRef, ...props2 });
|
|
1861
|
+
});
|
|
1862
|
+
CustomMonthGrid.displayName = "CustomMonthGrid";
|
|
1863
|
+
const CustomMonth = React9.memo(({ calendarMonth, displayIndex, className: className2, children }) => {
|
|
1864
|
+
const { formatters, components: components2, labels, classNames: classNames2, previousMonth, nextMonth, goToMonth } = useDayPicker();
|
|
1865
|
+
const caption = formatters.formatCaption(calendarMonth.date, {});
|
|
1866
|
+
const Chevron = components2?.Chevron;
|
|
1867
|
+
const childrenArray = React9.Children.toArray(children);
|
|
1868
|
+
const monthGridIndex = childrenArray.findIndex((child) => {
|
|
1869
|
+
if (!React9.isValidElement(child)) return false;
|
|
1870
|
+
const childType = child.type;
|
|
1871
|
+
return typeof childType === "function" && childType.displayName === "MonthGrid" || child.type === "table";
|
|
1872
|
+
});
|
|
1873
|
+
return /* @__PURE__ */ jsx9(Fragment4, { children: childrenArray.map((child, index) => {
|
|
1874
|
+
if (React9.isValidElement(child) && child.type?.displayName === "MonthCaption") {
|
|
1875
|
+
return null;
|
|
1876
|
+
}
|
|
1877
|
+
if (index === monthGridIndex && React9.isValidElement(child)) {
|
|
1878
|
+
const monthGridChild = child;
|
|
1879
|
+
const applyRootProps = displayIndex === 0 && index === monthGridIndex;
|
|
1880
|
+
const storedRootProps = applyRootProps ? rootPropsRef.current : null;
|
|
1881
|
+
const { children: monthGridChildren, className: monthGridClassName, style: monthGridStyle, ...monthGridRest } = monthGridChild.props;
|
|
1882
|
+
const mergedClassName = cn(
|
|
1883
|
+
"w-full border-collapse rounded-md border border-sec-200 bg-background",
|
|
1884
|
+
applyRootProps ? storedRootProps?.className : void 0,
|
|
1885
|
+
className2,
|
|
1886
|
+
monthGridClassName
|
|
1887
|
+
);
|
|
1888
|
+
const mergedStyle = {
|
|
1889
|
+
...applyRootProps ? storedRootProps?.style ?? {} : {},
|
|
1890
|
+
...monthGridStyle ?? {}
|
|
1891
|
+
};
|
|
1892
|
+
const tableProps = {
|
|
1893
|
+
...applyRootProps && storedRootProps?.restProps ? storedRootProps.restProps : {},
|
|
1894
|
+
...monthGridRest,
|
|
1895
|
+
className: mergedClassName,
|
|
1896
|
+
...Object.keys(mergedStyle).length ? { style: mergedStyle } : {}
|
|
1897
|
+
};
|
|
1898
|
+
if (mode && tableProps["data-mode"] === void 0) {
|
|
1899
|
+
tableProps["data-mode"] = mode;
|
|
1900
|
+
}
|
|
1901
|
+
const shouldAttachRef = applyRootProps || storedRootProps?.rootRef;
|
|
1902
|
+
const handleTableRef = shouldAttachRef ? (node) => {
|
|
1903
|
+
if (applyRootProps) {
|
|
1904
|
+
setForwardedRef(node);
|
|
1905
|
+
}
|
|
1906
|
+
if (storedRootProps?.rootRef) {
|
|
1907
|
+
assignToRef(storedRootProps.rootRef, node);
|
|
1908
|
+
}
|
|
1909
|
+
} : void 0;
|
|
1910
|
+
const handlePreviousClick = (event) => {
|
|
1911
|
+
event.preventDefault();
|
|
1912
|
+
if (!previousMonth) return;
|
|
1913
|
+
goToMonth(previousMonth);
|
|
1914
|
+
};
|
|
1915
|
+
const handleNextClick = (event) => {
|
|
1916
|
+
event.preventDefault();
|
|
1917
|
+
if (!nextMonth) return;
|
|
1918
|
+
goToMonth(nextMonth);
|
|
1919
|
+
};
|
|
1920
|
+
const monthGridElement = monthGridChild;
|
|
1921
|
+
const mergedRef = handleTableRef || monthGridElement.ref ? (node) => {
|
|
1922
|
+
if (handleTableRef) {
|
|
1923
|
+
handleTableRef(node);
|
|
1924
|
+
}
|
|
1925
|
+
assignToRef(monthGridElement.ref, node);
|
|
1926
|
+
} : void 0;
|
|
1927
|
+
return React9.cloneElement(
|
|
1928
|
+
monthGridElement,
|
|
1929
|
+
{
|
|
1930
|
+
key: child.key ?? `month-grid-${displayIndex}`,
|
|
1931
|
+
...tableProps,
|
|
1932
|
+
...mergedRef ? { ref: mergedRef } : {}
|
|
1933
|
+
},
|
|
1934
|
+
/* @__PURE__ */ jsxs4(Fragment4, { children: [
|
|
1935
|
+
/* @__PURE__ */ jsx9("caption", { className: "relative", children: /* @__PURE__ */ jsxs4("nav", { className: "relative flex items-center justify-center gap-1", children: [
|
|
1936
|
+
/* @__PURE__ */ jsx9(
|
|
1937
|
+
"button",
|
|
1938
|
+
{
|
|
1939
|
+
type: "button",
|
|
1940
|
+
className: cn(
|
|
1941
|
+
"h-7 w-7 bg-transparent p-0",
|
|
1942
|
+
"inline-flex items-center justify-center rounded-md",
|
|
1943
|
+
"hover:bg-acc-100",
|
|
1944
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-main-600 focus-visible:ring-offset-2",
|
|
1945
|
+
"disabled:opacity-50 disabled:pointer-events-none",
|
|
1946
|
+
classNames2?.button_previous
|
|
1947
|
+
),
|
|
1948
|
+
tabIndex: previousMonth ? void 0 : -1,
|
|
1949
|
+
"aria-disabled": previousMonth ? void 0 : true,
|
|
1950
|
+
"aria-label": previousMonth ? labels.labelPrevious(previousMonth) : void 0,
|
|
1951
|
+
onClick: handlePreviousClick,
|
|
1952
|
+
disabled: !previousMonth,
|
|
1953
|
+
children: Chevron ? /* @__PURE__ */ jsx9(Chevron, { orientation: "left", className: "size-4", disabled: !previousMonth }) : /* @__PURE__ */ jsx9("span", { children: "\u2039" })
|
|
1954
|
+
}
|
|
1955
|
+
),
|
|
1956
|
+
/* @__PURE__ */ jsx9("span", { className: "text-sm font-medium", children: caption }),
|
|
1957
|
+
/* @__PURE__ */ jsx9(
|
|
1958
|
+
"button",
|
|
1959
|
+
{
|
|
1960
|
+
type: "button",
|
|
1961
|
+
className: cn(
|
|
1962
|
+
"h-7 w-7 bg-transparent p-0",
|
|
1963
|
+
"inline-flex items-center justify-center rounded-md",
|
|
1964
|
+
"hover:bg-acc-100",
|
|
1965
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-main-600 focus-visible:ring-offset-2",
|
|
1966
|
+
"disabled:opacity-50 disabled:pointer-events-none",
|
|
1967
|
+
classNames2?.button_next
|
|
1968
|
+
),
|
|
1969
|
+
tabIndex: nextMonth ? void 0 : -1,
|
|
1970
|
+
"aria-disabled": nextMonth ? void 0 : true,
|
|
1971
|
+
"aria-label": nextMonth ? labels.labelNext(nextMonth) : void 0,
|
|
1972
|
+
onClick: handleNextClick,
|
|
1973
|
+
disabled: !nextMonth,
|
|
1974
|
+
children: Chevron ? /* @__PURE__ */ jsx9(Chevron, { orientation: "right", className: "size-4", disabled: !nextMonth }) : /* @__PURE__ */ jsx9("span", { children: "\u203A" })
|
|
1975
|
+
}
|
|
1976
|
+
)
|
|
1977
|
+
] }) }),
|
|
1978
|
+
monthGridChildren
|
|
1979
|
+
] })
|
|
1980
|
+
);
|
|
1981
|
+
}
|
|
1982
|
+
return child;
|
|
1983
|
+
}) });
|
|
1984
|
+
});
|
|
1985
|
+
CustomMonth.displayName = "CustomMonth";
|
|
1986
|
+
const CustomWeekdays = React9.memo(({ className: className2, children, ...props2 }) => {
|
|
1987
|
+
return /* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsx9("tr", { className: cn("text-xs text-sec-500", className2), ...props2, children }) });
|
|
1988
|
+
});
|
|
1989
|
+
CustomWeekdays.displayName = "CustomWeekdays";
|
|
1990
|
+
const defaultComponents = React9.useMemo(() => ({
|
|
1991
|
+
Root: CustomRoot,
|
|
1992
|
+
Months: CustomMonths,
|
|
1993
|
+
Month: CustomMonth,
|
|
1994
|
+
MonthGrid: CustomMonthGrid,
|
|
1995
|
+
// MonthCaption is now handled inside CustomMonth (injected into table)
|
|
1996
|
+
Weekdays: CustomWeekdays,
|
|
1997
|
+
// Spread user components AFTER ours so ours take precedence
|
|
1998
|
+
...components || {}
|
|
1999
|
+
}), [components, CustomRoot, CustomMonths, CustomMonth, CustomWeekdays]);
|
|
2000
|
+
return /* @__PURE__ */ jsx9(
|
|
1732
2001
|
DayPicker,
|
|
1733
2002
|
{
|
|
1734
2003
|
...mode ? { mode } : {},
|
|
2004
|
+
locale: locale ?? enAU,
|
|
2005
|
+
hideNavigation: true,
|
|
1735
2006
|
...props,
|
|
1736
|
-
|
|
2007
|
+
selected,
|
|
2008
|
+
onSelect,
|
|
2009
|
+
month,
|
|
2010
|
+
onMonthChange: wrappedHandleMonthChange,
|
|
2011
|
+
className,
|
|
1737
2012
|
classNames: {
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
2013
|
+
// v9 API: Updated for table-based structure
|
|
2014
|
+
months: "",
|
|
2015
|
+
// No wrapper - removed by CustomMonths
|
|
2016
|
+
month: "",
|
|
2017
|
+
// No wrapper - removed by CustomMonth
|
|
2018
|
+
month_caption: "",
|
|
2019
|
+
// Now handled by custom component (renders as <caption>)
|
|
1741
2020
|
caption_label: "text-sm font-medium",
|
|
1742
|
-
nav: "
|
|
1743
|
-
|
|
1744
|
-
|
|
2021
|
+
nav: "relative flex items-center justify-center space-x-1",
|
|
2022
|
+
// v9: button_previous and button_next for navigation buttons
|
|
2023
|
+
button_previous: cn(
|
|
2024
|
+
"absolute left-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
|
2025
|
+
"border border-input hover:bg-acc-100",
|
|
2026
|
+
"inline-flex items-center justify-center rounded-md",
|
|
2027
|
+
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-main-600 focus-visible:ring-offset-2"
|
|
2028
|
+
),
|
|
2029
|
+
button_next: cn(
|
|
2030
|
+
"absolute right-1 h-7 w-7 bg-transparent p-0 opacity-50 hover:opacity-100",
|
|
1745
2031
|
"border border-input hover:bg-acc-100",
|
|
1746
2032
|
"inline-flex items-center justify-center rounded-md",
|
|
1747
2033
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-main-600 focus-visible:ring-offset-2"
|
|
1748
2034
|
),
|
|
1749
|
-
|
|
1750
|
-
|
|
1751
|
-
table
|
|
1752
|
-
|
|
1753
|
-
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
2035
|
+
// v9: table -> month_grid (now a proper <table>)
|
|
2036
|
+
month_grid: "",
|
|
2037
|
+
// Styles applied directly to table in CustomMonth
|
|
2038
|
+
// v9: head_row -> weekdays (now wrapped in <thead> by custom component)
|
|
2039
|
+
weekdays: "",
|
|
2040
|
+
// Styles applied to <tr> inside <thead>
|
|
2041
|
+
weekday: "text-sec-600 rounded-md w-9 font-normal text-[0.8rem]",
|
|
2042
|
+
// v9: row -> week (now a proper <tr>)
|
|
2043
|
+
week: "mt-2",
|
|
2044
|
+
// v9: cell -> day (now a proper <td> by custom component)
|
|
2045
|
+
day: "",
|
|
2046
|
+
// Styles moved to <td> in custom component
|
|
2047
|
+
// v9: day -> day_button (the button inside the cell)
|
|
2048
|
+
day_button: cn(
|
|
1757
2049
|
"h-9 w-9 p-0 font-normal aria-selected:opacity-100",
|
|
1758
2050
|
"hover:bg-acc-100 hover:text-main-600",
|
|
1759
2051
|
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-main-600 focus-visible:ring-offset-2",
|
|
1760
2052
|
"inline-flex items-center justify-center rounded-md"
|
|
1761
2053
|
),
|
|
1762
|
-
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
|
|
1766
|
-
|
|
1767
|
-
|
|
1768
|
-
|
|
2054
|
+
// v9: day_range_end -> range_end
|
|
2055
|
+
range_end: "range-end",
|
|
2056
|
+
// v9: day_selected -> selected
|
|
2057
|
+
selected: "bg-main-600 text-main-50 hover:bg-main-600 hover:text-main-50 focus:bg-main-600 focus:text-main-50",
|
|
2058
|
+
// v9: day_today -> today
|
|
2059
|
+
today: "bg-sec-100 text-main-600 font-semibold",
|
|
2060
|
+
// v9: day_outside -> outside
|
|
2061
|
+
outside: "outside text-sec-400 opacity-50 aria-selected:bg-acc-50/50 aria-selected:text-sec-400 aria-selected:opacity-30",
|
|
2062
|
+
// v9: day_disabled -> disabled
|
|
2063
|
+
disabled: "text-sec-400 opacity-50 cursor-not-allowed",
|
|
2064
|
+
// v9: day_range_middle -> range_middle
|
|
2065
|
+
range_middle: "aria-selected:bg-acc-100 aria-selected:text-main-600",
|
|
2066
|
+
// v9: day_hidden -> hidden
|
|
2067
|
+
hidden: "invisible",
|
|
1769
2068
|
...classNames
|
|
1770
2069
|
},
|
|
1771
2070
|
components: defaultComponents
|
|
1772
2071
|
}
|
|
1773
|
-
)
|
|
2072
|
+
);
|
|
1774
2073
|
}
|
|
1775
2074
|
);
|
|
1776
2075
|
Calendar.displayName = "Calendar";
|
|
@@ -1779,7 +2078,7 @@ Calendar.displayName = "Calendar";
|
|
|
1779
2078
|
import * as React10 from "react";
|
|
1780
2079
|
import * as ToastPrimitives from "@radix-ui/react-toast";
|
|
1781
2080
|
import { X } from "lucide-react";
|
|
1782
|
-
import { jsx as jsx10, jsxs as
|
|
2081
|
+
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
1783
2082
|
var ToastProvider = ToastPrimitives.Provider;
|
|
1784
2083
|
var ToastViewport = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx10(
|
|
1785
2084
|
ToastPrimitives.Viewport,
|
|
@@ -1833,7 +2132,7 @@ var ToastClose = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
1833
2132
|
),
|
|
1834
2133
|
"toast-close": "",
|
|
1835
2134
|
...props,
|
|
1836
|
-
children: /* @__PURE__ */ jsx10(X, { className: "
|
|
2135
|
+
children: /* @__PURE__ */ jsx10(X, { className: "size-4" })
|
|
1837
2136
|
}
|
|
1838
2137
|
));
|
|
1839
2138
|
ToastClose.displayName = ToastPrimitives.Close.displayName;
|
|
@@ -1859,11 +2158,11 @@ var ToastDescription = React10.forwardRef(({ className, ...props }, ref) => /* @
|
|
|
1859
2158
|
ToastDescription.displayName = ToastPrimitives.Description.displayName;
|
|
1860
2159
|
function Toaster() {
|
|
1861
2160
|
const { toasts } = useToast();
|
|
1862
|
-
return /* @__PURE__ */
|
|
2161
|
+
return /* @__PURE__ */ jsxs5(ToastProvider, { "data-testid": "toast-provider", children: [
|
|
1863
2162
|
/* @__PURE__ */ jsx10(ToastViewport, {}),
|
|
1864
2163
|
toasts.map((toast) => {
|
|
1865
2164
|
const { id, title, description, action, dismiss, duration, ...toastProps } = toast;
|
|
1866
|
-
return /* @__PURE__ */
|
|
2165
|
+
return /* @__PURE__ */ jsxs5(Toast, { ...toastProps, duration, children: [
|
|
1867
2166
|
title && /* @__PURE__ */ jsx10(ToastTitle, { children: title }),
|
|
1868
2167
|
description && /* @__PURE__ */ jsx10(ToastDescription, { children: description }),
|
|
1869
2168
|
action && action,
|
|
@@ -1876,7 +2175,7 @@ function Toaster() {
|
|
|
1876
2175
|
// src/components/Form/Form.tsx
|
|
1877
2176
|
import { useForm, FormProvider, useFormContext, Controller } from "react-hook-form";
|
|
1878
2177
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
1879
|
-
import { jsx as jsx11, jsxs as
|
|
2178
|
+
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
1880
2179
|
function Form({
|
|
1881
2180
|
schema,
|
|
1882
2181
|
defaultValues,
|
|
@@ -1908,8 +2207,8 @@ function FormField({
|
|
|
1908
2207
|
const { control, formState: { errors } } = useFormContext();
|
|
1909
2208
|
const fieldError = errors[name];
|
|
1910
2209
|
const errorMessage = fieldError && typeof fieldError === "object" && "message" in fieldError ? String(fieldError.message) : void 0;
|
|
1911
|
-
return /* @__PURE__ */
|
|
1912
|
-
label && /* @__PURE__ */
|
|
2210
|
+
return /* @__PURE__ */ jsxs6("div", { className: cn("space-y-2", className), children: [
|
|
2211
|
+
label && /* @__PURE__ */ jsxs6(Label, { htmlFor: name, children: [
|
|
1913
2212
|
label,
|
|
1914
2213
|
validation?.required && /* @__PURE__ */ jsx11("span", { className: "text-destructive ml-1", "aria-label": "required", children: "*" })
|
|
1915
2214
|
] }),
|
|
@@ -1946,8 +2245,8 @@ function FormField({
|
|
|
1946
2245
|
}
|
|
1947
2246
|
|
|
1948
2247
|
// src/components/LoginForm/LoginForm.tsx
|
|
1949
|
-
import React11, { useState as
|
|
1950
|
-
import { jsx as jsx12, jsxs as
|
|
2248
|
+
import React11, { useState as useState7, useCallback as useCallback7, useMemo as useMemo4 } from "react";
|
|
2249
|
+
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
1951
2250
|
var LoginForm = React11.memo(({
|
|
1952
2251
|
onSignIn,
|
|
1953
2252
|
onSuccess,
|
|
@@ -1960,18 +2259,18 @@ var LoginForm = React11.memo(({
|
|
|
1960
2259
|
onSignUp,
|
|
1961
2260
|
className
|
|
1962
2261
|
}) => {
|
|
1963
|
-
const [formData, setFormData] =
|
|
1964
|
-
const [error, setError] =
|
|
1965
|
-
const isFormValid =
|
|
2262
|
+
const [formData, setFormData] = useState7({ email: "", password: "" });
|
|
2263
|
+
const [error, setError] = useState7(null);
|
|
2264
|
+
const isFormValid = useMemo4(() => {
|
|
1966
2265
|
return formData.email.length > 0 && formData.password.length > 0;
|
|
1967
2266
|
}, [formData.email, formData.password]);
|
|
1968
|
-
const handleEmailChange =
|
|
2267
|
+
const handleEmailChange = useCallback7((e) => {
|
|
1969
2268
|
setFormData((prev) => ({ ...prev, email: e.target.value }));
|
|
1970
2269
|
}, []);
|
|
1971
|
-
const handlePasswordChange =
|
|
2270
|
+
const handlePasswordChange = useCallback7((e) => {
|
|
1972
2271
|
setFormData((prev) => ({ ...prev, password: e.target.value }));
|
|
1973
2272
|
}, []);
|
|
1974
|
-
const handleSubmit =
|
|
2273
|
+
const handleSubmit = useCallback7(async (e) => {
|
|
1975
2274
|
e.preventDefault();
|
|
1976
2275
|
setError(null);
|
|
1977
2276
|
if (!isFormValid || isLoading) return;
|
|
@@ -1984,17 +2283,17 @@ var LoginForm = React11.memo(({
|
|
|
1984
2283
|
onError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
1985
2284
|
}
|
|
1986
2285
|
}, [formData, isFormValid, isLoading, onSignIn, onSuccess, onError]);
|
|
1987
|
-
const handleSignUpClick =
|
|
2286
|
+
const handleSignUpClick = useCallback7(() => {
|
|
1988
2287
|
onSignUp?.();
|
|
1989
2288
|
}, [onSignUp]);
|
|
1990
|
-
const displayTitle =
|
|
1991
|
-
const displaySubtitle =
|
|
1992
|
-
return /* @__PURE__ */ jsx12(Card, { className: cn("w-full max-w-md mx-auto", className), children: /* @__PURE__ */
|
|
1993
|
-
/* @__PURE__ */
|
|
2289
|
+
const displayTitle = useMemo4(() => title || (appName ? `Sign in to ${appName}` : "Sign In"), [title, appName]);
|
|
2290
|
+
const displaySubtitle = useMemo4(() => subtitle || "Enter your credentials to continue.", [subtitle]);
|
|
2291
|
+
return /* @__PURE__ */ jsx12(Card, { className: cn("w-full max-w-md mx-auto", className), children: /* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, "data-testid": "login-form", children: [
|
|
2292
|
+
/* @__PURE__ */ jsxs7(CardHeader, { className: "space-y-1", children: [
|
|
1994
2293
|
/* @__PURE__ */ jsx12(CardTitle, { className: "text-2xl text-center", children: displayTitle }),
|
|
1995
2294
|
/* @__PURE__ */ jsx12(CardDescription, { className: "text-center", children: displaySubtitle })
|
|
1996
2295
|
] }),
|
|
1997
|
-
/* @__PURE__ */
|
|
2296
|
+
/* @__PURE__ */ jsxs7(CardContent, { className: "space-y-4", children: [
|
|
1998
2297
|
error && /* @__PURE__ */ jsx12(Alert, { variant: "destructive", role: "alert", "aria-live": "assertive", children: /* @__PURE__ */ jsx12(AlertDescription, { children: error }) }),
|
|
1999
2298
|
/* @__PURE__ */ jsx12(Label, { htmlFor: "email", children: "Email" }),
|
|
2000
2299
|
/* @__PURE__ */ jsx12(
|
|
@@ -2023,7 +2322,7 @@ var LoginForm = React11.memo(({
|
|
|
2023
2322
|
}
|
|
2024
2323
|
)
|
|
2025
2324
|
] }),
|
|
2026
|
-
/* @__PURE__ */
|
|
2325
|
+
/* @__PURE__ */ jsxs7(CardFooter, { className: "flex flex-col space-y-4", children: [
|
|
2027
2326
|
/* @__PURE__ */ jsx12(
|
|
2028
2327
|
Button,
|
|
2029
2328
|
{
|
|
@@ -2041,7 +2340,7 @@ var LoginForm = React11.memo(({
|
|
|
2041
2340
|
className: "text-primary hover:underline",
|
|
2042
2341
|
children: "Don't have an account? Sign up"
|
|
2043
2342
|
}
|
|
2044
|
-
) }) : /* @__PURE__ */
|
|
2343
|
+
) }) : /* @__PURE__ */ jsxs7("p", { className: "text-center text-muted-foreground", children: [
|
|
2045
2344
|
"Don't have an account?",
|
|
2046
2345
|
" ",
|
|
2047
2346
|
/* @__PURE__ */ jsx12("a", { href: "/signup", className: "text-primary hover:underline", children: "Sign up" })
|
|
@@ -2052,8 +2351,8 @@ var LoginForm = React11.memo(({
|
|
|
2052
2351
|
|
|
2053
2352
|
// src/components/EventSelector/EventSelector.tsx
|
|
2054
2353
|
import { RefreshCw, AlertCircle, Lock, Calendar as Calendar2, Star } from "lucide-react";
|
|
2055
|
-
import { useEffect as useEffect6, useMemo as
|
|
2056
|
-
import { jsx as jsx13, jsxs as
|
|
2354
|
+
import { useEffect as useEffect6, useMemo as useMemo5, useRef as useRef6 } from "react";
|
|
2355
|
+
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2057
2356
|
function EventSelector({
|
|
2058
2357
|
placeholder = "Select an event",
|
|
2059
2358
|
className,
|
|
@@ -2111,13 +2410,13 @@ function EventSelector({
|
|
|
2111
2410
|
return date.toLocaleDateString();
|
|
2112
2411
|
}
|
|
2113
2412
|
};
|
|
2114
|
-
const sortedEvents =
|
|
2413
|
+
const sortedEvents = useMemo5(() => {
|
|
2115
2414
|
const getTime = (e) => e.event_date ? new Date(e.event_date).getTime() : Number.NEGATIVE_INFINITY;
|
|
2116
2415
|
return [...events].sort((a, b) => getTime(b) - getTime(a));
|
|
2117
2416
|
}, [events]);
|
|
2118
|
-
const prevEventsLengthRef =
|
|
2119
|
-
const prevSelectedEventIdRef =
|
|
2120
|
-
const hasAutoSelectedRef =
|
|
2417
|
+
const prevEventsLengthRef = useRef6(events.length);
|
|
2418
|
+
const prevSelectedEventIdRef = useRef6(selectedEvent?.event_id);
|
|
2419
|
+
const hasAutoSelectedRef = useRef6(false);
|
|
2121
2420
|
useEffect6(() => {
|
|
2122
2421
|
const eventsLengthChanged = events.length !== prevEventsLengthRef.current;
|
|
2123
2422
|
const selectedEventChanged = selectedEvent?.event_id !== prevSelectedEventIdRef.current;
|
|
@@ -2159,17 +2458,17 @@ function EventSelector({
|
|
|
2159
2458
|
}
|
|
2160
2459
|
}, [events.length, selectedEvent?.event_id, isLoading, setSelectedEvent, onEventChange]);
|
|
2161
2460
|
if (isLoading) {
|
|
2162
|
-
return /* @__PURE__ */
|
|
2461
|
+
return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-2 ${className}`, children: [
|
|
2163
2462
|
/* @__PURE__ */ jsx13(LoadingSpinner, { size: "sm" }),
|
|
2164
2463
|
/* @__PURE__ */ jsx13("span", { className: "text-sm text-muted-foreground", children: "Loading events..." })
|
|
2165
2464
|
] });
|
|
2166
2465
|
}
|
|
2167
2466
|
if (error) {
|
|
2168
|
-
return /* @__PURE__ */ jsx13("div", { className, children: /* @__PURE__ */
|
|
2169
|
-
/* @__PURE__ */ jsx13(Lock, { className: "
|
|
2170
|
-
/* @__PURE__ */
|
|
2467
|
+
return /* @__PURE__ */ jsx13("div", { className, children: /* @__PURE__ */ jsxs8(Alert, { variant: "destructive", children: [
|
|
2468
|
+
/* @__PURE__ */ jsx13(Lock, { className: "size-4" }),
|
|
2469
|
+
/* @__PURE__ */ jsxs8(AlertDescription, { className: "flex items-center justify-between", children: [
|
|
2171
2470
|
/* @__PURE__ */ jsx13("span", { children: error.message }),
|
|
2172
|
-
showRetryButton && /* @__PURE__ */
|
|
2471
|
+
showRetryButton && /* @__PURE__ */ jsxs8(
|
|
2173
2472
|
Button,
|
|
2174
2473
|
{
|
|
2175
2474
|
variant: "outline",
|
|
@@ -2177,7 +2476,7 @@ function EventSelector({
|
|
|
2177
2476
|
onClick: handleRetry,
|
|
2178
2477
|
className: "ml-2",
|
|
2179
2478
|
children: [
|
|
2180
|
-
/* @__PURE__ */ jsx13(RefreshCw, { className: "
|
|
2479
|
+
/* @__PURE__ */ jsx13(RefreshCw, { className: "size-3 mr-1" }),
|
|
2181
2480
|
"Retry"
|
|
2182
2481
|
]
|
|
2183
2482
|
}
|
|
@@ -2187,11 +2486,11 @@ function EventSelector({
|
|
|
2187
2486
|
}
|
|
2188
2487
|
if (events.length === 0) {
|
|
2189
2488
|
if (showNoEventsMessage) {
|
|
2190
|
-
return /* @__PURE__ */ jsx13("div", { className, children: /* @__PURE__ */
|
|
2191
|
-
/* @__PURE__ */ jsx13(AlertCircle, { className: "
|
|
2192
|
-
/* @__PURE__ */
|
|
2489
|
+
return /* @__PURE__ */ jsx13("div", { className, children: /* @__PURE__ */ jsxs8(Alert, { variant: "inline", children: [
|
|
2490
|
+
/* @__PURE__ */ jsx13(AlertCircle, { className: "size-4 text-acc-700" }),
|
|
2491
|
+
/* @__PURE__ */ jsxs8(AlertDescription, { className: "flex items-center justify-between", children: [
|
|
2193
2492
|
/* @__PURE__ */ jsx13("span", { children: "No events available." }),
|
|
2194
|
-
showRetryButton && /* @__PURE__ */
|
|
2493
|
+
showRetryButton && /* @__PURE__ */ jsxs8(
|
|
2195
2494
|
Button,
|
|
2196
2495
|
{
|
|
2197
2496
|
variant: "outline",
|
|
@@ -2199,7 +2498,7 @@ function EventSelector({
|
|
|
2199
2498
|
onClick: handleRetry,
|
|
2200
2499
|
className: "ml-2",
|
|
2201
2500
|
children: [
|
|
2202
|
-
/* @__PURE__ */ jsx13(RefreshCw, { className: "
|
|
2501
|
+
/* @__PURE__ */ jsx13(RefreshCw, { className: "size-3 mr-1" }),
|
|
2203
2502
|
"Refresh"
|
|
2204
2503
|
]
|
|
2205
2504
|
}
|
|
@@ -2209,17 +2508,17 @@ function EventSelector({
|
|
|
2209
2508
|
}
|
|
2210
2509
|
return null;
|
|
2211
2510
|
}
|
|
2212
|
-
return /* @__PURE__ */
|
|
2511
|
+
return /* @__PURE__ */ jsxs8(
|
|
2213
2512
|
Select,
|
|
2214
2513
|
{
|
|
2215
2514
|
value: selectedEvent ? selectedEvent.event_id || selectedEvent.id : "",
|
|
2216
2515
|
onValueChange: handleValueChange,
|
|
2217
2516
|
className,
|
|
2218
2517
|
children: [
|
|
2219
|
-
/* @__PURE__ */ jsx13(SelectTrigger, { className: "text-left", variant: "outline", children: /* @__PURE__ */ jsx13(SelectValue, { placeholder, children: selectedEvent && /* @__PURE__ */
|
|
2220
|
-
/* @__PURE__ */ jsx13(Calendar2, { className: "
|
|
2518
|
+
/* @__PURE__ */ jsx13(SelectTrigger, { className: "text-left", variant: "outline", children: /* @__PURE__ */ jsx13(SelectValue, { placeholder, children: selectedEvent && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
2519
|
+
/* @__PURE__ */ jsx13(Calendar2, { className: "size-4 flex-shrink-0" }),
|
|
2221
2520
|
/* @__PURE__ */ jsx13("span", { className: "truncate", children: selectedEvent.event_name }),
|
|
2222
|
-
selectedEvent.event_date && /* @__PURE__ */
|
|
2521
|
+
selectedEvent.event_date && /* @__PURE__ */ jsxs8("span", { className: "text-xs text-muted-foreground flex-shrink-0", children: [
|
|
2223
2522
|
"(",
|
|
2224
2523
|
formatEventDate(selectedEvent.event_date),
|
|
2225
2524
|
")"
|
|
@@ -2233,19 +2532,19 @@ function EventSelector({
|
|
|
2233
2532
|
{
|
|
2234
2533
|
value: event.event_id || event.id,
|
|
2235
2534
|
className: "flex items-center justify-between",
|
|
2236
|
-
children: /* @__PURE__ */
|
|
2237
|
-
showNextEventIndicator && isNext && /* @__PURE__ */ jsx13(Star, { className: "
|
|
2238
|
-
/* @__PURE__ */
|
|
2239
|
-
/* @__PURE__ */
|
|
2535
|
+
children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 w-full", children: [
|
|
2536
|
+
showNextEventIndicator && isNext && /* @__PURE__ */ jsx13(Star, { className: "size-3 text-acc-500" }),
|
|
2537
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex-1", children: [
|
|
2538
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
2240
2539
|
/* @__PURE__ */ jsx13("span", { className: isSelected ? "font-semibold" : "", children: event.event_name }),
|
|
2241
2540
|
isSelected && /* @__PURE__ */ jsx13("span", { className: "text-xs bg-primary text-primary-foreground px-1 rounded", children: "Current" })
|
|
2242
2541
|
] }),
|
|
2243
|
-
showEventDetails && event.event_date && /* @__PURE__ */
|
|
2244
|
-
/* @__PURE__ */ jsx13(Calendar2, { className: "
|
|
2542
|
+
showEventDetails && event.event_date && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
2543
|
+
/* @__PURE__ */ jsx13(Calendar2, { className: "size-3" }),
|
|
2245
2544
|
/* @__PURE__ */ jsx13("span", { children: formatEventDate(event.event_date) }),
|
|
2246
2545
|
showNextEventIndicator && isNext && /* @__PURE__ */ jsx13("span", { className: "text-acc-600 font-medium", children: "(Next)" })
|
|
2247
2546
|
] }),
|
|
2248
|
-
showEventDetails && event.event_venue && /* @__PURE__ */
|
|
2547
|
+
showEventDetails && event.event_venue && /* @__PURE__ */ jsxs8("div", { className: "text-xs text-muted-foreground", children: [
|
|
2249
2548
|
"\u{1F4CD} ",
|
|
2250
2549
|
event.event_venue
|
|
2251
2550
|
] })
|
|
@@ -2261,9 +2560,9 @@ function EventSelector({
|
|
|
2261
2560
|
}
|
|
2262
2561
|
|
|
2263
2562
|
// src/components/OrganisationSelector/OrganisationSelector.tsx
|
|
2264
|
-
import { useState as
|
|
2563
|
+
import { useState as useState8, useCallback as useCallback8, useMemo as useMemo6 } from "react";
|
|
2265
2564
|
import { RefreshCw as RefreshCw2, AlertCircle as AlertCircle2, Building2, Shield } from "lucide-react";
|
|
2266
|
-
import { jsx as jsx14, jsxs as
|
|
2565
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2267
2566
|
function OrganisationSelector({
|
|
2268
2567
|
placeholder = "Select organisation",
|
|
2269
2568
|
className,
|
|
@@ -2274,8 +2573,8 @@ function OrganisationSelector({
|
|
|
2274
2573
|
compact = false,
|
|
2275
2574
|
disabled = false
|
|
2276
2575
|
}) {
|
|
2277
|
-
const [isLoading, setIsLoading] =
|
|
2278
|
-
const [switchError, setSwitchError] =
|
|
2576
|
+
const [isLoading, setIsLoading] = useState8(false);
|
|
2577
|
+
const [switchError, setSwitchError] = useState8(null);
|
|
2279
2578
|
const {
|
|
2280
2579
|
organisations,
|
|
2281
2580
|
selectedOrganisation,
|
|
@@ -2286,7 +2585,7 @@ function OrganisationSelector({
|
|
|
2286
2585
|
validateOrganisationAccess,
|
|
2287
2586
|
refreshOrganisations
|
|
2288
2587
|
} = useOrganisations();
|
|
2289
|
-
const handleOrganisationChange =
|
|
2588
|
+
const handleOrganisationChange = useCallback8(async (orgId) => {
|
|
2290
2589
|
if (disabled || isLoading) return;
|
|
2291
2590
|
setSwitchError(null);
|
|
2292
2591
|
setIsLoading(true);
|
|
@@ -2314,7 +2613,7 @@ function OrganisationSelector({
|
|
|
2314
2613
|
organisations,
|
|
2315
2614
|
onOrganisationChange
|
|
2316
2615
|
]);
|
|
2317
|
-
const handleRetry =
|
|
2616
|
+
const handleRetry = useCallback8(async () => {
|
|
2318
2617
|
setIsLoading(true);
|
|
2319
2618
|
setSwitchError(null);
|
|
2320
2619
|
try {
|
|
@@ -2327,21 +2626,21 @@ function OrganisationSelector({
|
|
|
2327
2626
|
}
|
|
2328
2627
|
}, [refreshOrganisations]);
|
|
2329
2628
|
if (orgLoading) {
|
|
2330
|
-
return /* @__PURE__ */
|
|
2629
|
+
return /* @__PURE__ */ jsxs9("div", { className: `flex items-center gap-2 ${className}`, children: [
|
|
2331
2630
|
/* @__PURE__ */ jsx14(LoadingSpinner, { size: "sm" }),
|
|
2332
2631
|
/* @__PURE__ */ jsx14("span", { className: "text-sm text-muted-foreground", children: compact ? "Loading..." : "Loading organisations..." })
|
|
2333
2632
|
] });
|
|
2334
2633
|
}
|
|
2335
2634
|
if (orgError) {
|
|
2336
|
-
return /* @__PURE__ */
|
|
2337
|
-
/* @__PURE__ */
|
|
2338
|
-
/* @__PURE__ */ jsx14(AlertCircle2, { className: "
|
|
2339
|
-
/* @__PURE__ */
|
|
2635
|
+
return /* @__PURE__ */ jsxs9("div", { className: `space-y-2 ${className}`, children: [
|
|
2636
|
+
/* @__PURE__ */ jsxs9(Alert, { variant: "destructive", children: [
|
|
2637
|
+
/* @__PURE__ */ jsx14(AlertCircle2, { className: "size-4" }),
|
|
2638
|
+
/* @__PURE__ */ jsxs9(AlertDescription, { children: [
|
|
2340
2639
|
"Failed to load organisations: ",
|
|
2341
2640
|
orgError.message
|
|
2342
2641
|
] })
|
|
2343
2642
|
] }),
|
|
2344
|
-
showRetryButton && /* @__PURE__ */
|
|
2643
|
+
showRetryButton && /* @__PURE__ */ jsxs9(
|
|
2345
2644
|
Button,
|
|
2346
2645
|
{
|
|
2347
2646
|
variant: "outline",
|
|
@@ -2350,7 +2649,7 @@ function OrganisationSelector({
|
|
|
2350
2649
|
disabled: isLoading,
|
|
2351
2650
|
className: "w-full",
|
|
2352
2651
|
children: [
|
|
2353
|
-
/* @__PURE__ */ jsx14(RefreshCw2, { className: `
|
|
2652
|
+
/* @__PURE__ */ jsx14(RefreshCw2, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
2354
2653
|
"Retry"
|
|
2355
2654
|
]
|
|
2356
2655
|
}
|
|
@@ -2359,12 +2658,12 @@ function OrganisationSelector({
|
|
|
2359
2658
|
}
|
|
2360
2659
|
if (organisations.length === 0) {
|
|
2361
2660
|
if (showNoOrganisationsMessage) {
|
|
2362
|
-
return /* @__PURE__ */
|
|
2363
|
-
/* @__PURE__ */
|
|
2364
|
-
/* @__PURE__ */ jsx14(Building2, { className: "
|
|
2661
|
+
return /* @__PURE__ */ jsxs9("div", { className: `space-y-2 ${className}`, children: [
|
|
2662
|
+
/* @__PURE__ */ jsxs9(Alert, { children: [
|
|
2663
|
+
/* @__PURE__ */ jsx14(Building2, { className: "size-4" }),
|
|
2365
2664
|
/* @__PURE__ */ jsx14(AlertDescription, { children: "No organisations available. Please contact your administrator to be added to an organisation." })
|
|
2366
2665
|
] }),
|
|
2367
|
-
showRetryButton && /* @__PURE__ */
|
|
2666
|
+
showRetryButton && /* @__PURE__ */ jsxs9(
|
|
2368
2667
|
Button,
|
|
2369
2668
|
{
|
|
2370
2669
|
variant: "outline",
|
|
@@ -2373,7 +2672,7 @@ function OrganisationSelector({
|
|
|
2373
2672
|
disabled: isLoading,
|
|
2374
2673
|
className: "w-full",
|
|
2375
2674
|
children: [
|
|
2376
|
-
/* @__PURE__ */ jsx14(RefreshCw2, { className: `
|
|
2675
|
+
/* @__PURE__ */ jsx14(RefreshCw2, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
2377
2676
|
"Check Again"
|
|
2378
2677
|
]
|
|
2379
2678
|
}
|
|
@@ -2382,22 +2681,33 @@ function OrganisationSelector({
|
|
|
2382
2681
|
}
|
|
2383
2682
|
return null;
|
|
2384
2683
|
}
|
|
2385
|
-
const switchErrorDisplay = switchError && /* @__PURE__ */
|
|
2386
|
-
/* @__PURE__ */ jsx14(AlertCircle2, { className: "
|
|
2684
|
+
const switchErrorDisplay = switchError && /* @__PURE__ */ jsxs9(Alert, { variant: "destructive", className: "mt-2", children: [
|
|
2685
|
+
/* @__PURE__ */ jsx14(AlertCircle2, { className: "size-4" }),
|
|
2387
2686
|
/* @__PURE__ */ jsx14(AlertDescription, { children: switchError })
|
|
2388
2687
|
] });
|
|
2389
|
-
|
|
2390
|
-
|
|
2688
|
+
const isSelectDisabled = disabled || isLoading;
|
|
2689
|
+
const selectValue = useMemo6(() => {
|
|
2690
|
+
return selectedOrganisation?.id || "";
|
|
2691
|
+
}, [selectedOrganisation?.id]);
|
|
2692
|
+
return /* @__PURE__ */ jsxs9("div", { className, children: [
|
|
2693
|
+
/* @__PURE__ */ jsxs9(
|
|
2391
2694
|
Select,
|
|
2392
2695
|
{
|
|
2393
|
-
value:
|
|
2696
|
+
value: selectValue,
|
|
2394
2697
|
onValueChange: handleOrganisationChange,
|
|
2395
|
-
disabled:
|
|
2698
|
+
disabled: isSelectDisabled,
|
|
2396
2699
|
children: [
|
|
2397
|
-
/* @__PURE__ */ jsx14(
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2700
|
+
/* @__PURE__ */ jsx14(
|
|
2701
|
+
SelectTrigger,
|
|
2702
|
+
{
|
|
2703
|
+
className: "text-left",
|
|
2704
|
+
variant: "outline",
|
|
2705
|
+
children: /* @__PURE__ */ jsx14(SelectValue, { placeholder, children: selectedOrganisation && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
2706
|
+
isLoading ? /* @__PURE__ */ jsx14(LoadingSpinner, { size: "sm" }) : /* @__PURE__ */ jsx14(Building2, { className: "size-4 flex-shrink-0" }),
|
|
2707
|
+
/* @__PURE__ */ jsx14("span", { className: "truncate", children: selectedOrganisation.display_name })
|
|
2708
|
+
] }) })
|
|
2709
|
+
}
|
|
2710
|
+
),
|
|
2401
2711
|
/* @__PURE__ */ jsx14(SelectContent, { children: organisations.map((org) => {
|
|
2402
2712
|
const userRole = getUserRole(org.id);
|
|
2403
2713
|
const hasAccess = validateOrganisationAccess(org.id);
|
|
@@ -2407,16 +2717,16 @@ function OrganisationSelector({
|
|
|
2407
2717
|
value: org.id,
|
|
2408
2718
|
disabled: !hasAccess,
|
|
2409
2719
|
className: !hasAccess ? "opacity-50" : "",
|
|
2410
|
-
children: /* @__PURE__ */
|
|
2411
|
-
/* @__PURE__ */
|
|
2412
|
-
/* @__PURE__ */ jsx14(Building2, { className: "
|
|
2413
|
-
/* @__PURE__ */
|
|
2720
|
+
children: /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between w-full", children: [
|
|
2721
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
|
|
2722
|
+
/* @__PURE__ */ jsx14(Building2, { className: "size-4" }),
|
|
2723
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col", children: [
|
|
2414
2724
|
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: org.display_name }),
|
|
2415
2725
|
!compact && org.description && /* @__PURE__ */ jsx14("span", { className: "text-xs text-muted-foreground truncate max-w-40", children: org.description })
|
|
2416
2726
|
] })
|
|
2417
2727
|
] }),
|
|
2418
|
-
showRole && /* @__PURE__ */
|
|
2419
|
-
/* @__PURE__ */ jsx14(Shield, { className: "
|
|
2728
|
+
showRole && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1 ml-4", children: [
|
|
2729
|
+
/* @__PURE__ */ jsx14(Shield, { className: "size-3 text-muted-foreground" }),
|
|
2420
2730
|
/* @__PURE__ */ jsx14("span", { className: "text-xs text-muted-foreground capitalize", children: userRole?.replace("_", " ") || "No Role" })
|
|
2421
2731
|
] })
|
|
2422
2732
|
] })
|
|
@@ -2427,18 +2737,18 @@ function OrganisationSelector({
|
|
|
2427
2737
|
]
|
|
2428
2738
|
}
|
|
2429
2739
|
),
|
|
2430
|
-
switchErrorDisplay
|
|
2740
|
+
switchErrorDisplay && /* @__PURE__ */ jsx14("div", { className: "mt-2", children: switchErrorDisplay })
|
|
2431
2741
|
] });
|
|
2432
2742
|
}
|
|
2433
2743
|
|
|
2434
2744
|
// src/components/PasswordChange/PasswordChangeForm.tsx
|
|
2435
|
-
import { useState as
|
|
2436
|
-
import { jsx as jsx15, jsxs as
|
|
2745
|
+
import { useState as useState9 } from "react";
|
|
2746
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2437
2747
|
function PasswordChangeForm({ onSubmit, className }) {
|
|
2438
|
-
const [newPassword, setNewPassword] =
|
|
2439
|
-
const [confirmPassword, setConfirmPassword] =
|
|
2440
|
-
const [error, setError] =
|
|
2441
|
-
const [isSubmitting, setIsSubmitting] =
|
|
2748
|
+
const [newPassword, setNewPassword] = useState9("");
|
|
2749
|
+
const [confirmPassword, setConfirmPassword] = useState9("");
|
|
2750
|
+
const [error, setError] = useState9(null);
|
|
2751
|
+
const [isSubmitting, setIsSubmitting] = useState9(false);
|
|
2442
2752
|
const handleSubmit = async (e) => {
|
|
2443
2753
|
e.preventDefault();
|
|
2444
2754
|
setError(null);
|
|
@@ -2463,9 +2773,9 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2463
2773
|
setIsSubmitting(false);
|
|
2464
2774
|
}
|
|
2465
2775
|
};
|
|
2466
|
-
return /* @__PURE__ */
|
|
2776
|
+
return /* @__PURE__ */ jsxs10("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: [
|
|
2467
2777
|
error && /* @__PURE__ */ jsx15("div", { role: "alert", children: error }),
|
|
2468
|
-
/* @__PURE__ */
|
|
2778
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
|
|
2469
2779
|
/* @__PURE__ */ jsx15(Label, { htmlFor: "new-password", children: "New Password" }),
|
|
2470
2780
|
/* @__PURE__ */ jsx15(
|
|
2471
2781
|
Input,
|
|
@@ -2479,7 +2789,7 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2479
2789
|
}
|
|
2480
2790
|
)
|
|
2481
2791
|
] }),
|
|
2482
|
-
/* @__PURE__ */
|
|
2792
|
+
/* @__PURE__ */ jsxs10("div", { className: "space-y-2", children: [
|
|
2483
2793
|
/* @__PURE__ */ jsx15(Label, { htmlFor: "confirm-password", children: "Confirm Password" }),
|
|
2484
2794
|
/* @__PURE__ */ jsx15(
|
|
2485
2795
|
Input,
|
|
@@ -2506,9 +2816,9 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2506
2816
|
}
|
|
2507
2817
|
|
|
2508
2818
|
// src/components/UserMenu/UserMenu.tsx
|
|
2509
|
-
import React14, { useCallback as
|
|
2819
|
+
import React14, { useCallback as useCallback9, useMemo as useMemo7, useState as useState10 } from "react";
|
|
2510
2820
|
import { ChevronDown, LogOut, KeyRound } from "lucide-react";
|
|
2511
|
-
import { jsx as jsx16, jsxs as
|
|
2821
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2512
2822
|
var UserMenu = React14.memo(function UserMenu2({
|
|
2513
2823
|
user,
|
|
2514
2824
|
onSignOut,
|
|
@@ -2516,8 +2826,8 @@ var UserMenu = React14.memo(function UserMenu2({
|
|
|
2516
2826
|
className,
|
|
2517
2827
|
showAvatar = true
|
|
2518
2828
|
}) {
|
|
2519
|
-
const [isPasswordDialogOpen, setPasswordDialogOpen] =
|
|
2520
|
-
const userInfo =
|
|
2829
|
+
const [isPasswordDialogOpen, setPasswordDialogOpen] = useState10(false);
|
|
2830
|
+
const userInfo = useMemo7(() => {
|
|
2521
2831
|
if (!user) return null;
|
|
2522
2832
|
return {
|
|
2523
2833
|
email: user.email,
|
|
@@ -2526,15 +2836,15 @@ var UserMenu = React14.memo(function UserMenu2({
|
|
|
2526
2836
|
initial: (user.user_metadata?.display_name || user.user_metadata?.full_name || user.email || "U").charAt(0).toUpperCase()
|
|
2527
2837
|
};
|
|
2528
2838
|
}, [user]);
|
|
2529
|
-
const handleSignOut =
|
|
2839
|
+
const handleSignOut = useCallback9(async () => {
|
|
2530
2840
|
if (onSignOut) await onSignOut();
|
|
2531
2841
|
}, [onSignOut]);
|
|
2532
2842
|
if (!user || !userInfo) {
|
|
2533
2843
|
return null;
|
|
2534
2844
|
}
|
|
2535
|
-
return /* @__PURE__ */
|
|
2536
|
-
/* @__PURE__ */
|
|
2537
|
-
/* @__PURE__ */ jsx16(SelectTrigger, { asChild: true, children: /* @__PURE__ */
|
|
2845
|
+
return /* @__PURE__ */ jsxs11(Dialog, { open: isPasswordDialogOpen, onOpenChange: setPasswordDialogOpen, children: [
|
|
2846
|
+
/* @__PURE__ */ jsxs11(Select, { className, children: [
|
|
2847
|
+
/* @__PURE__ */ jsx16(SelectTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(Button, { variant: "outline", className: "flex items-center gap-2", "aria-label": userInfo.displayName, children: [
|
|
2538
2848
|
showAvatar && /* @__PURE__ */ jsx16(
|
|
2539
2849
|
Avatar,
|
|
2540
2850
|
{
|
|
@@ -2545,26 +2855,26 @@ var UserMenu = React14.memo(function UserMenu2({
|
|
|
2545
2855
|
}
|
|
2546
2856
|
),
|
|
2547
2857
|
/* @__PURE__ */ jsx16("span", { children: userInfo.displayName }),
|
|
2548
|
-
/* @__PURE__ */ jsx16(ChevronDown, { className: "
|
|
2858
|
+
/* @__PURE__ */ jsx16(ChevronDown, { className: "size-4" })
|
|
2549
2859
|
] }) }),
|
|
2550
|
-
/* @__PURE__ */
|
|
2551
|
-
/* @__PURE__ */ jsx16(SelectLabel, { className: "font-normal", children: /* @__PURE__ */
|
|
2860
|
+
/* @__PURE__ */ jsxs11(SelectContent, { children: [
|
|
2861
|
+
/* @__PURE__ */ jsx16(SelectLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs11("div", { className: "flex flex-col space-y-1", children: [
|
|
2552
2862
|
/* @__PURE__ */ jsx16("p", { className: "font-medium", children: userInfo.displayName }),
|
|
2553
2863
|
/* @__PURE__ */ jsx16("p", { className: "text-muted-foreground", children: userInfo.email })
|
|
2554
2864
|
] }) }),
|
|
2555
2865
|
/* @__PURE__ */ jsx16(SelectSeparator, {}),
|
|
2556
|
-
/* @__PURE__ */ jsx16(DialogTrigger, { asChild: true, children: /* @__PURE__ */
|
|
2557
|
-
/* @__PURE__ */ jsx16(KeyRound, { className: "mr-2
|
|
2866
|
+
/* @__PURE__ */ jsx16(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(SelectItem, { value: "change-password", children: [
|
|
2867
|
+
/* @__PURE__ */ jsx16(KeyRound, { className: "mr-2 size-4" }),
|
|
2558
2868
|
/* @__PURE__ */ jsx16("span", { children: "Change Password" })
|
|
2559
2869
|
] }) }),
|
|
2560
|
-
/* @__PURE__ */
|
|
2561
|
-
/* @__PURE__ */ jsx16(LogOut, { className: "mr-2
|
|
2870
|
+
/* @__PURE__ */ jsxs11(SelectItem, { value: "sign-out", onClick: handleSignOut, children: [
|
|
2871
|
+
/* @__PURE__ */ jsx16(LogOut, { className: "mr-2 size-4" }),
|
|
2562
2872
|
/* @__PURE__ */ jsx16("span", { children: "Sign out" })
|
|
2563
2873
|
] })
|
|
2564
2874
|
] })
|
|
2565
2875
|
] }),
|
|
2566
2876
|
/* @__PURE__ */ jsx16(DialogOverlay, {}),
|
|
2567
|
-
/* @__PURE__ */
|
|
2877
|
+
/* @__PURE__ */ jsxs11(DialogContent, { className, children: [
|
|
2568
2878
|
/* @__PURE__ */ jsx16(DialogHeader, { children: /* @__PURE__ */ jsx16(DialogTitle, { children: "Change Password" }) }),
|
|
2569
2879
|
/* @__PURE__ */ jsx16(
|
|
2570
2880
|
PasswordChangeForm,
|
|
@@ -2585,8 +2895,8 @@ var UserMenu = React14.memo(function UserMenu2({
|
|
|
2585
2895
|
] });
|
|
2586
2896
|
});
|
|
2587
2897
|
var UserMenuLoading = React14.memo(function UserMenuLoading2() {
|
|
2588
|
-
return /* @__PURE__ */
|
|
2589
|
-
/* @__PURE__ */
|
|
2898
|
+
return /* @__PURE__ */ jsxs11("div", { className: "relative inline-block text-left", children: [
|
|
2899
|
+
/* @__PURE__ */ jsxs11(
|
|
2590
2900
|
"button",
|
|
2591
2901
|
{
|
|
2592
2902
|
type: "button",
|
|
@@ -2607,7 +2917,7 @@ UserMenu.Loading = UserMenuLoading;
|
|
|
2607
2917
|
// src/components/NavigationMenu/NavigationMenu.tsx
|
|
2608
2918
|
import * as React15 from "react";
|
|
2609
2919
|
import { ChevronDown as ChevronDown2 } from "lucide-react";
|
|
2610
|
-
import { jsx as jsx17, jsxs as
|
|
2920
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
2611
2921
|
var NavigationMenu = React15.forwardRef(({
|
|
2612
2922
|
items,
|
|
2613
2923
|
mode = "dropdown",
|
|
@@ -2660,7 +2970,7 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
2660
2970
|
}
|
|
2661
2971
|
const userId2 = authContext.user.id;
|
|
2662
2972
|
const appName = authContext.appName;
|
|
2663
|
-
import("./api-
|
|
2973
|
+
import("./api-IHKALJZD.js").then(({ resolveAppContext }) => {
|
|
2664
2974
|
resolveAppContext({
|
|
2665
2975
|
userId: userId2,
|
|
2666
2976
|
appName
|
|
@@ -3011,8 +3321,8 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3011
3321
|
const hasChildren = item.children && item.children.length > 0;
|
|
3012
3322
|
const isExpanded = expandedItems.has(item.id);
|
|
3013
3323
|
const itemIsActive = isActiveItem(item);
|
|
3014
|
-
return /* @__PURE__ */ jsx17("li", { role: "none", children: hasChildren ? /* @__PURE__ */
|
|
3015
|
-
/* @__PURE__ */
|
|
3324
|
+
return /* @__PURE__ */ jsx17("li", { role: "none", children: hasChildren ? /* @__PURE__ */ jsxs12("div", { children: [
|
|
3325
|
+
/* @__PURE__ */ jsxs12(
|
|
3016
3326
|
"button",
|
|
3017
3327
|
{
|
|
3018
3328
|
onClick: () => toggleExpanded(item.id),
|
|
@@ -3053,7 +3363,7 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3053
3363
|
) });
|
|
3054
3364
|
};
|
|
3055
3365
|
if (mode === "dropdown") {
|
|
3056
|
-
return /* @__PURE__ */
|
|
3366
|
+
return /* @__PURE__ */ jsxs12(
|
|
3057
3367
|
Select,
|
|
3058
3368
|
{
|
|
3059
3369
|
onValueChange: handleNavigationSelect,
|
|
@@ -3102,7 +3412,7 @@ NavigationMenu.displayName = "NavigationMenu";
|
|
|
3102
3412
|
|
|
3103
3413
|
// src/components/Header/Header.tsx
|
|
3104
3414
|
import { Link } from "react-router-dom";
|
|
3105
|
-
import { jsx as jsx18, jsxs as
|
|
3415
|
+
import { jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3106
3416
|
function Header({
|
|
3107
3417
|
logoUrl,
|
|
3108
3418
|
logoAlt = "Logo",
|
|
@@ -3121,10 +3431,25 @@ function Header({
|
|
|
3121
3431
|
onNavigate,
|
|
3122
3432
|
logoHref
|
|
3123
3433
|
}) {
|
|
3434
|
+
const OrganisationSelectorConditional = () => {
|
|
3435
|
+
const { organisations, isContextReady } = useOrganisations();
|
|
3436
|
+
if (!isContextReady || !organisations || organisations.length === 0) {
|
|
3437
|
+
return null;
|
|
3438
|
+
}
|
|
3439
|
+
return /* @__PURE__ */ jsx18(
|
|
3440
|
+
OrganisationSelector,
|
|
3441
|
+
{
|
|
3442
|
+
placeholder: "Select organisation",
|
|
3443
|
+
className: "w-64",
|
|
3444
|
+
"data-testid": "org-selector",
|
|
3445
|
+
compact: true
|
|
3446
|
+
}
|
|
3447
|
+
);
|
|
3448
|
+
};
|
|
3124
3449
|
return /* @__PURE__ */ jsx18("header", { className: cn(
|
|
3125
3450
|
"w-full border-b border-main-200 h-16 shadow-sm bg-main-100 ",
|
|
3126
3451
|
className
|
|
3127
|
-
), role: "banner", children: /* @__PURE__ */
|
|
3452
|
+
), role: "banner", children: /* @__PURE__ */ jsxs13("nav", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto flex items-center gap-4 h-full", children: [
|
|
3128
3453
|
logo ? logoHref ? /* @__PURE__ */ jsx18(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: logo }) : logo : logoUrl ? logoHref ? /* @__PURE__ */ jsx18(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx18(
|
|
3129
3454
|
"img",
|
|
3130
3455
|
{
|
|
@@ -3144,14 +3469,14 @@ function Header({
|
|
|
3144
3469
|
{
|
|
3145
3470
|
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",
|
|
3146
3471
|
alt: logoAlt || "Logo",
|
|
3147
|
-
className: "
|
|
3472
|
+
className: "size-8 shadow-md"
|
|
3148
3473
|
}
|
|
3149
3474
|
) }) : /* @__PURE__ */ jsx18(
|
|
3150
3475
|
"img",
|
|
3151
3476
|
{
|
|
3152
3477
|
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",
|
|
3153
3478
|
alt: logoAlt || "Logo",
|
|
3154
|
-
className: "
|
|
3479
|
+
className: "size-8 shadow-md"
|
|
3155
3480
|
}
|
|
3156
3481
|
),
|
|
3157
3482
|
navItems && navItems.length > 0 && /* @__PURE__ */ jsx18(
|
|
@@ -3165,16 +3490,8 @@ function Header({
|
|
|
3165
3490
|
itemsPreFiltered: true
|
|
3166
3491
|
}
|
|
3167
3492
|
),
|
|
3168
|
-
/* @__PURE__ */
|
|
3169
|
-
showOrgSelector ? /* @__PURE__ */ jsx18(
|
|
3170
|
-
OrganisationSelector,
|
|
3171
|
-
{
|
|
3172
|
-
placeholder: "Select organisation",
|
|
3173
|
-
className: "w-64",
|
|
3174
|
-
"data-testid": "org-selector",
|
|
3175
|
-
compact: true
|
|
3176
|
-
}
|
|
3177
|
-
) : null,
|
|
3493
|
+
/* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-4 ml-auto", children: [
|
|
3494
|
+
showOrgSelector ? /* @__PURE__ */ jsx18(OrganisationSelectorConditional, {}) : null,
|
|
3178
3495
|
showEventSelector ? /* @__PURE__ */ jsx18(
|
|
3179
3496
|
EventSelector,
|
|
3180
3497
|
{
|
|
@@ -3199,7 +3516,7 @@ function Header({
|
|
|
3199
3516
|
|
|
3200
3517
|
// src/components/Footer/Footer.tsx
|
|
3201
3518
|
import React16 from "react";
|
|
3202
|
-
import { Fragment as
|
|
3519
|
+
import { Fragment as Fragment6, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3203
3520
|
var FooterComponent = ({
|
|
3204
3521
|
companyName = "Solvera Solutions Pty Ltd",
|
|
3205
3522
|
year = (/* @__PURE__ */ new Date()).getFullYear(),
|
|
@@ -3210,9 +3527,9 @@ var FooterComponent = ({
|
|
|
3210
3527
|
children
|
|
3211
3528
|
}) => {
|
|
3212
3529
|
const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
|
|
3213
|
-
return /* @__PURE__ */ jsx19("footer", { className: cn("mt-8 py-6 flex justify-center border-t border-border bg-main-100", className), children: /* @__PURE__ */
|
|
3530
|
+
return /* @__PURE__ */ jsx19("footer", { className: cn("mt-8 py-6 flex justify-center border-t border-border bg-main-100", className), children: /* @__PURE__ */ jsxs14("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
|
|
3214
3531
|
logo && /* @__PURE__ */ jsx19("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
|
|
3215
|
-
children && /* @__PURE__ */ jsx19(
|
|
3532
|
+
children && /* @__PURE__ */ jsx19(Fragment6, { children }),
|
|
3216
3533
|
/* @__PURE__ */ jsx19("span", { className: "text-muted-foreground", children: copyrightText }),
|
|
3217
3534
|
links && links.length > 0 && /* @__PURE__ */ jsx19("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx19("li", { children: /* @__PURE__ */ jsx19("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
|
|
3218
3535
|
] }) });
|
|
@@ -3222,9 +3539,9 @@ var Footer = React16.memo(FooterComponent);
|
|
|
3222
3539
|
Footer.displayName = "Footer";
|
|
3223
3540
|
|
|
3224
3541
|
// src/components/PaceAppLayout/PaceAppLayout.tsx
|
|
3225
|
-
import { useState as
|
|
3542
|
+
import { useState as useState12, useEffect as useEffect8, useMemo as useMemo9 } from "react";
|
|
3226
3543
|
import { Outlet, useNavigate, useLocation } from "react-router-dom";
|
|
3227
|
-
import { Fragment as
|
|
3544
|
+
import { Fragment as Fragment7, jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3228
3545
|
var EMPTY_PAGE_ID_MAPPING = {};
|
|
3229
3546
|
var EMPTY_ROUTE_PERMISSIONS = {};
|
|
3230
3547
|
function PaceAppLayout({
|
|
@@ -3258,7 +3575,13 @@ function PaceAppLayout({
|
|
|
3258
3575
|
onRouteStrictModeViolation
|
|
3259
3576
|
}) {
|
|
3260
3577
|
const { user, signOut, updatePassword, supabase, appId: contextAppId } = useUnifiedAuth();
|
|
3261
|
-
const {
|
|
3578
|
+
const {
|
|
3579
|
+
selectedOrganisation,
|
|
3580
|
+
isContextReady,
|
|
3581
|
+
hasValidOrganisationContext,
|
|
3582
|
+
ensureOrganisationContext,
|
|
3583
|
+
isLoading: organisationLoading
|
|
3584
|
+
} = useOrganisations();
|
|
3262
3585
|
const navigate = useNavigate();
|
|
3263
3586
|
const location = useLocation();
|
|
3264
3587
|
useEventTheme();
|
|
@@ -3274,7 +3597,7 @@ function PaceAppLayout({
|
|
|
3274
3597
|
selectedEventId: selectedEvent?.event_id || null
|
|
3275
3598
|
});
|
|
3276
3599
|
const resolvedAppId = contextAppId || resolvedScope?.appId;
|
|
3277
|
-
const scope =
|
|
3600
|
+
const scope = useMemo9(() => {
|
|
3278
3601
|
if (resolvedScope?.organisationId) {
|
|
3279
3602
|
return resolvedScope;
|
|
3280
3603
|
}
|
|
@@ -3291,19 +3614,19 @@ function PaceAppLayout({
|
|
|
3291
3614
|
appId: resolvedAppId || resolvedScope?.appId || void 0
|
|
3292
3615
|
};
|
|
3293
3616
|
}, [resolvedScope, selectedOrganisation?.id, selectedEvent?.event_id, resolvedAppId]);
|
|
3294
|
-
const defaultNavItems =
|
|
3617
|
+
const defaultNavItems = useMemo9(() => [
|
|
3295
3618
|
{ id: "home", label: "Home", href: "/", icon: "Home" },
|
|
3296
3619
|
{ id: "dashboard", label: "Dashboard", href: "/dashboard", icon: "LayoutDashboard" },
|
|
3297
3620
|
{ id: "settings", label: "Settings", href: "/settings", icon: "Settings" },
|
|
3298
3621
|
{ id: "ui-showcase", label: "UI Showcase", href: "/ui-showcase", icon: "Component" },
|
|
3299
3622
|
{ id: "data-table-showcase", label: "DataTable Showcase", href: "/data-table-showcase", icon: "Table" }
|
|
3300
3623
|
], []);
|
|
3301
|
-
const baseMenuItems =
|
|
3302
|
-
const currentRoutePermission =
|
|
3624
|
+
const baseMenuItems = useMemo9(() => navItems || defaultNavItems, [navItems]);
|
|
3625
|
+
const currentRoutePermission = useMemo9(() => {
|
|
3303
3626
|
const currentPath = location.pathname;
|
|
3304
3627
|
return routePermissions[currentPath] || defaultPermission;
|
|
3305
3628
|
}, [location.pathname, routePermissions, defaultPermission]);
|
|
3306
|
-
const currentPageId =
|
|
3629
|
+
const currentPageId = useMemo9(() => {
|
|
3307
3630
|
const currentPath = location.pathname;
|
|
3308
3631
|
if (pageIdMapping[currentPath]) {
|
|
3309
3632
|
return pageIdMapping[currentPath];
|
|
@@ -3311,15 +3634,15 @@ function PaceAppLayout({
|
|
|
3311
3634
|
const pathSegments = currentPath.slice(1).split("/").filter(Boolean);
|
|
3312
3635
|
return pathSegments[0] || "home";
|
|
3313
3636
|
}, [location.pathname, pageIdMapping]);
|
|
3314
|
-
const currentPermission =
|
|
3637
|
+
const currentPermission = useMemo9(() => {
|
|
3315
3638
|
if (!enforcePermissions) {
|
|
3316
3639
|
return "read:page.home";
|
|
3317
3640
|
}
|
|
3318
3641
|
const permissionString = `${currentRoutePermission}:page.${currentPageId}`;
|
|
3319
3642
|
return permissionString;
|
|
3320
3643
|
}, [enforcePermissions, currentRoutePermission, currentPageId]);
|
|
3321
|
-
const [isSuperAdminUser, setIsSuperAdminUser] =
|
|
3322
|
-
const [isCheckingSuperAdmin, setIsCheckingSuperAdmin] =
|
|
3644
|
+
const [isSuperAdminUser, setIsSuperAdminUser] = useState12(false);
|
|
3645
|
+
const [isCheckingSuperAdmin, setIsCheckingSuperAdmin] = useState12(false);
|
|
3323
3646
|
useEffect8(() => {
|
|
3324
3647
|
const checkSuperAdminStatus = async () => {
|
|
3325
3648
|
if (!user?.id) {
|
|
@@ -3345,8 +3668,10 @@ function PaceAppLayout({
|
|
|
3345
3668
|
scope,
|
|
3346
3669
|
currentPermission,
|
|
3347
3670
|
currentPageId,
|
|
3348
|
-
true
|
|
3671
|
+
true,
|
|
3349
3672
|
// useCache
|
|
3673
|
+
appName
|
|
3674
|
+
// Pass appName for PORTAL/ADMIN special case
|
|
3350
3675
|
);
|
|
3351
3676
|
const can = isSuperAdminUser ? true : canFromHook;
|
|
3352
3677
|
const hasPermission = enforcePermissions ? can : true;
|
|
@@ -3373,7 +3698,7 @@ function PaceAppLayout({
|
|
|
3373
3698
|
onPageAccessDenied(currentPageId, currentRoutePermission);
|
|
3374
3699
|
}
|
|
3375
3700
|
}, [enforcePermissions, can, isCheckingPermission, isCheckingSuperAdmin, isSuperAdminUser, currentPageId, currentRoutePermission, user?.id, strictMode, auditLog, onPageAccessDenied, onStrictModeViolation]);
|
|
3376
|
-
const [filteredMenuItems, setFilteredMenuItems] =
|
|
3701
|
+
const [filteredMenuItems, setFilteredMenuItems] = useState12(baseMenuItems);
|
|
3377
3702
|
useEffect8(() => {
|
|
3378
3703
|
let isMounted = true;
|
|
3379
3704
|
const filterItems = async () => {
|
|
@@ -3400,7 +3725,7 @@ function PaceAppLayout({
|
|
|
3400
3725
|
return;
|
|
3401
3726
|
}
|
|
3402
3727
|
try {
|
|
3403
|
-
const { isSuperAdmin: isSuperAdmin2 } = await import("./api-
|
|
3728
|
+
const { isSuperAdmin: isSuperAdmin2 } = await import("./api-IHKALJZD.js");
|
|
3404
3729
|
const isSuper = await isSuperAdmin2(user.id);
|
|
3405
3730
|
if (isSuper) {
|
|
3406
3731
|
if (isMounted) {
|
|
@@ -3415,7 +3740,7 @@ function PaceAppLayout({
|
|
|
3415
3740
|
}
|
|
3416
3741
|
}
|
|
3417
3742
|
try {
|
|
3418
|
-
const { getPermissionMap } = await import("./api-
|
|
3743
|
+
const { getPermissionMap } = await import("./api-IHKALJZD.js");
|
|
3419
3744
|
const permissionScope = {
|
|
3420
3745
|
organisationId: currentScope.organisationId,
|
|
3421
3746
|
eventId: currentScope.eventId,
|
|
@@ -3471,7 +3796,7 @@ function PaceAppLayout({
|
|
|
3471
3796
|
let hasAccess = true;
|
|
3472
3797
|
if (currentRoute.pageId && currentRoute.permissions && currentRoute.permissions.length > 0) {
|
|
3473
3798
|
try {
|
|
3474
|
-
const { isPermittedCached } = await import("./api-
|
|
3799
|
+
const { isPermittedCached } = await import("./api-IHKALJZD.js");
|
|
3475
3800
|
const hasPagePermission = await isPermittedCached({
|
|
3476
3801
|
userId: user?.id || "",
|
|
3477
3802
|
scope,
|
|
@@ -3487,7 +3812,7 @@ function PaceAppLayout({
|
|
|
3487
3812
|
}
|
|
3488
3813
|
}
|
|
3489
3814
|
if (hasAccess && currentRoute.roles && currentRoute.roles.length > 0 && user?.id) {
|
|
3490
|
-
const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-
|
|
3815
|
+
const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-FTSG5XH7.js");
|
|
3491
3816
|
hasAccess = true;
|
|
3492
3817
|
}
|
|
3493
3818
|
if (!isMounted) return;
|
|
@@ -3533,14 +3858,20 @@ function PaceAppLayout({
|
|
|
3533
3858
|
}
|
|
3534
3859
|
return {};
|
|
3535
3860
|
};
|
|
3861
|
+
if (user?.id && organisationLoading) {
|
|
3862
|
+
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
|
|
3863
|
+
/* @__PURE__ */ jsx20("div", { className: "animate-spin rounded-full size-8 border-b-2 border-sec-900 mx-auto mb-4" }),
|
|
3864
|
+
/* @__PURE__ */ jsx20("p", { className: "text-sec-600", children: "Loading organisation context..." })
|
|
3865
|
+
] }) });
|
|
3866
|
+
}
|
|
3536
3867
|
if (enforcePermissions && (isCheckingSuperAdmin || isCheckingPermission)) {
|
|
3537
|
-
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */
|
|
3538
|
-
/* @__PURE__ */ jsx20("div", { className: "animate-spin rounded-full
|
|
3868
|
+
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
|
|
3869
|
+
/* @__PURE__ */ jsx20("div", { className: "animate-spin rounded-full size-8 border-b-2 border-sec-900 mx-auto mb-4" }),
|
|
3539
3870
|
/* @__PURE__ */ jsx20("p", { className: "text-sec-600", children: "Checking permissions..." })
|
|
3540
3871
|
] }) });
|
|
3541
3872
|
}
|
|
3542
3873
|
if (enforcePermissions && permissionError && !isSuperAdminUser) {
|
|
3543
|
-
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */
|
|
3874
|
+
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
|
|
3544
3875
|
/* @__PURE__ */ jsx20("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Permission Error" }),
|
|
3545
3876
|
/* @__PURE__ */ jsx20("p", { className: "text-sec-600 mb-4", children: permissionError.message }),
|
|
3546
3877
|
/* @__PURE__ */ jsx20(Button, { onClick: () => navigate("/"), children: "Go Home" })
|
|
@@ -3548,15 +3879,15 @@ function PaceAppLayout({
|
|
|
3548
3879
|
}
|
|
3549
3880
|
if (enforcePermissions && hasPermission === false && !isCheckingSuperAdmin && !isSuperAdminUser) {
|
|
3550
3881
|
if (enforcePagePermissions && pagePermissionFallback) {
|
|
3551
|
-
return /* @__PURE__ */ jsx20(
|
|
3882
|
+
return /* @__PURE__ */ jsx20(Fragment7, { children: pagePermissionFallback });
|
|
3552
3883
|
}
|
|
3553
3884
|
if (permissionFallback) {
|
|
3554
|
-
return /* @__PURE__ */ jsx20(
|
|
3885
|
+
return /* @__PURE__ */ jsx20(Fragment7, { children: permissionFallback });
|
|
3555
3886
|
}
|
|
3556
|
-
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */
|
|
3887
|
+
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
|
|
3557
3888
|
/* @__PURE__ */ jsx20("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Access Denied" }),
|
|
3558
3889
|
/* @__PURE__ */ jsx20("p", { className: "text-sec-600 mb-4", children: "You don't have permission to access this page." }),
|
|
3559
|
-
/* @__PURE__ */
|
|
3890
|
+
/* @__PURE__ */ jsxs15("div", { className: "flex gap-2 justify-center", children: [
|
|
3560
3891
|
/* @__PURE__ */ jsx20(Button, { onClick: () => navigate("/"), children: "Go Home" }),
|
|
3561
3892
|
/* @__PURE__ */ jsx20(
|
|
3562
3893
|
Button,
|
|
@@ -3572,7 +3903,7 @@ function PaceAppLayout({
|
|
|
3572
3903
|
] })
|
|
3573
3904
|
] }) });
|
|
3574
3905
|
}
|
|
3575
|
-
return /* @__PURE__ */
|
|
3906
|
+
return /* @__PURE__ */ jsxs15(Fragment7, { children: [
|
|
3576
3907
|
/* @__PURE__ */ jsx20(
|
|
3577
3908
|
Header,
|
|
3578
3909
|
{
|
|
@@ -3604,9 +3935,9 @@ function PaceAppLayout({
|
|
|
3604
3935
|
}
|
|
3605
3936
|
|
|
3606
3937
|
// src/components/PaceLoginPage/PaceLoginPage.tsx
|
|
3607
|
-
import { useEffect as useEffect9, useState as
|
|
3938
|
+
import { useEffect as useEffect9, useState as useState13, useContext as useContext2 } from "react";
|
|
3608
3939
|
import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
|
|
3609
|
-
import { jsx as jsx21, jsxs as
|
|
3940
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3610
3941
|
var PaceLoginPage = ({
|
|
3611
3942
|
appName = "Pace",
|
|
3612
3943
|
onSuccessRedirectPath = "/",
|
|
@@ -3615,9 +3946,9 @@ var PaceLoginPage = ({
|
|
|
3615
3946
|
const { signIn, isAuthenticated, isLoading, authError, user, supabase } = useUnifiedAuth();
|
|
3616
3947
|
const navigate = useNavigate2();
|
|
3617
3948
|
const location = useLocation2();
|
|
3618
|
-
const [isSigningIn, setIsSigningIn] =
|
|
3619
|
-
const [accessError, setAccessError] =
|
|
3620
|
-
const [isCheckingAccess, setIsCheckingAccess] =
|
|
3949
|
+
const [isSigningIn, setIsSigningIn] = useState13(false);
|
|
3950
|
+
const [accessError, setAccessError] = useState13(null);
|
|
3951
|
+
const [isCheckingAccess, setIsCheckingAccess] = useState13(false);
|
|
3621
3952
|
const eventServiceContext = useContext2(EventServiceContext);
|
|
3622
3953
|
const eventService = eventServiceContext?.eventService || null;
|
|
3623
3954
|
useEffect9(() => {
|
|
@@ -3676,8 +4007,9 @@ var PaceLoginPage = ({
|
|
|
3676
4007
|
setIsCheckingAccess(false);
|
|
3677
4008
|
return;
|
|
3678
4009
|
}
|
|
3679
|
-
const { data:
|
|
3680
|
-
|
|
4010
|
+
const { data: orgRow } = await supabase.from("rbac_organisation_roles").select("organisation_id").eq("user_id", userId).eq("status", "active").is("revoked_at", null).limit(1).maybeSingle();
|
|
4011
|
+
const organisationId = orgRow?.organisation_id;
|
|
4012
|
+
if (!organisationId) {
|
|
3681
4013
|
logger.debug("PaceLoginPage", "User has no organisation access");
|
|
3682
4014
|
setAccessError(`You do not have permission to access ${appName}. You are not assigned to any organisation. Please contact your administrator.`);
|
|
3683
4015
|
setIsCheckingAccess(false);
|
|
@@ -3689,7 +4021,7 @@ var PaceLoginPage = ({
|
|
|
3689
4021
|
p_user_id: userId,
|
|
3690
4022
|
p_permission: `read:page.${page.page_name}`,
|
|
3691
4023
|
// Permission format: operation:resource
|
|
3692
|
-
p_organisation_id:
|
|
4024
|
+
p_organisation_id: organisationId,
|
|
3693
4025
|
p_event_id: null,
|
|
3694
4026
|
p_app_id: appData.id,
|
|
3695
4027
|
p_page_id: page.page_name
|
|
@@ -3737,7 +4069,7 @@ var PaceLoginPage = ({
|
|
|
3737
4069
|
setIsSigningIn(false);
|
|
3738
4070
|
}
|
|
3739
4071
|
};
|
|
3740
|
-
return /* @__PURE__ */
|
|
4072
|
+
return /* @__PURE__ */ jsxs16("main", { className: "min-h-screen grid mx-auto w-fit content-center justify-items-center gap-y-8", "aria-label": `${appName} Login Page`, children: [
|
|
3741
4073
|
/* @__PURE__ */ jsx21(
|
|
3742
4074
|
"img",
|
|
3743
4075
|
{
|
|
@@ -3768,12 +4100,12 @@ var PaceLoginPage = ({
|
|
|
3768
4100
|
};
|
|
3769
4101
|
|
|
3770
4102
|
// src/components/SessionRestorationLoader/SessionRestorationLoader.tsx
|
|
3771
|
-
import { jsx as jsx22, jsxs as
|
|
4103
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3772
4104
|
var SessionRestorationLoader = ({
|
|
3773
4105
|
message = "Restoring session...",
|
|
3774
4106
|
className
|
|
3775
4107
|
}) => {
|
|
3776
|
-
return /* @__PURE__ */
|
|
4108
|
+
return /* @__PURE__ */ jsxs17(
|
|
3777
4109
|
"div",
|
|
3778
4110
|
{
|
|
3779
4111
|
className: cn(
|
|
@@ -3792,9 +4124,9 @@ var SessionRestorationLoader = ({
|
|
|
3792
4124
|
};
|
|
3793
4125
|
|
|
3794
4126
|
// src/components/ProtectedRoute/ProtectedRoute.tsx
|
|
3795
|
-
import { useMemo as
|
|
4127
|
+
import { useMemo as useMemo10, useEffect as useEffect10, useRef as useRef8, useState as useState14 } from "react";
|
|
3796
4128
|
import { Navigate, Outlet as Outlet2 } from "react-router-dom";
|
|
3797
|
-
import { jsx as jsx23, jsxs as
|
|
4129
|
+
import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
3798
4130
|
function ProtectedRoute({
|
|
3799
4131
|
requireEvent = false,
|
|
3800
4132
|
allowSuperAdminBypass = false,
|
|
@@ -3809,9 +4141,9 @@ function ProtectedRoute({
|
|
|
3809
4141
|
const eventLoading = requireEvent ? eventsContext.isLoading || false : false;
|
|
3810
4142
|
const sessionRestoration = useSessionRestoration();
|
|
3811
4143
|
usePreventTabReload({ enabled: true, gracePeriodMs: 2e3 });
|
|
3812
|
-
const wasAuthenticatedRef =
|
|
3813
|
-
const [shouldRedirect, setShouldRedirect] =
|
|
3814
|
-
const tabJustBecameVisibleRef =
|
|
4144
|
+
const wasAuthenticatedRef = useRef8(false);
|
|
4145
|
+
const [shouldRedirect, setShouldRedirect] = useState14(false);
|
|
4146
|
+
const tabJustBecameVisibleRef = useRef8(false);
|
|
3815
4147
|
useEffect10(() => {
|
|
3816
4148
|
if (isAuthenticated) {
|
|
3817
4149
|
wasAuthenticatedRef.current = true;
|
|
@@ -3869,7 +4201,7 @@ function ProtectedRoute({
|
|
|
3869
4201
|
tabJustBecameVisibleRef.current = false;
|
|
3870
4202
|
}
|
|
3871
4203
|
}, [isAuthenticated]);
|
|
3872
|
-
const isRestoringSession =
|
|
4204
|
+
const isRestoringSession = useMemo10(() => {
|
|
3873
4205
|
return sessionRestoration.isRestoring && !sessionRestoration.restorationComplete && !sessionRestoration.restorationError && !sessionRestoration.hasTimedOut;
|
|
3874
4206
|
}, [
|
|
3875
4207
|
sessionRestoration.isRestoring,
|
|
@@ -3913,7 +4245,7 @@ function ProtectedRoute({
|
|
|
3913
4245
|
return /* @__PURE__ */ jsx23(Outlet2, {});
|
|
3914
4246
|
}
|
|
3915
4247
|
if (!events || events.length === 0) {
|
|
3916
|
-
return noEventsFallback || /* @__PURE__ */ jsx23("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "100vh", padding: "2rem" }, children: /* @__PURE__ */
|
|
4248
|
+
return noEventsFallback || /* @__PURE__ */ jsx23("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "100vh", padding: "2rem" }, children: /* @__PURE__ */ jsxs18(Alert, { variant: "destructive", className: "max-w-md", children: [
|
|
3917
4249
|
/* @__PURE__ */ jsx23(AlertTitle, { children: "No Events Available" }),
|
|
3918
4250
|
/* @__PURE__ */ jsx23(AlertDescription, { children: "You don't have access to any events. Please contact your administrator if you believe this is an error." })
|
|
3919
4251
|
] }) });
|
|
@@ -3926,13 +4258,14 @@ function ProtectedRoute({
|
|
|
3926
4258
|
}
|
|
3927
4259
|
|
|
3928
4260
|
// src/components/FileUpload/FileUpload.tsx
|
|
3929
|
-
import { useState as
|
|
3930
|
-
import { Fragment as
|
|
4261
|
+
import { useState as useState15, useCallback as useCallback11, useRef as useRef9, useEffect as useEffect11, useMemo as useMemo11 } from "react";
|
|
4262
|
+
import { Fragment as Fragment8, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3931
4263
|
function FileUpload({
|
|
3932
4264
|
supabase,
|
|
3933
4265
|
table_name,
|
|
3934
4266
|
record_id,
|
|
3935
4267
|
organisation_id,
|
|
4268
|
+
userId,
|
|
3936
4269
|
app_id,
|
|
3937
4270
|
category,
|
|
3938
4271
|
folder,
|
|
@@ -3952,12 +4285,12 @@ function FileUpload({
|
|
|
3952
4285
|
onProgress,
|
|
3953
4286
|
children
|
|
3954
4287
|
}) {
|
|
3955
|
-
const [isDragging, setIsDragging] =
|
|
3956
|
-
const [uploadStates, setUploadStates] =
|
|
3957
|
-
const [resolvedAppId, setResolvedAppId] =
|
|
3958
|
-
const [isResolvingAppId, setIsResolvingAppId] =
|
|
3959
|
-
const [appIdError, setAppIdError] =
|
|
3960
|
-
const fileInputRef =
|
|
4288
|
+
const [isDragging, setIsDragging] = useState15(false);
|
|
4289
|
+
const [uploadStates, setUploadStates] = useState15(/* @__PURE__ */ new Map());
|
|
4290
|
+
const [resolvedAppId, setResolvedAppId] = useState15(app_id || null);
|
|
4291
|
+
const [isResolvingAppId, setIsResolvingAppId] = useState15(!app_id);
|
|
4292
|
+
const [appIdError, setAppIdError] = useState15(null);
|
|
4293
|
+
const fileInputRef = useRef9(null);
|
|
3961
4294
|
const { uploadFile, isLoading, error } = useFileReference(supabase);
|
|
3962
4295
|
useEffect11(() => {
|
|
3963
4296
|
if (app_id) {
|
|
@@ -3994,15 +4327,15 @@ function FileUpload({
|
|
|
3994
4327
|
};
|
|
3995
4328
|
resolveAppId();
|
|
3996
4329
|
}, [app_id, supabase]);
|
|
3997
|
-
const isUploading =
|
|
4330
|
+
const isUploading = useMemo11(() => {
|
|
3998
4331
|
return uploadStates.size > 0 && Array.from(uploadStates.values()).some(
|
|
3999
4332
|
(state) => state.progress.status === "uploading" || state.progress.status === "processing"
|
|
4000
4333
|
);
|
|
4001
4334
|
}, [uploadStates]);
|
|
4002
|
-
const isDisabled =
|
|
4335
|
+
const isDisabled = useMemo11(() => {
|
|
4003
4336
|
return disabled || isUploading || isResolvingAppId || !resolvedAppId;
|
|
4004
4337
|
}, [disabled, isUploading, isResolvingAppId, resolvedAppId]);
|
|
4005
|
-
const generatePreview =
|
|
4338
|
+
const generatePreview = useCallback11((file) => {
|
|
4006
4339
|
return new Promise((resolve) => {
|
|
4007
4340
|
if (!file.type.startsWith("image/")) {
|
|
4008
4341
|
resolve(null);
|
|
@@ -4016,7 +4349,7 @@ function FileUpload({
|
|
|
4016
4349
|
reader.readAsDataURL(file);
|
|
4017
4350
|
});
|
|
4018
4351
|
}, []);
|
|
4019
|
-
const validateFile =
|
|
4352
|
+
const validateFile = useCallback11((file) => {
|
|
4020
4353
|
if (file.size > maxSize) {
|
|
4021
4354
|
return `File "${file.name}" exceeds maximum size of ${Math.round(maxSize / 1024 / 1024)}MB`;
|
|
4022
4355
|
}
|
|
@@ -4040,7 +4373,7 @@ function FileUpload({
|
|
|
4040
4373
|
}
|
|
4041
4374
|
return null;
|
|
4042
4375
|
}, [accept, maxSize]);
|
|
4043
|
-
const handleFileSelect =
|
|
4376
|
+
const handleFileSelect = useCallback11(async (files) => {
|
|
4044
4377
|
if (!files || files.length === 0) return;
|
|
4045
4378
|
const fileArray = Array.from(files);
|
|
4046
4379
|
const validationErrors = [];
|
|
@@ -4122,7 +4455,9 @@ function FileUpload({
|
|
|
4122
4455
|
const result = await uploadFile({
|
|
4123
4456
|
table_name,
|
|
4124
4457
|
record_id,
|
|
4125
|
-
organisation_id,
|
|
4458
|
+
organisation_id: organisation_id || null,
|
|
4459
|
+
userId,
|
|
4460
|
+
// Pass userId prop directly - it's required for user-scoped files when organisation_id is null
|
|
4126
4461
|
app_id: resolvedAppId ? assertAppId(resolvedAppId) : assertAppId(""),
|
|
4127
4462
|
category,
|
|
4128
4463
|
folder,
|
|
@@ -4215,19 +4550,19 @@ function FileUpload({
|
|
|
4215
4550
|
}
|
|
4216
4551
|
}
|
|
4217
4552
|
}, [uploadFile, table_name, record_id, organisation_id, resolvedAppId, category, folder, isPublic, maxSize, onUploadSuccess, onUploadError, onProgress, validateFile, generatePreview, showPreview, appIdError]);
|
|
4218
|
-
const handleDragOver =
|
|
4553
|
+
const handleDragOver = useCallback11((e) => {
|
|
4219
4554
|
e.preventDefault();
|
|
4220
4555
|
e.stopPropagation();
|
|
4221
4556
|
if (!isDisabled) {
|
|
4222
4557
|
setIsDragging(true);
|
|
4223
4558
|
}
|
|
4224
4559
|
}, [isDisabled]);
|
|
4225
|
-
const handleDragLeave =
|
|
4560
|
+
const handleDragLeave = useCallback11((e) => {
|
|
4226
4561
|
e.preventDefault();
|
|
4227
4562
|
e.stopPropagation();
|
|
4228
4563
|
setIsDragging(false);
|
|
4229
4564
|
}, []);
|
|
4230
|
-
const handleDrop =
|
|
4565
|
+
const handleDrop = useCallback11((e) => {
|
|
4231
4566
|
e.preventDefault();
|
|
4232
4567
|
e.stopPropagation();
|
|
4233
4568
|
setIsDragging(false);
|
|
@@ -4235,13 +4570,13 @@ function FileUpload({
|
|
|
4235
4570
|
const files = e.dataTransfer.files;
|
|
4236
4571
|
handleFileSelect(files);
|
|
4237
4572
|
}, [isDisabled, handleFileSelect]);
|
|
4238
|
-
const handleFileInputChange =
|
|
4573
|
+
const handleFileInputChange = useCallback11((e) => {
|
|
4239
4574
|
handleFileSelect(e.target.files);
|
|
4240
4575
|
if (e.target) {
|
|
4241
4576
|
e.target.value = "";
|
|
4242
4577
|
}
|
|
4243
4578
|
}, [handleFileSelect]);
|
|
4244
|
-
const handleClick =
|
|
4579
|
+
const handleClick = useCallback11(() => {
|
|
4245
4580
|
if (!isDisabled && fileInputRef.current) {
|
|
4246
4581
|
fileInputRef.current.click();
|
|
4247
4582
|
}
|
|
@@ -4255,8 +4590,8 @@ function FileUpload({
|
|
|
4255
4590
|
};
|
|
4256
4591
|
const dragClasses = isDragging ? "border-main-500 bg-main-50" : "border-sec-300 hover:border-sec-400";
|
|
4257
4592
|
const disabledClasses = isDisabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-sec-50";
|
|
4258
|
-
return /* @__PURE__ */
|
|
4259
|
-
/* @__PURE__ */
|
|
4593
|
+
return /* @__PURE__ */ jsxs19("div", { className: `space-y-4 ${className}`, children: [
|
|
4594
|
+
/* @__PURE__ */ jsxs19(
|
|
4260
4595
|
"div",
|
|
4261
4596
|
{
|
|
4262
4597
|
role: "button",
|
|
@@ -4275,7 +4610,7 @@ function FileUpload({
|
|
|
4275
4610
|
}
|
|
4276
4611
|
} : void 0,
|
|
4277
4612
|
children: [
|
|
4278
|
-
children || /* @__PURE__ */
|
|
4613
|
+
children || /* @__PURE__ */ jsxs19("div", { className: "space-y-2", children: [
|
|
4279
4614
|
/* @__PURE__ */ jsx24(
|
|
4280
4615
|
"input",
|
|
4281
4616
|
{
|
|
@@ -4289,12 +4624,12 @@ function FileUpload({
|
|
|
4289
4624
|
"data-testid": "file-input"
|
|
4290
4625
|
}
|
|
4291
4626
|
),
|
|
4292
|
-
/* @__PURE__ */ jsx24("div", { className: "text-sec-600", children: isResolvingAppId ? "Resolving app configuration..." : isDragging ? "Drop files here..." : /* @__PURE__ */
|
|
4627
|
+
/* @__PURE__ */ jsx24("div", { className: "text-sec-600", children: isResolvingAppId ? "Resolving app configuration..." : isDragging ? "Drop files here..." : /* @__PURE__ */ jsxs19(Fragment8, { children: [
|
|
4293
4628
|
/* @__PURE__ */ jsx24("span", { className: "font-medium", children: "Click to upload" }),
|
|
4294
4629
|
" ",
|
|
4295
4630
|
"or drag and drop"
|
|
4296
4631
|
] }) }),
|
|
4297
|
-
/* @__PURE__ */
|
|
4632
|
+
/* @__PURE__ */ jsxs19("div", { className: "text-sm text-sec-500", children: [
|
|
4298
4633
|
!isResolvingAppId && accept !== "*/*" && `Accepted formats: ${accept}`,
|
|
4299
4634
|
!isResolvingAppId && maxSize && ` \u2022 Max size: ${Math.round(maxSize / 1024 / 1024)}MB`,
|
|
4300
4635
|
!isResolvingAppId && multiple && " \u2022 Multiple files allowed"
|
|
@@ -4307,7 +4642,7 @@ function FileUpload({
|
|
|
4307
4642
|
role: "status",
|
|
4308
4643
|
"aria-live": "polite",
|
|
4309
4644
|
"aria-label": "Uploading file",
|
|
4310
|
-
children: /* @__PURE__ */ jsx24("div", { className: "animate-spin rounded-full
|
|
4645
|
+
children: /* @__PURE__ */ jsx24("div", { className: "animate-spin rounded-full size-8 border-b-2 border-main-500", "aria-hidden": "true" })
|
|
4311
4646
|
}
|
|
4312
4647
|
)
|
|
4313
4648
|
]
|
|
@@ -4318,7 +4653,7 @@ function FileUpload({
|
|
|
4318
4653
|
const isError = progress.status === "error";
|
|
4319
4654
|
const isCompleted = progress.status === "completed";
|
|
4320
4655
|
const isUploading2 = progress.status === "uploading" || progress.status === "processing";
|
|
4321
|
-
return /* @__PURE__ */
|
|
4656
|
+
return /* @__PURE__ */ jsxs19(
|
|
4322
4657
|
"div",
|
|
4323
4658
|
{
|
|
4324
4659
|
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"}`,
|
|
@@ -4331,14 +4666,14 @@ function FileUpload({
|
|
|
4331
4666
|
className: "w-12 h-12 object-cover rounded"
|
|
4332
4667
|
}
|
|
4333
4668
|
) : /* @__PURE__ */ jsx24("div", { className: "w-12 h-12 flex items-center justify-center bg-sec-200 rounded", children: /* @__PURE__ */ jsx24("span", { className: "text-2xl", children: "\u{1F4C4}" }) }) }),
|
|
4334
|
-
/* @__PURE__ */
|
|
4669
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-1 min-w-0", children: [
|
|
4335
4670
|
/* @__PURE__ */ jsx24("div", { className: "font-medium text-sec-900 truncate", children: file.name }),
|
|
4336
|
-
/* @__PURE__ */
|
|
4671
|
+
/* @__PURE__ */ jsxs19("div", { className: "text-sm text-sec-500", children: [
|
|
4337
4672
|
formatFileSize(file.size),
|
|
4338
4673
|
isCompleted && result && " \u2022 Uploaded",
|
|
4339
4674
|
isError && progress.error && ` \u2022 ${progress.error}`
|
|
4340
4675
|
] }),
|
|
4341
|
-
showProgress && (isUploading2 || isError) && /* @__PURE__ */
|
|
4676
|
+
showProgress && (isUploading2 || isError) && /* @__PURE__ */ jsxs19("div", { className: "mt-2", children: [
|
|
4342
4677
|
/* @__PURE__ */ jsx24("div", { className: "w-full bg-sec-200 rounded-full h-2", children: /* @__PURE__ */ jsx24(
|
|
4343
4678
|
"div",
|
|
4344
4679
|
{
|
|
@@ -4346,7 +4681,7 @@ function FileUpload({
|
|
|
4346
4681
|
style: { width: `${progress.percentage}%` }
|
|
4347
4682
|
}
|
|
4348
4683
|
) }),
|
|
4349
|
-
isUploading2 && /* @__PURE__ */
|
|
4684
|
+
isUploading2 && /* @__PURE__ */ jsxs19("div", { className: "text-xs text-sec-500 mt-1", children: [
|
|
4350
4685
|
progress.percentage,
|
|
4351
4686
|
"% \u2022 ",
|
|
4352
4687
|
formatFileSize(progress.loaded),
|
|
@@ -4355,13 +4690,13 @@ function FileUpload({
|
|
|
4355
4690
|
] })
|
|
4356
4691
|
] })
|
|
4357
4692
|
] }),
|
|
4358
|
-
/* @__PURE__ */
|
|
4693
|
+
/* @__PURE__ */ jsxs19("div", { className: "flex-shrink-0", children: [
|
|
4359
4694
|
isCompleted && /* @__PURE__ */ jsx24("span", { className: "text-success-500 text-xl", children: "\u2713" }),
|
|
4360
4695
|
isError && /* @__PURE__ */ jsx24("span", { className: "text-acc-500 text-xl", children: "\u2715" }),
|
|
4361
4696
|
isUploading2 && /* @__PURE__ */ jsx24(
|
|
4362
4697
|
"div",
|
|
4363
4698
|
{
|
|
4364
|
-
className: "animate-spin rounded-full
|
|
4699
|
+
className: "animate-spin rounded-full size-5 border-b-2 border-main-500",
|
|
4365
4700
|
role: "status",
|
|
4366
4701
|
"aria-label": "Uploading",
|
|
4367
4702
|
"aria-hidden": "true"
|
|
@@ -4473,7 +4808,7 @@ var TableCaption = React21.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
4473
4808
|
TableCaption.displayName = "TableCaption";
|
|
4474
4809
|
|
|
4475
4810
|
// src/components/PublicLayout/PublicPageLayout.tsx
|
|
4476
|
-
import { Fragment as
|
|
4811
|
+
import { Fragment as Fragment9, jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4477
4812
|
function PublicPageHeader({
|
|
4478
4813
|
event,
|
|
4479
4814
|
eventCode,
|
|
@@ -4486,7 +4821,7 @@ function PublicPageHeader({
|
|
|
4486
4821
|
customEventLogo
|
|
4487
4822
|
}) {
|
|
4488
4823
|
const { appName } = useAppConfig();
|
|
4489
|
-
return /* @__PURE__ */
|
|
4824
|
+
return /* @__PURE__ */ jsxs20("header", { className: cn(
|
|
4490
4825
|
"w-full px-[max(0rem,calc((100vw-var(--app-width))/2-0.5rem))] grid grid-cols-[auto_1fr_auto] place-items-center gap-2",
|
|
4491
4826
|
className
|
|
4492
4827
|
), children: [
|
|
@@ -4498,9 +4833,9 @@ function PublicPageHeader({
|
|
|
4498
4833
|
alt: appName
|
|
4499
4834
|
}
|
|
4500
4835
|
),
|
|
4501
|
-
event && /* @__PURE__ */
|
|
4836
|
+
event && /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
4502
4837
|
/* @__PURE__ */ jsx26("h1", { children: event.event_name }),
|
|
4503
|
-
showEventLogo && event && /* @__PURE__ */ jsx26(
|
|
4838
|
+
showEventLogo && event && /* @__PURE__ */ jsx26(Fragment9, { children: customEventLogo || /* @__PURE__ */ jsx26(
|
|
4504
4839
|
FileDisplay,
|
|
4505
4840
|
{
|
|
4506
4841
|
table_name: "event",
|
|
@@ -4519,11 +4854,11 @@ function PublicPageHeader({
|
|
|
4519
4854
|
) }),
|
|
4520
4855
|
event.event_venue && /* @__PURE__ */ jsx26("h4", { children: event.event_venue })
|
|
4521
4856
|
] }),
|
|
4522
|
-
title && /* @__PURE__ */
|
|
4857
|
+
title && /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
4523
4858
|
/* @__PURE__ */ jsx26("h1", { children: title }),
|
|
4524
4859
|
description && /* @__PURE__ */ jsx26("p", { className: "text-lg text-sec-600 max-w-3xl mx-auto", children: description })
|
|
4525
4860
|
] }),
|
|
4526
|
-
children && /* @__PURE__ */ jsx26(
|
|
4861
|
+
children && /* @__PURE__ */ jsx26(Fragment9, { children })
|
|
4527
4862
|
] });
|
|
4528
4863
|
}
|
|
4529
4864
|
function PublicPageFooter({
|
|
@@ -4537,9 +4872,9 @@ function PublicPageFooter({
|
|
|
4537
4872
|
children
|
|
4538
4873
|
}) {
|
|
4539
4874
|
const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
|
|
4540
|
-
return /* @__PURE__ */ jsx26("footer", { className: cn("mt-8 py-6 flex justify-center", className), children: /* @__PURE__ */
|
|
4875
|
+
return /* @__PURE__ */ jsx26("footer", { className: cn("mt-8 py-6 flex justify-center", className), children: /* @__PURE__ */ jsxs20("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
|
|
4541
4876
|
logo && /* @__PURE__ */ jsx26("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
|
|
4542
|
-
children && /* @__PURE__ */ jsx26(
|
|
4877
|
+
children && /* @__PURE__ */ jsx26(Fragment9, { children }),
|
|
4543
4878
|
/* @__PURE__ */ jsx26("span", { className: "text-muted-foreground", children: copyrightText }),
|
|
4544
4879
|
links && links.length > 0 && /* @__PURE__ */ jsx26("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsx26("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
|
|
4545
4880
|
] }) });
|
|
@@ -4567,7 +4902,7 @@ function PublicPageLayout({
|
|
|
4567
4902
|
if (LoadingFallback) {
|
|
4568
4903
|
return /* @__PURE__ */ jsx26(LoadingFallback, {});
|
|
4569
4904
|
}
|
|
4570
|
-
return /* @__PURE__ */ jsx26("div", { className: "min-h-screen bg-background flex items-center justify-center", children: /* @__PURE__ */
|
|
4905
|
+
return /* @__PURE__ */ jsx26("div", { className: "min-h-screen bg-background flex items-center justify-center", children: /* @__PURE__ */ jsxs20("div", { className: "max-w-md mx-auto text-center px-4", children: [
|
|
4571
4906
|
/* @__PURE__ */ jsx26(LoadingSpinner, { size: "lg", className: "mx-auto mb-4" }),
|
|
4572
4907
|
loadingMessage && /* @__PURE__ */ jsx26("p", { className: "text-sec-600", children: loadingMessage })
|
|
4573
4908
|
] }) });
|
|
@@ -4576,9 +4911,9 @@ function PublicPageLayout({
|
|
|
4576
4911
|
if (ErrorFallback) {
|
|
4577
4912
|
return /* @__PURE__ */ jsx26(ErrorFallback, { error, retry: handleRefetch });
|
|
4578
4913
|
}
|
|
4579
|
-
return /* @__PURE__ */
|
|
4914
|
+
return /* @__PURE__ */ jsxs20("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
|
|
4580
4915
|
/* @__PURE__ */ jsx26("h1", { children: "Event Not Found" }),
|
|
4581
|
-
/* @__PURE__ */
|
|
4916
|
+
/* @__PURE__ */ jsxs20("p", { children: [
|
|
4582
4917
|
'The event code "',
|
|
4583
4918
|
eventCode,
|
|
4584
4919
|
'" is invalid or the event is not available for public viewing.'
|
|
@@ -4587,13 +4922,13 @@ function PublicPageLayout({
|
|
|
4587
4922
|
] });
|
|
4588
4923
|
}
|
|
4589
4924
|
if (!event && showValidationErrors) {
|
|
4590
|
-
return /* @__PURE__ */
|
|
4925
|
+
return /* @__PURE__ */ jsxs20("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
|
|
4591
4926
|
/* @__PURE__ */ jsx26("h1", { children: "Event Not Available" }),
|
|
4592
4927
|
/* @__PURE__ */ jsx26("p", { children: "This event is not available for public viewing." }),
|
|
4593
4928
|
handleRefetch && /* @__PURE__ */ jsx26(Button, { onClick: handleRefetch, children: "Try Again" })
|
|
4594
4929
|
] });
|
|
4595
4930
|
}
|
|
4596
|
-
return /* @__PURE__ */ jsx26(ErrorBoundary, { componentName: "PublicPageLayout", children: /* @__PURE__ */
|
|
4931
|
+
return /* @__PURE__ */ jsx26(ErrorBoundary, { componentName: "PublicPageLayout", children: /* @__PURE__ */ jsxs20(Fragment9, { children: [
|
|
4597
4932
|
customHeader || /* @__PURE__ */ jsx26(
|
|
4598
4933
|
PublicPageHeader,
|
|
4599
4934
|
{
|
|
@@ -4658,4 +4993,4 @@ export {
|
|
|
4658
4993
|
PublicPageFooter,
|
|
4659
4994
|
PublicPageLayout
|
|
4660
4995
|
};
|
|
4661
|
-
//# sourceMappingURL=chunk-
|
|
4996
|
+
//# sourceMappingURL=chunk-VKB2CO4Z.js.map
|