@jmruthers/pace-core 0.6.2 → 0.6.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +45 -0
- package/cursor-rules/00-pace-core-compliance.mdc +34 -2
- package/dist/{AuthService-BPvc3Ka0.d.ts → AuthService-Cb34EQs3.d.ts} +9 -1
- package/dist/{DataTable-TPTKCX4D.js → DataTable-THFPBKTP.js} +9 -8
- package/dist/{PublicPageProvider-DC6kCaqf.d.ts → PublicPageProvider-DEMpysFR.d.ts} +45 -67
- package/dist/{UnifiedAuthProvider-CVcTjx-d.d.ts → UnifiedAuthProvider-CKvHP1MK.d.ts} +1 -8
- package/dist/{UnifiedAuthProvider-CH6Z342H.js → UnifiedAuthProvider-KAGUYQ4J.js} +5 -4
- package/dist/{api-MVVQZLJI.js → api-IAGWF3ZG.js} +10 -10
- package/dist/{audit-B5P6FFIR.js → audit-V53FV5AG.js} +2 -2
- package/dist/{chunk-SFZUDBL5.js → chunk-2T2IG7T7.js} +70 -56
- package/dist/chunk-2T2IG7T7.js.map +1 -0
- package/dist/{chunk-MMZ7JXPU.js → chunk-6Z7LTB3D.js} +13 -21
- package/dist/{chunk-MMZ7JXPU.js.map → chunk-6Z7LTB3D.js.map} +1 -1
- package/dist/{chunk-6J4GEEJR.js → chunk-CNCQDFLN.js} +53 -27
- package/dist/chunk-CNCQDFLN.js.map +1 -0
- package/dist/chunk-DGUM43GV.js +11 -0
- package/dist/{chunk-EHMR7VYL.js → chunk-DWUBLJJM.js} +361 -187
- package/dist/chunk-DWUBLJJM.js.map +1 -0
- package/dist/{chunk-2UOI2FG5.js → chunk-HFZBI76P.js} +4 -4
- package/dist/{chunk-F2IMUDXZ.js → chunk-M7MPQISP.js} +2 -2
- package/dist/{chunk-3XC4CPTD.js → chunk-PQBSKX33.js} +244 -5727
- package/dist/chunk-PQBSKX33.js.map +1 -0
- package/dist/chunk-QRPVRXYT.js +226 -0
- package/dist/chunk-QRPVRXYT.js.map +1 -0
- package/dist/{chunk-24UVZUZG.js → chunk-RWEBCB47.js} +129 -387
- package/dist/chunk-RWEBCB47.js.map +1 -0
- package/dist/{chunk-XWQCNGTQ.js → chunk-YDQHOZNA.js} +173 -79
- package/dist/chunk-YDQHOZNA.js.map +1 -0
- package/dist/{chunk-NECFR5MM.js → chunk-ZNIWI3UC.js} +562 -644
- package/dist/chunk-ZNIWI3UC.js.map +1 -0
- package/dist/components.d.ts +2 -2
- package/dist/components.js +12 -13
- package/dist/contextValidator-3JNZKUTX.js +9 -0
- package/dist/contextValidator-3JNZKUTX.js.map +1 -0
- package/dist/eslint-rules/pace-core-compliance.cjs +106 -0
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +7 -6
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +7 -7
- package/dist/index.js +21 -16
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +3 -3
- package/dist/providers.js +4 -3
- package/dist/rbac/index.d.ts +67 -27
- package/dist/rbac/index.js +15 -8
- package/dist/styles/index.js +1 -1
- package/dist/theming/runtime.js +1 -1
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-1oMokgLF.d.ts → usePublicRouteParams-i3qtoBgg.d.ts} +7 -16
- package/dist/utils.js +5 -7
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +14 -16
- package/docs/api/modules.md +3796 -2513
- package/docs/components/context-selector.md +126 -0
- package/docs/migration/RBAC_SCOPE_MIGRATION.md +385 -0
- package/docs/pace-mint-fix-auto-selection.md +218 -0
- package/docs/pace-mint-rbac-setup.md +391 -0
- package/docs/rbac/secure-client-protection.md +330 -0
- package/package.json +3 -3
- package/scripts/audit/core/checks/compliance.cjs +72 -0
- package/scripts/audit/core/checks/dependencies.cjs +559 -28
- package/scripts/audit/core/checks/documentation.cjs +68 -3
- package/scripts/audit/core/checks/environment.cjs +2 -14
- package/scripts/audit/core/checks/error-handling.cjs +47 -6
- package/src/components/ContextSelector/ContextSelector.tsx +384 -0
- package/src/components/ContextSelector/index.ts +3 -0
- package/src/components/DataTable/components/RowComponent.tsx +19 -19
- package/src/components/DataTable/components/UnifiedTableBody.tsx +2 -2
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +8 -6
- package/src/components/Dialog/Dialog.tsx +29 -1
- package/src/components/FileDisplay/FileDisplay.tsx +42 -10
- package/src/components/Header/Header.test.tsx +43 -73
- package/src/components/Header/Header.tsx +44 -45
- package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +10 -19
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +2 -2
- package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +5 -5
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +9 -9
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +135 -33
- package/src/components/PaceAppLayout/README.md +14 -17
- package/src/components/PaceAppLayout/test-setup.tsx +2 -2
- package/src/components/index.ts +5 -5
- package/src/eslint-rules/pace-core-compliance.cjs +106 -0
- package/src/hooks/__tests__/useAppConfig.unit.test.ts +4 -98
- package/src/hooks/useAppConfig.ts +15 -30
- package/src/hooks/useFileDisplay.ts +77 -50
- package/src/index.ts +4 -5
- package/src/providers/services/AuthServiceProvider.tsx +17 -7
- package/src/providers/services/EventServiceProvider.tsx +33 -5
- package/src/providers/services/UnifiedAuthProvider.tsx +90 -134
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +1 -1
- package/src/rbac/adapters.tsx +2 -2
- package/src/rbac/api.test.ts +59 -51
- package/src/rbac/api.ts +178 -132
- package/src/rbac/components/PagePermissionGuard.tsx +38 -10
- package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +32 -21
- package/src/rbac/hooks/permissions/useAccessLevel.ts +1 -1
- package/src/rbac/hooks/permissions/useCan.ts +41 -11
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +1 -1
- package/src/rbac/hooks/permissions/useHasAnyPermission.ts +1 -1
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +1 -1
- package/src/rbac/hooks/useCan.test.ts +0 -9
- package/src/rbac/hooks/useRBAC.test.ts +1 -5
- package/src/rbac/hooks/useRBAC.ts +36 -37
- package/src/rbac/hooks/useResolvedScope.test.ts +120 -35
- package/src/rbac/hooks/useResolvedScope.ts +35 -40
- package/src/rbac/hooks/useSecureSupabase.ts +7 -7
- package/src/rbac/index.ts +7 -0
- package/src/rbac/secureClient.test.ts +22 -18
- package/src/rbac/secureClient.ts +103 -16
- package/src/rbac/security.ts +0 -17
- package/src/rbac/types.ts +1 -0
- package/src/rbac/utils/__tests__/contextValidator.test.ts +64 -86
- package/src/rbac/utils/clientSecurity.ts +93 -0
- package/src/rbac/utils/contextValidator.ts +77 -168
- package/src/services/AuthService.ts +39 -7
- package/src/services/EventService.ts +186 -54
- package/src/services/OrganisationService.ts +81 -14
- package/src/services/__tests__/EventService.test.ts +1 -2
- package/src/services/base/BaseService.ts +3 -0
- package/src/utils/dynamic/dynamicUtils.ts +7 -4
- package/dist/chunk-24UVZUZG.js.map +0 -1
- package/dist/chunk-3XC4CPTD.js.map +0 -1
- package/dist/chunk-6J4GEEJR.js.map +0 -1
- package/dist/chunk-7D4SUZUM.js +0 -38
- package/dist/chunk-EHMR7VYL.js.map +0 -1
- package/dist/chunk-NECFR5MM.js.map +0 -1
- package/dist/chunk-SFZUDBL5.js.map +0 -1
- package/dist/chunk-XWQCNGTQ.js.map +0 -1
- package/docs/api/classes/ColumnFactory.md +0 -243
- package/docs/api/classes/InvalidScopeError.md +0 -73
- package/docs/api/classes/Logger.md +0 -178
- package/docs/api/classes/MissingUserContextError.md +0 -66
- package/docs/api/classes/OrganisationContextRequiredError.md +0 -66
- package/docs/api/classes/PermissionDeniedError.md +0 -73
- package/docs/api/classes/RBACAuditManager.md +0 -297
- package/docs/api/classes/RBACCache.md +0 -322
- package/docs/api/classes/RBACEngine.md +0 -171
- package/docs/api/classes/RBACError.md +0 -76
- package/docs/api/classes/RBACNotInitializedError.md +0 -66
- package/docs/api/classes/SecureSupabaseClient.md +0 -163
- package/docs/api/classes/StorageUtils.md +0 -328
- package/docs/api/enums/FileCategory.md +0 -184
- package/docs/api/enums/LogLevel.md +0 -54
- package/docs/api/enums/RBACErrorCode.md +0 -228
- package/docs/api/enums/RPCFunction.md +0 -118
- package/docs/api/interfaces/AddressFieldProps.md +0 -241
- package/docs/api/interfaces/AddressFieldRef.md +0 -94
- package/docs/api/interfaces/AggregateConfig.md +0 -43
- package/docs/api/interfaces/AutocompleteOptions.md +0 -75
- package/docs/api/interfaces/AvatarProps.md +0 -128
- package/docs/api/interfaces/BadgeProps.md +0 -34
- package/docs/api/interfaces/ButtonProps.md +0 -56
- package/docs/api/interfaces/CalendarProps.md +0 -73
- package/docs/api/interfaces/CardProps.md +0 -69
- package/docs/api/interfaces/ColorPalette.md +0 -7
- package/docs/api/interfaces/ColorShade.md +0 -66
- package/docs/api/interfaces/ComplianceResult.md +0 -30
- package/docs/api/interfaces/DataAccessRecord.md +0 -96
- package/docs/api/interfaces/DataRecord.md +0 -11
- package/docs/api/interfaces/DataTableAction.md +0 -252
- package/docs/api/interfaces/DataTableColumn.md +0 -504
- package/docs/api/interfaces/DataTableProps.md +0 -625
- package/docs/api/interfaces/DataTableToolbarButton.md +0 -96
- package/docs/api/interfaces/DatabaseComplianceResult.md +0 -85
- package/docs/api/interfaces/DatabaseIssue.md +0 -41
- package/docs/api/interfaces/EmptyStateConfig.md +0 -61
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +0 -235
- package/docs/api/interfaces/ErrorBoundaryProps.md +0 -147
- package/docs/api/interfaces/ErrorBoundaryProviderProps.md +0 -36
- package/docs/api/interfaces/ErrorBoundaryState.md +0 -75
- package/docs/api/interfaces/EventAppRoleData.md +0 -71
- package/docs/api/interfaces/ExportColumn.md +0 -90
- package/docs/api/interfaces/ExportOptions.md +0 -126
- package/docs/api/interfaces/FileDisplayProps.md +0 -249
- package/docs/api/interfaces/FileMetadata.md +0 -129
- package/docs/api/interfaces/FileReference.md +0 -118
- package/docs/api/interfaces/FileSizeLimits.md +0 -7
- package/docs/api/interfaces/FileUploadOptions.md +0 -139
- package/docs/api/interfaces/FileUploadProps.md +0 -296
- package/docs/api/interfaces/FooterProps.md +0 -107
- package/docs/api/interfaces/FormFieldProps.md +0 -166
- package/docs/api/interfaces/FormProps.md +0 -113
- package/docs/api/interfaces/GrantEventAppRoleParams.md +0 -122
- package/docs/api/interfaces/InactivityWarningModalProps.md +0 -115
- package/docs/api/interfaces/InputProps.md +0 -56
- package/docs/api/interfaces/LabelProps.md +0 -107
- package/docs/api/interfaces/LoggerConfig.md +0 -62
- package/docs/api/interfaces/LoginFormProps.md +0 -187
- package/docs/api/interfaces/NavigationAccessRecord.md +0 -107
- package/docs/api/interfaces/NavigationContextType.md +0 -164
- package/docs/api/interfaces/NavigationGuardProps.md +0 -139
- package/docs/api/interfaces/NavigationItem.md +0 -120
- package/docs/api/interfaces/NavigationMenuProps.md +0 -221
- package/docs/api/interfaces/NavigationProviderProps.md +0 -117
- package/docs/api/interfaces/Organisation.md +0 -140
- package/docs/api/interfaces/OrganisationContextType.md +0 -388
- package/docs/api/interfaces/OrganisationMembership.md +0 -140
- package/docs/api/interfaces/OrganisationProviderProps.md +0 -76
- package/docs/api/interfaces/OrganisationSecurityError.md +0 -62
- package/docs/api/interfaces/PaceAppLayoutProps.md +0 -409
- package/docs/api/interfaces/PaceLoginPageProps.md +0 -49
- package/docs/api/interfaces/PageAccessRecord.md +0 -85
- package/docs/api/interfaces/PagePermissionContextType.md +0 -140
- package/docs/api/interfaces/PagePermissionGuardProps.md +0 -153
- package/docs/api/interfaces/PagePermissionProviderProps.md +0 -119
- package/docs/api/interfaces/PaletteData.md +0 -41
- package/docs/api/interfaces/ParsedAddress.md +0 -120
- package/docs/api/interfaces/PermissionEnforcerProps.md +0 -153
- package/docs/api/interfaces/ProgressProps.md +0 -42
- package/docs/api/interfaces/ProtectedRouteProps.md +0 -78
- package/docs/api/interfaces/PublicPageFooterProps.md +0 -112
- package/docs/api/interfaces/PublicPageHeaderProps.md +0 -125
- package/docs/api/interfaces/PublicPageLayoutProps.md +0 -185
- package/docs/api/interfaces/QuickFix.md +0 -52
- package/docs/api/interfaces/RBACAccessValidateParams.md +0 -52
- package/docs/api/interfaces/RBACAccessValidateResult.md +0 -41
- package/docs/api/interfaces/RBACAuditLogParams.md +0 -85
- package/docs/api/interfaces/RBACAuditLogResult.md +0 -52
- package/docs/api/interfaces/RBACConfig.md +0 -133
- package/docs/api/interfaces/RBACContext.md +0 -52
- package/docs/api/interfaces/RBACLogger.md +0 -112
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +0 -74
- package/docs/api/interfaces/RBACPerformanceMetrics.md +0 -138
- package/docs/api/interfaces/RBACPermissionCheckParams.md +0 -74
- package/docs/api/interfaces/RBACPermissionCheckResult.md +0 -52
- package/docs/api/interfaces/RBACPermissionsGetParams.md +0 -63
- package/docs/api/interfaces/RBACPermissionsGetResult.md +0 -63
- package/docs/api/interfaces/RBACResult.md +0 -58
- package/docs/api/interfaces/RBACRoleGrantParams.md +0 -63
- package/docs/api/interfaces/RBACRoleGrantResult.md +0 -52
- package/docs/api/interfaces/RBACRoleRevokeParams.md +0 -63
- package/docs/api/interfaces/RBACRoleRevokeResult.md +0 -52
- package/docs/api/interfaces/RBACRoleValidateParams.md +0 -52
- package/docs/api/interfaces/RBACRoleValidateResult.md +0 -63
- package/docs/api/interfaces/RBACRolesListParams.md +0 -52
- package/docs/api/interfaces/RBACRolesListResult.md +0 -74
- package/docs/api/interfaces/RBACSessionTrackParams.md +0 -74
- package/docs/api/interfaces/RBACSessionTrackResult.md +0 -52
- package/docs/api/interfaces/ResourcePermissions.md +0 -155
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +0 -100
- package/docs/api/interfaces/RoleBasedRouterContextType.md +0 -151
- package/docs/api/interfaces/RoleBasedRouterProps.md +0 -156
- package/docs/api/interfaces/RoleManagementResult.md +0 -52
- package/docs/api/interfaces/RouteAccessRecord.md +0 -107
- package/docs/api/interfaces/RouteConfig.md +0 -134
- package/docs/api/interfaces/RuntimeComplianceResult.md +0 -55
- package/docs/api/interfaces/SecureDataContextType.md +0 -168
- package/docs/api/interfaces/SecureDataProviderProps.md +0 -132
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +0 -34
- package/docs/api/interfaces/SetupIssue.md +0 -41
- package/docs/api/interfaces/StorageConfig.md +0 -41
- package/docs/api/interfaces/StorageFileInfo.md +0 -74
- package/docs/api/interfaces/StorageFileMetadata.md +0 -151
- package/docs/api/interfaces/StorageListOptions.md +0 -99
- package/docs/api/interfaces/StorageListResult.md +0 -41
- package/docs/api/interfaces/StorageUploadOptions.md +0 -101
- package/docs/api/interfaces/StorageUploadResult.md +0 -63
- package/docs/api/interfaces/StorageUrlOptions.md +0 -60
- package/docs/api/interfaces/StyleImport.md +0 -19
- package/docs/api/interfaces/SwitchProps.md +0 -34
- package/docs/api/interfaces/TabsContentProps.md +0 -9
- package/docs/api/interfaces/TabsListProps.md +0 -9
- package/docs/api/interfaces/TabsProps.md +0 -9
- package/docs/api/interfaces/TabsTriggerProps.md +0 -50
- package/docs/api/interfaces/TextareaProps.md +0 -53
- package/docs/api/interfaces/ToastActionElement.md +0 -12
- package/docs/api/interfaces/ToastProps.md +0 -9
- package/docs/api/interfaces/UnifiedAuthContextType.md +0 -823
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +0 -173
- package/docs/api/interfaces/UseFormDialogOptions.md +0 -62
- package/docs/api/interfaces/UseFormDialogReturn.md +0 -117
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +0 -138
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +0 -123
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -84
- package/docs/api/interfaces/UsePublicEventOptions.md +0 -34
- package/docs/api/interfaces/UsePublicEventReturn.md +0 -71
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +0 -47
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +0 -123
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +0 -97
- package/docs/api/interfaces/UseResolvedScopeOptions.md +0 -47
- package/docs/api/interfaces/UseResolvedScopeReturn.md +0 -47
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +0 -34
- package/docs/api/interfaces/UserEventAccess.md +0 -121
- package/docs/api/interfaces/UserMenuProps.md +0 -88
- package/docs/api/interfaces/UserProfile.md +0 -63
- package/src/components/EventSelector/EventSelector.test.tsx +0 -720
- package/src/components/EventSelector/EventSelector.tsx +0 -423
- package/src/components/EventSelector/index.ts +0 -3
- package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +0 -784
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -327
- package/src/components/OrganisationSelector/index.ts +0 -9
- /package/dist/{DataTable-TPTKCX4D.js.map → DataTable-THFPBKTP.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-CH6Z342H.js.map → UnifiedAuthProvider-KAGUYQ4J.js.map} +0 -0
- /package/dist/{api-MVVQZLJI.js.map → api-IAGWF3ZG.js.map} +0 -0
- /package/dist/{audit-B5P6FFIR.js.map → audit-V53FV5AG.js.map} +0 -0
- /package/dist/{chunk-7D4SUZUM.js.map → chunk-DGUM43GV.js.map} +0 -0
- /package/dist/{chunk-2UOI2FG5.js.map → chunk-HFZBI76P.js.map} +0 -0
- /package/dist/{chunk-F2IMUDXZ.js.map → chunk-M7MPQISP.js.map} +0 -0
|
@@ -20,18 +20,19 @@ import {
|
|
|
20
20
|
Input,
|
|
21
21
|
Select,
|
|
22
22
|
SelectContent,
|
|
23
|
+
SelectGroup,
|
|
23
24
|
SelectItem,
|
|
24
25
|
SelectLabel,
|
|
25
26
|
SelectSeparator,
|
|
26
27
|
SelectTrigger,
|
|
27
28
|
SelectValue
|
|
28
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-PQBSKX33.js";
|
|
29
30
|
import {
|
|
30
31
|
useCan,
|
|
31
32
|
usePermissions,
|
|
32
33
|
useRBAC,
|
|
33
34
|
useResolvedScope
|
|
34
|
-
} from "./chunk-
|
|
35
|
+
} from "./chunk-YDQHOZNA.js";
|
|
35
36
|
import {
|
|
36
37
|
createFileReferenceService,
|
|
37
38
|
generateFileUrlsBatch,
|
|
@@ -43,7 +44,7 @@ import {
|
|
|
43
44
|
useFileDisplay,
|
|
44
45
|
usePreventTabReload,
|
|
45
46
|
usePublicFileDisplay
|
|
46
|
-
} from "./chunk-
|
|
47
|
+
} from "./chunk-2T2IG7T7.js";
|
|
47
48
|
import {
|
|
48
49
|
useToast
|
|
49
50
|
} from "./chunk-6SOIHG6Z.js";
|
|
@@ -53,16 +54,16 @@ import {
|
|
|
53
54
|
useAppConfig,
|
|
54
55
|
useEvents,
|
|
55
56
|
useIsPublicPage
|
|
56
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-6Z7LTB3D.js";
|
|
57
58
|
import {
|
|
58
59
|
EventServiceContext,
|
|
59
60
|
useOrganisations,
|
|
60
61
|
useSessionRestoration,
|
|
61
62
|
useUnifiedAuth
|
|
62
|
-
} from "./chunk-
|
|
63
|
+
} from "./chunk-DWUBLJJM.js";
|
|
63
64
|
import {
|
|
64
65
|
isSuperAdmin
|
|
65
|
-
} from "./chunk-
|
|
66
|
+
} from "./chunk-RWEBCB47.js";
|
|
66
67
|
import {
|
|
67
68
|
assertAppId
|
|
68
69
|
} from "./chunk-QXHPKYJV.js";
|
|
@@ -75,7 +76,7 @@ import {
|
|
|
75
76
|
} from "./chunk-M43Y4SSO.js";
|
|
76
77
|
import {
|
|
77
78
|
getCurrentAppName
|
|
78
|
-
} from "./chunk-
|
|
79
|
+
} from "./chunk-M7MPQISP.js";
|
|
79
80
|
import {
|
|
80
81
|
clearPalette
|
|
81
82
|
} from "./chunk-L4OXEN46.js";
|
|
@@ -404,7 +405,7 @@ function Textarea({ className, variant = "default", size = "md", error, ref, ...
|
|
|
404
405
|
Textarea.displayName = "Textarea";
|
|
405
406
|
|
|
406
407
|
// src/components/FileDisplay/FileDisplay.tsx
|
|
407
|
-
import { useState as useState3, useEffect as useEffect3, useRef as useRef3, useContext, useMemo } from "react";
|
|
408
|
+
import React3, { useState as useState3, useEffect as useEffect3, useCallback as useCallback3, useRef as useRef3, useContext, useMemo } from "react";
|
|
408
409
|
import { FileText, ExternalLink } from "lucide-react";
|
|
409
410
|
|
|
410
411
|
// src/hooks/useFileUrl.ts
|
|
@@ -506,7 +507,7 @@ function defaultGenerateFallbackText(fileName) {
|
|
|
506
507
|
if (words.length === 0) return "FL";
|
|
507
508
|
return words.map((word) => word.charAt(0).toUpperCase()).join("").substring(0, 3);
|
|
508
509
|
}
|
|
509
|
-
|
|
510
|
+
var FileDisplayContent = React3.memo(function FileDisplayContent2({
|
|
510
511
|
isLoading,
|
|
511
512
|
error,
|
|
512
513
|
fileUrl,
|
|
@@ -537,6 +538,22 @@ function FileDisplayContent({
|
|
|
537
538
|
const [internalFileUrls, setInternalFileUrls] = useState3(new Map(fileUrls));
|
|
538
539
|
const [deleteDialogOpen, setDeleteDialogOpen] = useState3(false);
|
|
539
540
|
const fileReferencesRef = useRef3([]);
|
|
541
|
+
const imgRef = useRef3(null);
|
|
542
|
+
const currentSrcRef = useRef3(null);
|
|
543
|
+
const isImageLoadingRef = useRef3(false);
|
|
544
|
+
const stableFileUrl = useMemo(() => fileUrl, [fileUrl]);
|
|
545
|
+
const handleImageLoadStart = useCallback3(() => {
|
|
546
|
+
isImageLoadingRef.current = true;
|
|
547
|
+
if (stableFileUrl) {
|
|
548
|
+
currentSrcRef.current = stableFileUrl;
|
|
549
|
+
}
|
|
550
|
+
}, [stableFileUrl]);
|
|
551
|
+
const handleImageLoad = useCallback3(() => {
|
|
552
|
+
isImageLoadingRef.current = false;
|
|
553
|
+
if (stableFileUrl) {
|
|
554
|
+
currentSrcRef.current = stableFileUrl;
|
|
555
|
+
}
|
|
556
|
+
}, [stableFileUrl]);
|
|
540
557
|
const computedFallbackText = useMemo(() => {
|
|
541
558
|
if (fallbackText) return fallbackText;
|
|
542
559
|
const sourceText = fallbackSourceText ?? fileReference?.file_metadata?.fileName;
|
|
@@ -642,27 +659,32 @@ function FileDisplayContent({
|
|
|
642
659
|
if (imageError && showFallback) {
|
|
643
660
|
return /* @__PURE__ */ jsx4("figure", { className, title: fileReference.file_metadata.fileName || "File", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: computedFallbackText }) });
|
|
644
661
|
}
|
|
645
|
-
if (!
|
|
662
|
+
if (!stableFileUrl) {
|
|
646
663
|
return /* @__PURE__ */ jsx4("figure", { className: className || "max-w-full h-48", title: "Loading", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: /* @__PURE__ */ jsx4(LoadingSpinner, {}) }) });
|
|
647
664
|
}
|
|
648
665
|
return /* @__PURE__ */ jsx4("figure", { className: className || "", children: /* @__PURE__ */ jsx4(
|
|
649
666
|
"img",
|
|
650
667
|
{
|
|
651
|
-
|
|
668
|
+
ref: imgRef,
|
|
669
|
+
src: stableFileUrl || void 0,
|
|
652
670
|
alt: fileReference.file_metadata.fileName || "File",
|
|
653
671
|
className: imgClassName || "object-cover size-full",
|
|
654
|
-
onError: handleImageError
|
|
655
|
-
|
|
672
|
+
onError: handleImageError,
|
|
673
|
+
onLoadStart: handleImageLoadStart,
|
|
674
|
+
onLoad: handleImageLoad,
|
|
675
|
+
loading: "lazy"
|
|
676
|
+
},
|
|
677
|
+
fileReference.id
|
|
656
678
|
) });
|
|
657
679
|
}
|
|
658
|
-
if (displayOnly && !isImage &&
|
|
680
|
+
if (displayOnly && !isImage && stableFileUrl && fileReference && !showDelete) {
|
|
659
681
|
const fileName = fileReference.file_metadata?.fileName || "Document";
|
|
660
682
|
const ariaLabel = `Open ${fileName} in new tab`;
|
|
661
683
|
return /* @__PURE__ */ jsxs3("figure", { className, children: [
|
|
662
684
|
/* @__PURE__ */ jsxs3(
|
|
663
685
|
"a",
|
|
664
686
|
{
|
|
665
|
-
href:
|
|
687
|
+
href: stableFileUrl || void 0,
|
|
666
688
|
target: "_blank",
|
|
667
689
|
rel: "noopener noreferrer",
|
|
668
690
|
"aria-label": ariaLabel,
|
|
@@ -684,18 +706,20 @@ function FileDisplayContent({
|
|
|
684
706
|
] })
|
|
685
707
|
] });
|
|
686
708
|
}
|
|
687
|
-
if (displayOnly && showFallback && (!
|
|
709
|
+
if (displayOnly && showFallback && (!stableFileUrl || imageError || !isImage)) {
|
|
688
710
|
return /* @__PURE__ */ jsx4("figure", { className, title: fileReference.file_metadata.fileName || "File", children: /* @__PURE__ */ jsx4("p", { className: fallbackClasses, children: computedFallbackText }) });
|
|
689
711
|
}
|
|
690
|
-
return /* @__PURE__ */ jsx4("figure", { className: `relative ${className}`, children: isImage &&
|
|
712
|
+
return /* @__PURE__ */ jsx4("figure", { className: `relative ${className}`, children: isImage && stableFileUrl && !imageError ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
691
713
|
/* @__PURE__ */ jsx4(
|
|
692
714
|
"img",
|
|
693
715
|
{
|
|
694
|
-
src:
|
|
716
|
+
src: stableFileUrl,
|
|
695
717
|
alt: fileReference.file_metadata.fileName || "File",
|
|
696
718
|
className: imgClassName || "object-cover size-full",
|
|
697
|
-
onError: handleImageError
|
|
698
|
-
|
|
719
|
+
onError: handleImageError,
|
|
720
|
+
loading: "lazy"
|
|
721
|
+
},
|
|
722
|
+
fileReference.id
|
|
699
723
|
),
|
|
700
724
|
showDelete && /* @__PURE__ */ jsxs3(Fragment3, { children: [
|
|
701
725
|
/* @__PURE__ */ jsx4(
|
|
@@ -788,11 +812,13 @@ function FileDisplayContent({
|
|
|
788
812
|
isImage && fileUrl2 ? /* @__PURE__ */ jsx4(
|
|
789
813
|
"img",
|
|
790
814
|
{
|
|
791
|
-
src: fileUrl2,
|
|
815
|
+
src: fileUrl2 || void 0,
|
|
792
816
|
alt: fileRef.file_metadata.fileName || "File",
|
|
793
817
|
className: imgClassName || "object-cover size-full",
|
|
794
|
-
onError: handleImageError
|
|
795
|
-
|
|
818
|
+
onError: handleImageError,
|
|
819
|
+
loading: "lazy"
|
|
820
|
+
},
|
|
821
|
+
fileRef.id
|
|
796
822
|
) : /* @__PURE__ */ jsx4("span", { className: "text-2xl", children: getFileIcon(fileRef.file_metadata.fileType || "") }),
|
|
797
823
|
showMetadata && /* @__PURE__ */ jsxs3("figcaption", { className: "flex-1 min-w-0", children: [
|
|
798
824
|
/* @__PURE__ */ jsx4("p", { className: "font-medium text-sec-900 truncate", children: fileRef.file_metadata.fileName || "Unknown file" }),
|
|
@@ -831,7 +857,7 @@ function FileDisplayContent({
|
|
|
831
857
|
}),
|
|
832
858
|
children
|
|
833
859
|
] });
|
|
834
|
-
}
|
|
860
|
+
});
|
|
835
861
|
function FileDisplayPublic({
|
|
836
862
|
table_name,
|
|
837
863
|
record_id,
|
|
@@ -2371,297 +2397,98 @@ var LoginForm = React9.memo(({
|
|
|
2371
2397
|
] }) });
|
|
2372
2398
|
});
|
|
2373
2399
|
|
|
2374
|
-
// src/components/
|
|
2375
|
-
import {
|
|
2376
|
-
import {
|
|
2377
|
-
import { jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2378
|
-
function
|
|
2379
|
-
placeholder = "Select
|
|
2400
|
+
// src/components/ContextSelector/ContextSelector.tsx
|
|
2401
|
+
import { useMemo as useMemo5 } from "react";
|
|
2402
|
+
import { RefreshCw, AlertCircle, Building2, Calendar as Calendar2 } from "lucide-react";
|
|
2403
|
+
import { Fragment as Fragment6, jsx as jsx13, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
2404
|
+
function ContextSelector({
|
|
2405
|
+
placeholder = "Select organisation or event",
|
|
2380
2406
|
className,
|
|
2381
|
-
|
|
2382
|
-
|
|
2407
|
+
onOrganisationSelect,
|
|
2408
|
+
onEventSelect,
|
|
2409
|
+
showNoItemsMessage = true,
|
|
2383
2410
|
showRetryButton = true,
|
|
2384
|
-
|
|
2385
|
-
|
|
2411
|
+
compact = false,
|
|
2412
|
+
disabled = false,
|
|
2413
|
+
showOrganisations = true,
|
|
2414
|
+
showEvents = true
|
|
2386
2415
|
}) {
|
|
2416
|
+
const {
|
|
2417
|
+
organisations,
|
|
2418
|
+
selectedOrganisation,
|
|
2419
|
+
isLoading: orgLoading,
|
|
2420
|
+
error: orgError,
|
|
2421
|
+
refreshOrganisations
|
|
2422
|
+
} = useOrganisations();
|
|
2387
2423
|
const {
|
|
2388
2424
|
events,
|
|
2389
2425
|
selectedEvent,
|
|
2390
|
-
isLoading,
|
|
2391
|
-
error,
|
|
2392
|
-
setSelectedEvent,
|
|
2426
|
+
isLoading: eventLoading,
|
|
2427
|
+
error: eventError,
|
|
2393
2428
|
refreshEvents
|
|
2394
2429
|
} = useEvents();
|
|
2395
|
-
const
|
|
2396
|
-
|
|
2397
|
-
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
}
|
|
2430
|
+
const { isSuperAdmin: isSuperAdmin2 } = useRBAC();
|
|
2431
|
+
const isLoading = showOrganisations && orgLoading || showEvents && eventLoading;
|
|
2432
|
+
const hasError = showOrganisations && orgError || showEvents && eventError;
|
|
2433
|
+
const hasItems = showOrganisations && (organisations?.length || 0) > 0 || showEvents && (events?.length || 0) > 0;
|
|
2434
|
+
const currentValue = useMemo5(() => {
|
|
2435
|
+
if (showEvents && selectedEvent) {
|
|
2436
|
+
return `event:${selectedEvent.event_id || selectedEvent.id}`;
|
|
2402
2437
|
}
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
refreshEvents();
|
|
2406
|
-
};
|
|
2407
|
-
const isNextEvent = (event) => {
|
|
2408
|
-
if (!event.event_date) return false;
|
|
2409
|
-
const now = /* @__PURE__ */ new Date();
|
|
2410
|
-
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
2411
|
-
const eventDate = new Date(event.event_date);
|
|
2412
|
-
return eventDate >= today;
|
|
2413
|
-
};
|
|
2414
|
-
const formatEventDate = (dateString) => {
|
|
2415
|
-
const date = new Date(dateString);
|
|
2416
|
-
const today = /* @__PURE__ */ new Date();
|
|
2417
|
-
const tomorrow = new Date(today);
|
|
2418
|
-
tomorrow.setDate(tomorrow.getDate() + 1);
|
|
2419
|
-
const normalizeDate = (d) => {
|
|
2420
|
-
const normalized = new Date(d);
|
|
2421
|
-
normalized.setHours(0, 0, 0, 0);
|
|
2422
|
-
return normalized;
|
|
2423
|
-
};
|
|
2424
|
-
const normalizedDate = normalizeDate(date);
|
|
2425
|
-
const normalizedToday = normalizeDate(today);
|
|
2426
|
-
const normalizedTomorrow = normalizeDate(tomorrow);
|
|
2427
|
-
if (normalizedDate.getTime() === normalizedToday.getTime()) {
|
|
2428
|
-
return "Today";
|
|
2429
|
-
} else if (normalizedDate.getTime() === normalizedTomorrow.getTime()) {
|
|
2430
|
-
return "Tomorrow";
|
|
2431
|
-
} else {
|
|
2432
|
-
return date.toLocaleDateString();
|
|
2438
|
+
if (showOrganisations && selectedOrganisation) {
|
|
2439
|
+
return `org:${selectedOrganisation.id}`;
|
|
2433
2440
|
}
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
|
|
2442
|
-
|
|
2443
|
-
const eventsLengthChanged = events.length !== prevEventsLengthRef.current;
|
|
2444
|
-
const selectedEventChanged = selectedEvent?.event_id !== prevSelectedEventIdRef.current;
|
|
2445
|
-
if (eventsLengthChanged) {
|
|
2446
|
-
prevEventsLengthRef.current = events.length;
|
|
2447
|
-
if (events.length > 0) {
|
|
2448
|
-
hasAutoSelectedRef.current = false;
|
|
2441
|
+
return "";
|
|
2442
|
+
}, [showOrganisations, showEvents, selectedOrganisation?.id, selectedEvent]);
|
|
2443
|
+
const handleValueChange = (value) => {
|
|
2444
|
+
if (disabled || isLoading) return;
|
|
2445
|
+
if (value.startsWith("org:") && showOrganisations) {
|
|
2446
|
+
const orgId = value.replace("org:", "");
|
|
2447
|
+
const org = organisations?.find((o) => o.id === orgId);
|
|
2448
|
+
if (org && onOrganisationSelect) {
|
|
2449
|
+
onOrganisationSelect(org);
|
|
2449
2450
|
}
|
|
2450
|
-
}
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
if (
|
|
2454
|
-
|
|
2451
|
+
} else if (value.startsWith("event:") && showEvents) {
|
|
2452
|
+
const eventId = value.replace("event:", "");
|
|
2453
|
+
const event = events?.find((e) => (e.event_id || e.id) === eventId);
|
|
2454
|
+
if (event && onEventSelect) {
|
|
2455
|
+
onEventSelect(event);
|
|
2455
2456
|
}
|
|
2456
2457
|
}
|
|
2457
|
-
|
|
2458
|
-
|
|
2459
|
-
|
|
2460
|
-
|
|
2461
|
-
|
|
2462
|
-
|
|
2463
|
-
|
|
2464
|
-
|
|
2465
|
-
if (next) {
|
|
2466
|
-
setSelectedEvent(next);
|
|
2467
|
-
if (onEventChange) onEventChange(next);
|
|
2468
|
-
} else {
|
|
2469
|
-
const mostRecentPast = [...events].filter((e) => {
|
|
2470
|
-
if (!e.event_date) return false;
|
|
2471
|
-
const eventDate = new Date(e.event_date);
|
|
2472
|
-
const startOfEventDate = new Date(eventDate.getFullYear(), eventDate.getMonth(), eventDate.getDate()).getTime();
|
|
2473
|
-
return startOfEventDate < startOfToday;
|
|
2474
|
-
}).sort((a, b) => new Date(b.event_date).getTime() - new Date(a.event_date).getTime())[0];
|
|
2475
|
-
if (mostRecentPast) {
|
|
2476
|
-
setSelectedEvent(mostRecentPast);
|
|
2477
|
-
if (onEventChange) onEventChange(mostRecentPast);
|
|
2478
|
-
}
|
|
2458
|
+
};
|
|
2459
|
+
const handleRetry = async () => {
|
|
2460
|
+
try {
|
|
2461
|
+
if (showOrganisations && orgError) {
|
|
2462
|
+
await refreshOrganisations();
|
|
2463
|
+
}
|
|
2464
|
+
if (showEvents && eventError) {
|
|
2465
|
+
await refreshEvents();
|
|
2479
2466
|
}
|
|
2467
|
+
} catch (error) {
|
|
2468
|
+
logger.error("ContextSelector", "Failed to refresh:", error);
|
|
2480
2469
|
}
|
|
2481
|
-
}
|
|
2482
|
-
if (isLoading) {
|
|
2470
|
+
};
|
|
2471
|
+
if (isLoading && !hasItems) {
|
|
2472
|
+
const loadingText = compact ? "Loading..." : showOrganisations && showEvents ? "Loading organisations and events..." : showOrganisations ? "Loading organisations..." : "Loading events...";
|
|
2483
2473
|
return /* @__PURE__ */ jsxs8("div", { className: `flex items-center gap-2 ${className}`, children: [
|
|
2484
2474
|
/* @__PURE__ */ jsx13(LoadingSpinner, { size: "sm" }),
|
|
2485
|
-
/* @__PURE__ */ jsx13("span", { className: "text-sm text-muted-foreground", children:
|
|
2475
|
+
/* @__PURE__ */ jsx13("span", { className: "text-sm text-muted-foreground", children: loadingText })
|
|
2486
2476
|
] });
|
|
2487
2477
|
}
|
|
2488
|
-
if (
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2492
|
-
/* @__PURE__ */ jsx13("span", { children: error.message }),
|
|
2493
|
-
showRetryButton && /* @__PURE__ */ jsxs8(
|
|
2494
|
-
Button,
|
|
2495
|
-
{
|
|
2496
|
-
variant: "outline",
|
|
2497
|
-
size: "sm",
|
|
2498
|
-
onClick: handleRetry,
|
|
2499
|
-
className: "ml-2",
|
|
2500
|
-
children: [
|
|
2501
|
-
/* @__PURE__ */ jsx13(RefreshCw, { className: "size-3 mr-1" }),
|
|
2502
|
-
"Retry"
|
|
2503
|
-
]
|
|
2504
|
-
}
|
|
2505
|
-
)
|
|
2506
|
-
] })
|
|
2507
|
-
] }) });
|
|
2508
|
-
}
|
|
2509
|
-
if (events.length === 0) {
|
|
2510
|
-
if (showNoEventsMessage) {
|
|
2511
|
-
return /* @__PURE__ */ jsx13("div", { className, children: /* @__PURE__ */ jsxs8(Alert, { variant: "inline", children: [
|
|
2512
|
-
/* @__PURE__ */ jsx13(AlertCircle, { className: "size-4 text-acc-700" }),
|
|
2513
|
-
/* @__PURE__ */ jsxs8(AlertDescription, { className: "flex items-center justify-between", children: [
|
|
2514
|
-
/* @__PURE__ */ jsx13("span", { children: "No events available." }),
|
|
2515
|
-
showRetryButton && /* @__PURE__ */ jsxs8(
|
|
2516
|
-
Button,
|
|
2517
|
-
{
|
|
2518
|
-
variant: "outline",
|
|
2519
|
-
size: "sm",
|
|
2520
|
-
onClick: handleRetry,
|
|
2521
|
-
className: "ml-2",
|
|
2522
|
-
children: [
|
|
2523
|
-
/* @__PURE__ */ jsx13(RefreshCw, { className: "size-3 mr-1" }),
|
|
2524
|
-
"Refresh"
|
|
2525
|
-
]
|
|
2526
|
-
}
|
|
2527
|
-
)
|
|
2528
|
-
] })
|
|
2529
|
-
] }) });
|
|
2478
|
+
if (hasError) {
|
|
2479
|
+
const errorMessages = [];
|
|
2480
|
+
if (showOrganisations && orgError) {
|
|
2481
|
+
errorMessages.push(`Failed to load organisations: ${orgError.message}`);
|
|
2530
2482
|
}
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
return /* @__PURE__ */ jsxs8(
|
|
2534
|
-
Select,
|
|
2535
|
-
{
|
|
2536
|
-
value: selectedEvent ? selectedEvent.event_id || selectedEvent.id : "",
|
|
2537
|
-
onValueChange: handleValueChange,
|
|
2538
|
-
className,
|
|
2539
|
-
children: [
|
|
2540
|
-
/* @__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: [
|
|
2541
|
-
/* @__PURE__ */ jsx13(Calendar2, { className: "size-4 flex-shrink-0" }),
|
|
2542
|
-
/* @__PURE__ */ jsx13("span", { className: "truncate", children: selectedEvent.event_name }),
|
|
2543
|
-
selectedEvent.event_date && /* @__PURE__ */ jsxs8("span", { className: "text-xs text-muted-foreground flex-shrink-0", children: [
|
|
2544
|
-
"(",
|
|
2545
|
-
formatEventDate(selectedEvent.event_date),
|
|
2546
|
-
")"
|
|
2547
|
-
] })
|
|
2548
|
-
] }) }) }),
|
|
2549
|
-
/* @__PURE__ */ jsx13(SelectContent, { children: sortedEvents.map((event) => {
|
|
2550
|
-
const isNext = isNextEvent(event);
|
|
2551
|
-
const isSelected = selectedEvent && (selectedEvent.event_id === event.event_id || selectedEvent.id === event.id);
|
|
2552
|
-
return /* @__PURE__ */ jsx13(
|
|
2553
|
-
SelectItem,
|
|
2554
|
-
{
|
|
2555
|
-
value: event.event_id || event.id,
|
|
2556
|
-
className: "flex items-center justify-between",
|
|
2557
|
-
children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 w-full", children: [
|
|
2558
|
-
showNextEventIndicator && isNext && /* @__PURE__ */ jsx13(Star, { className: "size-3 text-acc-500" }),
|
|
2559
|
-
/* @__PURE__ */ jsxs8("div", { className: "flex-1", children: [
|
|
2560
|
-
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
2561
|
-
/* @__PURE__ */ jsx13("span", { className: isSelected ? "font-semibold" : "", children: event.event_name }),
|
|
2562
|
-
isSelected && /* @__PURE__ */ jsx13("span", { className: "text-xs bg-primary text-primary-foreground px-1 rounded", children: "Current" })
|
|
2563
|
-
] }),
|
|
2564
|
-
showEventDetails && event.event_date && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1 text-xs text-muted-foreground", children: [
|
|
2565
|
-
/* @__PURE__ */ jsx13(Calendar2, { className: "size-3" }),
|
|
2566
|
-
/* @__PURE__ */ jsx13("span", { children: formatEventDate(event.event_date) }),
|
|
2567
|
-
showNextEventIndicator && isNext && /* @__PURE__ */ jsx13("span", { className: "text-acc-600 font-medium", children: "(Next)" })
|
|
2568
|
-
] }),
|
|
2569
|
-
showEventDetails && event.event_venue && /* @__PURE__ */ jsxs8("div", { className: "text-xs text-muted-foreground", children: [
|
|
2570
|
-
"\u{1F4CD} ",
|
|
2571
|
-
event.event_venue
|
|
2572
|
-
] })
|
|
2573
|
-
] })
|
|
2574
|
-
] })
|
|
2575
|
-
},
|
|
2576
|
-
event.event_id || event.id
|
|
2577
|
-
);
|
|
2578
|
-
}) })
|
|
2579
|
-
]
|
|
2483
|
+
if (showEvents && eventError) {
|
|
2484
|
+
errorMessages.push(`Failed to load events: ${eventError.message}`);
|
|
2580
2485
|
}
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
import { useState as useState8, useCallback as useCallback8, useMemo as useMemo6 } from "react";
|
|
2586
|
-
import { RefreshCw as RefreshCw2, AlertCircle as AlertCircle2, Building2, Shield } from "lucide-react";
|
|
2587
|
-
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2588
|
-
function OrganisationSelector({
|
|
2589
|
-
placeholder = "Select organisation",
|
|
2590
|
-
className,
|
|
2591
|
-
onOrganisationChange,
|
|
2592
|
-
showNoOrganisationsMessage = true,
|
|
2593
|
-
showRetryButton = true,
|
|
2594
|
-
showRole = false,
|
|
2595
|
-
compact = false,
|
|
2596
|
-
disabled = false
|
|
2597
|
-
}) {
|
|
2598
|
-
const [isLoading, setIsLoading] = useState8(false);
|
|
2599
|
-
const [switchError, setSwitchError] = useState8(null);
|
|
2600
|
-
const {
|
|
2601
|
-
organisations,
|
|
2602
|
-
selectedOrganisation,
|
|
2603
|
-
isLoading: orgLoading,
|
|
2604
|
-
error: orgError,
|
|
2605
|
-
switchOrganisation,
|
|
2606
|
-
getUserRole,
|
|
2607
|
-
validateOrganisationAccess,
|
|
2608
|
-
refreshOrganisations
|
|
2609
|
-
} = useOrganisations();
|
|
2610
|
-
const handleOrganisationChange = useCallback8(async (orgId) => {
|
|
2611
|
-
if (disabled || isLoading) return;
|
|
2612
|
-
setSwitchError(null);
|
|
2613
|
-
setIsLoading(true);
|
|
2614
|
-
try {
|
|
2615
|
-
if (!validateOrganisationAccess(orgId)) {
|
|
2616
|
-
throw new Error("You do not have access to this organisation");
|
|
2617
|
-
}
|
|
2618
|
-
await switchOrganisation(orgId);
|
|
2619
|
-
const newOrganisation = organisations.find((org) => org.id === orgId);
|
|
2620
|
-
if (newOrganisation && onOrganisationChange) {
|
|
2621
|
-
onOrganisationChange(newOrganisation);
|
|
2622
|
-
}
|
|
2623
|
-
} catch (error) {
|
|
2624
|
-
logger.error("OrganisationSelector", "Failed to switch organisation:", error);
|
|
2625
|
-
setSwitchError(error instanceof Error ? error.message : "Failed to switch organisation");
|
|
2626
|
-
} finally {
|
|
2627
|
-
setIsLoading(false);
|
|
2628
|
-
}
|
|
2629
|
-
}, [
|
|
2630
|
-
disabled,
|
|
2631
|
-
isLoading,
|
|
2632
|
-
validateOrganisationAccess,
|
|
2633
|
-
switchOrganisation,
|
|
2634
|
-
organisations,
|
|
2635
|
-
onOrganisationChange
|
|
2636
|
-
]);
|
|
2637
|
-
const handleRetry = useCallback8(async () => {
|
|
2638
|
-
setIsLoading(true);
|
|
2639
|
-
setSwitchError(null);
|
|
2640
|
-
try {
|
|
2641
|
-
await refreshOrganisations();
|
|
2642
|
-
} catch (error) {
|
|
2643
|
-
logger.error("OrganisationSelector", "Failed to refresh organisations:", error);
|
|
2644
|
-
setSwitchError("Failed to refresh organisations");
|
|
2645
|
-
} finally {
|
|
2646
|
-
setIsLoading(false);
|
|
2647
|
-
}
|
|
2648
|
-
}, [refreshOrganisations]);
|
|
2649
|
-
if (orgLoading) {
|
|
2650
|
-
return /* @__PURE__ */ jsxs9("div", { className: `flex items-center gap-2 ${className}`, children: [
|
|
2651
|
-
/* @__PURE__ */ jsx14(LoadingSpinner, { size: "sm" }),
|
|
2652
|
-
/* @__PURE__ */ jsx14("span", { className: "text-sm text-muted-foreground", children: compact ? "Loading..." : "Loading organisations..." })
|
|
2653
|
-
] });
|
|
2654
|
-
}
|
|
2655
|
-
if (orgError) {
|
|
2656
|
-
return /* @__PURE__ */ jsxs9("div", { className: `space-y-2 ${className}`, children: [
|
|
2657
|
-
/* @__PURE__ */ jsxs9(Alert, { variant: "destructive", children: [
|
|
2658
|
-
/* @__PURE__ */ jsx14(AlertCircle2, { className: "size-4" }),
|
|
2659
|
-
/* @__PURE__ */ jsxs9(AlertDescription, { children: [
|
|
2660
|
-
"Failed to load organisations: ",
|
|
2661
|
-
orgError.message
|
|
2662
|
-
] })
|
|
2486
|
+
return /* @__PURE__ */ jsxs8("div", { className: `space-y-2 ${className}`, children: [
|
|
2487
|
+
/* @__PURE__ */ jsxs8(Alert, { variant: "destructive", children: [
|
|
2488
|
+
/* @__PURE__ */ jsx13(AlertCircle, { className: "size-4" }),
|
|
2489
|
+
/* @__PURE__ */ jsx13(AlertDescription, { children: errorMessages.join(" ") })
|
|
2663
2490
|
] }),
|
|
2664
|
-
showRetryButton && /* @__PURE__ */
|
|
2491
|
+
showRetryButton && /* @__PURE__ */ jsxs8(
|
|
2665
2492
|
Button,
|
|
2666
2493
|
{
|
|
2667
2494
|
variant: "outline",
|
|
@@ -2670,21 +2497,22 @@ function OrganisationSelector({
|
|
|
2670
2497
|
disabled: isLoading,
|
|
2671
2498
|
className: "w-full",
|
|
2672
2499
|
children: [
|
|
2673
|
-
/* @__PURE__ */
|
|
2500
|
+
/* @__PURE__ */ jsx13(RefreshCw, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
2674
2501
|
"Retry"
|
|
2675
2502
|
]
|
|
2676
2503
|
}
|
|
2677
2504
|
)
|
|
2678
2505
|
] });
|
|
2679
2506
|
}
|
|
2680
|
-
if (
|
|
2681
|
-
if (
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
/* @__PURE__ */
|
|
2507
|
+
if (!hasItems) {
|
|
2508
|
+
if (showNoItemsMessage) {
|
|
2509
|
+
const noItemsText = showOrganisations && showEvents ? "No organisations or events available. Please contact your administrator." : showOrganisations ? "No organisations available. Please contact your administrator." : "No events available. Please contact your administrator.";
|
|
2510
|
+
return /* @__PURE__ */ jsxs8("div", { className: `space-y-2 ${className}`, children: [
|
|
2511
|
+
/* @__PURE__ */ jsxs8(Alert, { children: [
|
|
2512
|
+
/* @__PURE__ */ jsx13(AlertCircle, { className: "size-4" }),
|
|
2513
|
+
/* @__PURE__ */ jsx13(AlertDescription, { children: noItemsText })
|
|
2686
2514
|
] }),
|
|
2687
|
-
showRetryButton && /* @__PURE__ */
|
|
2515
|
+
showRetryButton && /* @__PURE__ */ jsxs8(
|
|
2688
2516
|
Button,
|
|
2689
2517
|
{
|
|
2690
2518
|
variant: "outline",
|
|
@@ -2693,7 +2521,7 @@ function OrganisationSelector({
|
|
|
2693
2521
|
disabled: isLoading,
|
|
2694
2522
|
className: "w-full",
|
|
2695
2523
|
children: [
|
|
2696
|
-
/* @__PURE__ */
|
|
2524
|
+
/* @__PURE__ */ jsx13(RefreshCw, { className: `size-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
2697
2525
|
"Check Again"
|
|
2698
2526
|
]
|
|
2699
2527
|
}
|
|
@@ -2702,74 +2530,103 @@ function OrganisationSelector({
|
|
|
2702
2530
|
}
|
|
2703
2531
|
return null;
|
|
2704
2532
|
}
|
|
2705
|
-
const
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2533
|
+
const displayValue = useMemo5(() => {
|
|
2534
|
+
if (showEvents && selectedEvent) {
|
|
2535
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
2536
|
+
/* @__PURE__ */ jsx13(Calendar2, { className: "size-4 flex-shrink-0" }),
|
|
2537
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate", children: selectedEvent.event_name })
|
|
2538
|
+
] });
|
|
2539
|
+
}
|
|
2540
|
+
if (showOrganisations && selectedOrganisation) {
|
|
2541
|
+
return /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
2542
|
+
/* @__PURE__ */ jsx13(Building2, { className: "size-4 flex-shrink-0" }),
|
|
2543
|
+
/* @__PURE__ */ jsx13("span", { className: "truncate", children: selectedOrganisation.display_name })
|
|
2544
|
+
] });
|
|
2545
|
+
}
|
|
2546
|
+
return null;
|
|
2547
|
+
}, [showOrganisations, showEvents, selectedOrganisation, selectedEvent]);
|
|
2548
|
+
const effectivePlaceholder = useMemo5(() => {
|
|
2549
|
+
if (placeholder !== "Select organisation or event") {
|
|
2550
|
+
return placeholder;
|
|
2551
|
+
}
|
|
2552
|
+
if (showOrganisations && showEvents) {
|
|
2553
|
+
return "Select organisation or event";
|
|
2554
|
+
}
|
|
2555
|
+
if (showOrganisations) {
|
|
2556
|
+
return "Select organisation";
|
|
2557
|
+
}
|
|
2558
|
+
if (showEvents) {
|
|
2559
|
+
return "Select event";
|
|
2560
|
+
}
|
|
2561
|
+
return placeholder;
|
|
2562
|
+
}, [placeholder, showOrganisations, showEvents]);
|
|
2563
|
+
return /* @__PURE__ */ jsx13("div", { className, "data-testid": "context-selector", children: /* @__PURE__ */ jsxs8(
|
|
2564
|
+
Select,
|
|
2565
|
+
{
|
|
2566
|
+
value: currentValue,
|
|
2567
|
+
onValueChange: handleValueChange,
|
|
2568
|
+
disabled: disabled || isLoading,
|
|
2569
|
+
children: [
|
|
2570
|
+
/* @__PURE__ */ jsx13(
|
|
2571
|
+
SelectTrigger,
|
|
2572
|
+
{
|
|
2573
|
+
className: "text-left",
|
|
2574
|
+
variant: "outline",
|
|
2575
|
+
children: /* @__PURE__ */ jsx13(SelectValue, { placeholder: effectivePlaceholder, children: displayValue })
|
|
2576
|
+
}
|
|
2577
|
+
),
|
|
2578
|
+
/* @__PURE__ */ jsxs8(SelectContent, { children: [
|
|
2579
|
+
showOrganisations && organisations && organisations.length > 0 && /* @__PURE__ */ jsxs8(Fragment6, { children: [
|
|
2580
|
+
/* @__PURE__ */ jsxs8(SelectGroup, { children: [
|
|
2581
|
+
/* @__PURE__ */ jsx13(SelectLabel, { children: "Organisations" }),
|
|
2582
|
+
organisations.map((org) => /* @__PURE__ */ jsx13(
|
|
2583
|
+
SelectItem,
|
|
2584
|
+
{
|
|
2585
|
+
value: `org:${org.id}`,
|
|
2586
|
+
children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
2587
|
+
/* @__PURE__ */ jsx13(Building2, { className: "size-4" }),
|
|
2588
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
|
|
2589
|
+
/* @__PURE__ */ jsx13("span", { className: "font-medium", children: org.display_name }),
|
|
2590
|
+
!compact && org.description && /* @__PURE__ */ jsx13("span", { className: "text-xs text-muted-foreground truncate max-w-40", children: org.description })
|
|
2591
|
+
] })
|
|
2592
|
+
] })
|
|
2593
|
+
},
|
|
2594
|
+
org.id
|
|
2595
|
+
))
|
|
2596
|
+
] }),
|
|
2597
|
+
showEvents && events && events.length > 0 && /* @__PURE__ */ jsx13(SelectSeparator, {})
|
|
2598
|
+
] }),
|
|
2599
|
+
showEvents && events && events.length > 0 && /* @__PURE__ */ jsxs8(SelectGroup, { children: [
|
|
2600
|
+
/* @__PURE__ */ jsx13(SelectLabel, { children: "Events" }),
|
|
2601
|
+
events.map((event) => /* @__PURE__ */ jsx13(
|
|
2736
2602
|
SelectItem,
|
|
2737
2603
|
{
|
|
2738
|
-
value:
|
|
2739
|
-
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
/* @__PURE__ */
|
|
2744
|
-
/* @__PURE__ */ jsxs9("div", { className: "flex flex-col", children: [
|
|
2745
|
-
/* @__PURE__ */ jsx14("span", { className: "font-medium", children: org.display_name }),
|
|
2746
|
-
!compact && org.description && /* @__PURE__ */ jsx14("span", { className: "text-xs text-muted-foreground truncate max-w-40", children: org.description })
|
|
2747
|
-
] })
|
|
2748
|
-
] }),
|
|
2749
|
-
showRole && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1 ml-4", children: [
|
|
2750
|
-
/* @__PURE__ */ jsx14(Shield, { className: "size-3 text-muted-foreground" }),
|
|
2751
|
-
/* @__PURE__ */ jsx14("span", { className: "text-xs text-muted-foreground capitalize", children: userRole?.replace("_", " ") || "No Role" })
|
|
2604
|
+
value: `event:${event.event_id || event.id}`,
|
|
2605
|
+
children: /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
|
|
2606
|
+
/* @__PURE__ */ jsx13(Calendar2, { className: "size-4" }),
|
|
2607
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex flex-col", children: [
|
|
2608
|
+
/* @__PURE__ */ jsx13("span", { className: "font-medium", children: event.event_name }),
|
|
2609
|
+
!compact && event.event_date && /* @__PURE__ */ jsx13("span", { className: "text-xs text-muted-foreground", children: new Date(event.event_date).toLocaleDateString() })
|
|
2752
2610
|
] })
|
|
2753
2611
|
] })
|
|
2754
2612
|
},
|
|
2755
|
-
|
|
2756
|
-
)
|
|
2757
|
-
|
|
2758
|
-
]
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
] });
|
|
2613
|
+
event.event_id || event.id
|
|
2614
|
+
))
|
|
2615
|
+
] })
|
|
2616
|
+
] })
|
|
2617
|
+
]
|
|
2618
|
+
}
|
|
2619
|
+
) });
|
|
2763
2620
|
}
|
|
2764
2621
|
|
|
2765
2622
|
// src/components/PasswordChange/PasswordChangeForm.tsx
|
|
2766
|
-
import { useState as
|
|
2767
|
-
import { jsx as
|
|
2623
|
+
import { useState as useState8 } from "react";
|
|
2624
|
+
import { jsx as jsx14, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
2768
2625
|
function PasswordChangeForm({ onSubmit, className }) {
|
|
2769
|
-
const [newPassword, setNewPassword] =
|
|
2770
|
-
const [confirmPassword, setConfirmPassword] =
|
|
2771
|
-
const [error, setError] =
|
|
2772
|
-
const [isSubmitting, setIsSubmitting] =
|
|
2626
|
+
const [newPassword, setNewPassword] = useState8("");
|
|
2627
|
+
const [confirmPassword, setConfirmPassword] = useState8("");
|
|
2628
|
+
const [error, setError] = useState8(null);
|
|
2629
|
+
const [isSubmitting, setIsSubmitting] = useState8(false);
|
|
2773
2630
|
const handleSubmit = async (e) => {
|
|
2774
2631
|
e.preventDefault();
|
|
2775
2632
|
setError(null);
|
|
@@ -2794,11 +2651,11 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2794
2651
|
setIsSubmitting(false);
|
|
2795
2652
|
}
|
|
2796
2653
|
};
|
|
2797
|
-
return /* @__PURE__ */
|
|
2798
|
-
error && /* @__PURE__ */
|
|
2799
|
-
/* @__PURE__ */
|
|
2800
|
-
/* @__PURE__ */
|
|
2801
|
-
/* @__PURE__ */
|
|
2654
|
+
return /* @__PURE__ */ jsxs9("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: [
|
|
2655
|
+
error && /* @__PURE__ */ jsx14("div", { role: "alert", children: error }),
|
|
2656
|
+
/* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
|
|
2657
|
+
/* @__PURE__ */ jsx14(Label, { htmlFor: "new-password", children: "New Password" }),
|
|
2658
|
+
/* @__PURE__ */ jsx14(
|
|
2802
2659
|
Input,
|
|
2803
2660
|
{
|
|
2804
2661
|
id: "new-password",
|
|
@@ -2810,9 +2667,9 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2810
2667
|
}
|
|
2811
2668
|
)
|
|
2812
2669
|
] }),
|
|
2813
|
-
/* @__PURE__ */
|
|
2814
|
-
/* @__PURE__ */
|
|
2815
|
-
/* @__PURE__ */
|
|
2670
|
+
/* @__PURE__ */ jsxs9("div", { className: "space-y-2", children: [
|
|
2671
|
+
/* @__PURE__ */ jsx14(Label, { htmlFor: "confirm-password", children: "Confirm Password" }),
|
|
2672
|
+
/* @__PURE__ */ jsx14(
|
|
2816
2673
|
Input,
|
|
2817
2674
|
{
|
|
2818
2675
|
id: "confirm-password",
|
|
@@ -2824,7 +2681,7 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2824
2681
|
}
|
|
2825
2682
|
)
|
|
2826
2683
|
] }),
|
|
2827
|
-
/* @__PURE__ */
|
|
2684
|
+
/* @__PURE__ */ jsx14(
|
|
2828
2685
|
Button,
|
|
2829
2686
|
{
|
|
2830
2687
|
type: "submit",
|
|
@@ -2837,9 +2694,9 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2837
2694
|
}
|
|
2838
2695
|
|
|
2839
2696
|
// src/components/UserMenu/UserMenu.tsx
|
|
2840
|
-
import React12, { useCallback as
|
|
2697
|
+
import React12, { useCallback as useCallback8, useMemo as useMemo6, useState as useState9 } from "react";
|
|
2841
2698
|
import { ChevronDown, LogOut, KeyRound } from "lucide-react";
|
|
2842
|
-
import { jsx as
|
|
2699
|
+
import { jsx as jsx15, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
2843
2700
|
var UserMenu = React12.memo(function UserMenu2({
|
|
2844
2701
|
user,
|
|
2845
2702
|
onSignOut,
|
|
@@ -2847,8 +2704,8 @@ var UserMenu = React12.memo(function UserMenu2({
|
|
|
2847
2704
|
className,
|
|
2848
2705
|
showAvatar = true
|
|
2849
2706
|
}) {
|
|
2850
|
-
const [isPasswordDialogOpen, setPasswordDialogOpen] =
|
|
2851
|
-
const userInfo =
|
|
2707
|
+
const [isPasswordDialogOpen, setPasswordDialogOpen] = useState9(false);
|
|
2708
|
+
const userInfo = useMemo6(() => {
|
|
2852
2709
|
if (!user) return null;
|
|
2853
2710
|
return {
|
|
2854
2711
|
email: user.email,
|
|
@@ -2857,16 +2714,16 @@ var UserMenu = React12.memo(function UserMenu2({
|
|
|
2857
2714
|
initial: (user.user_metadata?.display_name || user.user_metadata?.full_name || user.email || "U").charAt(0).toUpperCase()
|
|
2858
2715
|
};
|
|
2859
2716
|
}, [user]);
|
|
2860
|
-
const handleSignOut =
|
|
2717
|
+
const handleSignOut = useCallback8(async () => {
|
|
2861
2718
|
if (onSignOut) await onSignOut();
|
|
2862
2719
|
}, [onSignOut]);
|
|
2863
2720
|
if (!user || !userInfo) {
|
|
2864
2721
|
return null;
|
|
2865
2722
|
}
|
|
2866
|
-
return /* @__PURE__ */
|
|
2867
|
-
/* @__PURE__ */
|
|
2868
|
-
/* @__PURE__ */
|
|
2869
|
-
showAvatar && /* @__PURE__ */
|
|
2723
|
+
return /* @__PURE__ */ jsxs10(Dialog, { open: isPasswordDialogOpen, onOpenChange: setPasswordDialogOpen, children: [
|
|
2724
|
+
/* @__PURE__ */ jsxs10(Select, { className, children: [
|
|
2725
|
+
/* @__PURE__ */ jsx15(SelectTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(Button, { variant: "outline", className: "flex items-center gap-2", "aria-label": userInfo.displayName, children: [
|
|
2726
|
+
showAvatar && /* @__PURE__ */ jsx15(
|
|
2870
2727
|
Avatar,
|
|
2871
2728
|
{
|
|
2872
2729
|
src: userInfo.avatarUrl,
|
|
@@ -2875,30 +2732,30 @@ var UserMenu = React12.memo(function UserMenu2({
|
|
|
2875
2732
|
className: "size-7"
|
|
2876
2733
|
}
|
|
2877
2734
|
),
|
|
2878
|
-
/* @__PURE__ */
|
|
2879
|
-
/* @__PURE__ */
|
|
2735
|
+
/* @__PURE__ */ jsx15("span", { children: userInfo.displayName }),
|
|
2736
|
+
/* @__PURE__ */ jsx15(ChevronDown, { className: "size-4" })
|
|
2880
2737
|
] }) }),
|
|
2881
|
-
/* @__PURE__ */
|
|
2882
|
-
/* @__PURE__ */
|
|
2738
|
+
/* @__PURE__ */ jsxs10(SelectContent, { children: [
|
|
2739
|
+
/* @__PURE__ */ jsx15(SelectLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs10("li", { className: "pt-2", children: [
|
|
2883
2740
|
userInfo.displayName,
|
|
2884
|
-
/* @__PURE__ */
|
|
2885
|
-
/* @__PURE__ */
|
|
2741
|
+
/* @__PURE__ */ jsx15("br", {}),
|
|
2742
|
+
/* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: userInfo.email })
|
|
2886
2743
|
] }) }),
|
|
2887
|
-
/* @__PURE__ */
|
|
2888
|
-
/* @__PURE__ */
|
|
2889
|
-
/* @__PURE__ */
|
|
2890
|
-
/* @__PURE__ */
|
|
2744
|
+
/* @__PURE__ */ jsx15(SelectSeparator, {}),
|
|
2745
|
+
/* @__PURE__ */ jsx15(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs10(SelectItem, { value: "change-password", children: [
|
|
2746
|
+
/* @__PURE__ */ jsx15(KeyRound, { className: "mr-2 size-4" }),
|
|
2747
|
+
/* @__PURE__ */ jsx15("span", { children: "Change Password" })
|
|
2891
2748
|
] }) }),
|
|
2892
|
-
/* @__PURE__ */
|
|
2893
|
-
/* @__PURE__ */
|
|
2894
|
-
/* @__PURE__ */
|
|
2749
|
+
/* @__PURE__ */ jsxs10(SelectItem, { value: "sign-out", onClick: handleSignOut, children: [
|
|
2750
|
+
/* @__PURE__ */ jsx15(LogOut, { className: "mr-2 size-4" }),
|
|
2751
|
+
/* @__PURE__ */ jsx15("span", { children: "Sign out" })
|
|
2895
2752
|
] })
|
|
2896
2753
|
] })
|
|
2897
2754
|
] }),
|
|
2898
|
-
/* @__PURE__ */
|
|
2899
|
-
/* @__PURE__ */
|
|
2900
|
-
/* @__PURE__ */
|
|
2901
|
-
/* @__PURE__ */
|
|
2755
|
+
/* @__PURE__ */ jsx15(DialogOverlay, {}),
|
|
2756
|
+
/* @__PURE__ */ jsxs10(DialogContent, { className, children: [
|
|
2757
|
+
/* @__PURE__ */ jsx15(DialogHeader, { children: /* @__PURE__ */ jsx15(DialogTitle, { children: "Change Password" }) }),
|
|
2758
|
+
/* @__PURE__ */ jsx15(
|
|
2902
2759
|
PasswordChangeForm,
|
|
2903
2760
|
{
|
|
2904
2761
|
onSubmit: async ({ newPassword, confirmPassword }) => {
|
|
@@ -2917,7 +2774,7 @@ var UserMenu = React12.memo(function UserMenu2({
|
|
|
2917
2774
|
] });
|
|
2918
2775
|
});
|
|
2919
2776
|
var UserMenuLoading = React12.memo(function UserMenuLoading2() {
|
|
2920
|
-
return /* @__PURE__ */
|
|
2777
|
+
return /* @__PURE__ */ jsxs10(
|
|
2921
2778
|
Button,
|
|
2922
2779
|
{
|
|
2923
2780
|
type: "button",
|
|
@@ -2926,9 +2783,9 @@ var UserMenuLoading = React12.memo(function UserMenuLoading2() {
|
|
|
2926
2783
|
className: "flex items-center space-x-2",
|
|
2927
2784
|
"aria-label": "Loading user menu",
|
|
2928
2785
|
children: [
|
|
2929
|
-
/* @__PURE__ */
|
|
2930
|
-
/* @__PURE__ */
|
|
2931
|
-
/* @__PURE__ */
|
|
2786
|
+
/* @__PURE__ */ jsx15(LoadingSpinner, { size: "sm", className: "inline-block mr-2" }),
|
|
2787
|
+
/* @__PURE__ */ jsx15("span", { className: "truncate max-w-[150px]", children: "Loading..." }),
|
|
2788
|
+
/* @__PURE__ */ jsx15(ChevronDown, { className: "w-4 h-4 text-muted-foreground" })
|
|
2932
2789
|
]
|
|
2933
2790
|
}
|
|
2934
2791
|
);
|
|
@@ -2984,7 +2841,7 @@ function useNavigationFiltering({
|
|
|
2984
2841
|
}
|
|
2985
2842
|
const userId2 = authContext.user.id;
|
|
2986
2843
|
const appName = authContext.appName;
|
|
2987
|
-
import("./api-
|
|
2844
|
+
import("./api-IAGWF3ZG.js").then(({ resolveAppContext }) => {
|
|
2988
2845
|
resolveAppContext({
|
|
2989
2846
|
userId: userId2,
|
|
2990
2847
|
appName
|
|
@@ -3227,7 +3084,7 @@ function useNavigationFiltering({
|
|
|
3227
3084
|
}
|
|
3228
3085
|
|
|
3229
3086
|
// src/components/NavigationMenu/NavigationMenu.tsx
|
|
3230
|
-
import { jsx as
|
|
3087
|
+
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3231
3088
|
var NavigationMenu = React14.forwardRef(({
|
|
3232
3089
|
items,
|
|
3233
3090
|
mode = "dropdown",
|
|
@@ -3370,8 +3227,8 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3370
3227
|
const hasChildren = item.children && item.children.length > 0;
|
|
3371
3228
|
const isExpanded = expandedItems.has(item.id);
|
|
3372
3229
|
const itemIsActive = isActiveItem(item);
|
|
3373
|
-
return /* @__PURE__ */
|
|
3374
|
-
/* @__PURE__ */
|
|
3230
|
+
return /* @__PURE__ */ jsx16("li", { role: "none", children: hasChildren ? /* @__PURE__ */ jsxs11("div", { children: [
|
|
3231
|
+
/* @__PURE__ */ jsxs11(
|
|
3375
3232
|
"button",
|
|
3376
3233
|
{
|
|
3377
3234
|
onClick: () => toggleExpanded(item.id),
|
|
@@ -3380,21 +3237,21 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3380
3237
|
"aria-controls": `submenu-${item.id}`,
|
|
3381
3238
|
"aria-current": itemIsActive ? "page" : void 0,
|
|
3382
3239
|
children: [
|
|
3383
|
-
/* @__PURE__ */
|
|
3384
|
-
/* @__PURE__ */
|
|
3240
|
+
/* @__PURE__ */ jsx16("span", { children: item.label }),
|
|
3241
|
+
/* @__PURE__ */ jsx16(ChevronDown2, { "aria-hidden": "true" })
|
|
3385
3242
|
]
|
|
3386
3243
|
}
|
|
3387
3244
|
),
|
|
3388
|
-
isExpanded && item.children && /* @__PURE__ */
|
|
3245
|
+
isExpanded && item.children && /* @__PURE__ */ jsx16(
|
|
3389
3246
|
"ul",
|
|
3390
3247
|
{
|
|
3391
3248
|
id: `submenu-${item.id}`,
|
|
3392
3249
|
role: "menu",
|
|
3393
3250
|
"aria-label": `${item.label} submenu`,
|
|
3394
|
-
children: item.children.map((child) => /* @__PURE__ */
|
|
3251
|
+
children: item.children.map((child) => /* @__PURE__ */ jsx16(React14.Fragment, { children: renderHierarchicalItem(child, level + 1) }, child.id))
|
|
3395
3252
|
}
|
|
3396
3253
|
)
|
|
3397
|
-
] }) : /* @__PURE__ */
|
|
3254
|
+
] }) : /* @__PURE__ */ jsx16(
|
|
3398
3255
|
"a",
|
|
3399
3256
|
{
|
|
3400
3257
|
href: item.href || "#",
|
|
@@ -3412,26 +3269,26 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3412
3269
|
) });
|
|
3413
3270
|
};
|
|
3414
3271
|
if (mode === "dropdown") {
|
|
3415
|
-
return /* @__PURE__ */
|
|
3272
|
+
return /* @__PURE__ */ jsxs11(
|
|
3416
3273
|
Select,
|
|
3417
3274
|
{
|
|
3418
3275
|
onValueChange: handleNavigationSelect,
|
|
3419
3276
|
className,
|
|
3420
3277
|
"data-testid": "navigation-menu-root",
|
|
3421
3278
|
children: [
|
|
3422
|
-
/* @__PURE__ */
|
|
3279
|
+
/* @__PURE__ */ jsx16(
|
|
3423
3280
|
SelectTrigger,
|
|
3424
3281
|
{
|
|
3425
3282
|
ref: buttonRef,
|
|
3426
3283
|
disabled,
|
|
3427
3284
|
"aria-label": buttonText,
|
|
3428
3285
|
"data-testid": "navigation-menu-trigger",
|
|
3429
|
-
children: /* @__PURE__ */
|
|
3286
|
+
children: /* @__PURE__ */ jsx16(SelectValue, { placeholder: buttonText })
|
|
3430
3287
|
}
|
|
3431
3288
|
),
|
|
3432
|
-
/* @__PURE__ */
|
|
3289
|
+
/* @__PURE__ */ jsx16(SelectContent, { children: filteredItems.map((item) => {
|
|
3433
3290
|
const isActive = isActiveItem(item);
|
|
3434
|
-
return /* @__PURE__ */
|
|
3291
|
+
return /* @__PURE__ */ jsx16(
|
|
3435
3292
|
SelectItem,
|
|
3436
3293
|
{
|
|
3437
3294
|
value: item.id,
|
|
@@ -3446,14 +3303,14 @@ var NavigationMenu = React14.forwardRef(({
|
|
|
3446
3303
|
}
|
|
3447
3304
|
);
|
|
3448
3305
|
}
|
|
3449
|
-
return /* @__PURE__ */
|
|
3306
|
+
return /* @__PURE__ */ jsx16(
|
|
3450
3307
|
"nav",
|
|
3451
3308
|
{
|
|
3452
3309
|
ref,
|
|
3453
3310
|
className,
|
|
3454
3311
|
"aria-label": navigationLabel,
|
|
3455
3312
|
...props,
|
|
3456
|
-
children: /* @__PURE__ */
|
|
3313
|
+
children: /* @__PURE__ */ jsx16("ul", { role: "menubar", children: filteredItems.map((item) => /* @__PURE__ */ jsx16(React14.Fragment, { children: renderHierarchicalItem(item, 0) }, item.id)) })
|
|
3457
3314
|
}
|
|
3458
3315
|
);
|
|
3459
3316
|
});
|
|
@@ -3461,7 +3318,7 @@ NavigationMenu.displayName = "NavigationMenu";
|
|
|
3461
3318
|
|
|
3462
3319
|
// src/components/Header/Header.tsx
|
|
3463
3320
|
import { Link } from "react-router-dom";
|
|
3464
|
-
import { jsx as
|
|
3321
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3465
3322
|
function Header({
|
|
3466
3323
|
logoUrl,
|
|
3467
3324
|
logoAlt = "Logo",
|
|
@@ -3473,54 +3330,43 @@ function Header({
|
|
|
3473
3330
|
actions,
|
|
3474
3331
|
userMenu,
|
|
3475
3332
|
className,
|
|
3476
|
-
|
|
3477
|
-
|
|
3333
|
+
showContextSelector = true,
|
|
3334
|
+
showOrganisations = true,
|
|
3335
|
+
showEvents = true,
|
|
3478
3336
|
showUserMenu = true,
|
|
3479
3337
|
currentPath,
|
|
3480
3338
|
onNavigate,
|
|
3481
3339
|
logoHref
|
|
3482
3340
|
}) {
|
|
3483
|
-
const
|
|
3484
|
-
|
|
3485
|
-
|
|
3486
|
-
|
|
3487
|
-
}
|
|
3488
|
-
return /* @__PURE__ */ jsx18(
|
|
3489
|
-
OrganisationSelector,
|
|
3490
|
-
{
|
|
3491
|
-
placeholder: "Select organisation",
|
|
3492
|
-
className: "w-64",
|
|
3493
|
-
"data-testid": "org-selector",
|
|
3494
|
-
compact: true
|
|
3495
|
-
}
|
|
3496
|
-
);
|
|
3497
|
-
};
|
|
3498
|
-
return /* @__PURE__ */ jsx18("header", { className: cn(
|
|
3341
|
+
const shouldShowContextSelector = showContextSelector !== false;
|
|
3342
|
+
const { switchOrganisation } = useOrganisations();
|
|
3343
|
+
const { events, setSelectedEvent } = useEvents();
|
|
3344
|
+
return /* @__PURE__ */ jsx17("header", { className: cn(
|
|
3499
3345
|
"w-full border-b border-main-200 h-16 shadow-sm bg-main-100 ",
|
|
3500
3346
|
className
|
|
3501
|
-
), role: "banner", children: /* @__PURE__ */
|
|
3502
|
-
logo ? logoHref ? /* @__PURE__ */
|
|
3347
|
+
), role: "banner", children: /* @__PURE__ */ jsxs12("nav", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto grid grid-cols-[auto_1fr_auto_auto_auto_auto] items-center gap-4 h-full", children: [
|
|
3348
|
+
logo ? logoHref ? /* @__PURE__ */ jsx17(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: logo }) : logo : logoUrl ? logoHref ? /* @__PURE__ */ jsx17(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx17(
|
|
3503
3349
|
"img",
|
|
3504
3350
|
{
|
|
3505
3351
|
src: logoUrl,
|
|
3506
3352
|
alt: logoAlt || "Logo",
|
|
3507
3353
|
className: "h-[2.15rem] w-auto max-w-[200px] object-contain rounded-md shadow-md bg-transparent"
|
|
3508
3354
|
}
|
|
3509
|
-
) }) : /* @__PURE__ */
|
|
3355
|
+
) }) : /* @__PURE__ */ jsx17(
|
|
3510
3356
|
"img",
|
|
3511
3357
|
{
|
|
3512
3358
|
src: logoUrl,
|
|
3513
3359
|
alt: logoAlt || "Logo",
|
|
3514
3360
|
className: "h-[2.15rem] w-auto max-w-[200px] object-contain rounded-md shadow-md bg-transparent"
|
|
3515
3361
|
}
|
|
3516
|
-
) : logoHref ? /* @__PURE__ */
|
|
3362
|
+
) : logoHref ? /* @__PURE__ */ jsx17(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx17(
|
|
3517
3363
|
"img",
|
|
3518
3364
|
{
|
|
3519
3365
|
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",
|
|
3520
3366
|
alt: logoAlt || "Logo",
|
|
3521
3367
|
className: "size-8 shadow-md"
|
|
3522
3368
|
}
|
|
3523
|
-
) }) : /* @__PURE__ */
|
|
3369
|
+
) }) : /* @__PURE__ */ jsx17(
|
|
3524
3370
|
"img",
|
|
3525
3371
|
{
|
|
3526
3372
|
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",
|
|
@@ -3528,7 +3374,7 @@ function Header({
|
|
|
3528
3374
|
className: "size-8 shadow-md"
|
|
3529
3375
|
}
|
|
3530
3376
|
),
|
|
3531
|
-
navItems && navItems.length > 0 && /* @__PURE__ */
|
|
3377
|
+
navItems && navItems.length > 0 && /* @__PURE__ */ jsx17(
|
|
3532
3378
|
NavigationMenu,
|
|
3533
3379
|
{
|
|
3534
3380
|
items: navItems,
|
|
@@ -3539,23 +3385,30 @@ function Header({
|
|
|
3539
3385
|
itemsPreFiltered: true
|
|
3540
3386
|
}
|
|
3541
3387
|
),
|
|
3542
|
-
|
|
3543
|
-
|
|
3544
|
-
EventSelector,
|
|
3388
|
+
shouldShowContextSelector ? /* @__PURE__ */ jsx17(
|
|
3389
|
+
ContextSelector,
|
|
3545
3390
|
{
|
|
3546
|
-
placeholder: "Select event",
|
|
3391
|
+
placeholder: "Select organisation or event",
|
|
3547
3392
|
className: cn(
|
|
3548
3393
|
"w-96",
|
|
3549
|
-
//
|
|
3550
|
-
|
|
3551
|
-
// If neither exists, EventSelector spans 3 columns
|
|
3552
|
-
showOrgSelector && actions ? "col-span-1" : showOrgSelector || actions ? "col-span-2" : "col-span-3"
|
|
3394
|
+
// Adjust width based on whether actions exist
|
|
3395
|
+
actions ? "col-span-1" : "col-span-2"
|
|
3553
3396
|
),
|
|
3554
|
-
|
|
3397
|
+
showOrganisations,
|
|
3398
|
+
showEvents,
|
|
3399
|
+
onOrganisationSelect: async (org) => {
|
|
3400
|
+
setSelectedEvent(null);
|
|
3401
|
+
await switchOrganisation(org.id);
|
|
3402
|
+
},
|
|
3403
|
+
onEventSelect: (event) => {
|
|
3404
|
+
const fullEvent = events.find((e) => (e.event_id || e.id) === (event.event_id || event.id));
|
|
3405
|
+
setSelectedEvent(fullEvent || event);
|
|
3406
|
+
},
|
|
3407
|
+
compact: true
|
|
3555
3408
|
}
|
|
3556
3409
|
) : null,
|
|
3557
3410
|
actions,
|
|
3558
|
-
showUserMenu && (userMenu ? userMenu : /* @__PURE__ */
|
|
3411
|
+
showUserMenu && (userMenu ? userMenu : /* @__PURE__ */ jsx17(
|
|
3559
3412
|
UserMenu,
|
|
3560
3413
|
{
|
|
3561
3414
|
user: user || null,
|
|
@@ -3569,7 +3422,7 @@ function Header({
|
|
|
3569
3422
|
|
|
3570
3423
|
// src/components/Footer/Footer.tsx
|
|
3571
3424
|
import React15 from "react";
|
|
3572
|
-
import { Fragment as
|
|
3425
|
+
import { Fragment as Fragment8, jsx as jsx18, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
3573
3426
|
var FooterComponent = ({
|
|
3574
3427
|
companyName = "Solvera Solutions Pty Ltd",
|
|
3575
3428
|
year = (/* @__PURE__ */ new Date()).getFullYear(),
|
|
@@ -3580,11 +3433,11 @@ var FooterComponent = ({
|
|
|
3580
3433
|
children
|
|
3581
3434
|
}) => {
|
|
3582
3435
|
const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
|
|
3583
|
-
return /* @__PURE__ */
|
|
3584
|
-
logo && /* @__PURE__ */
|
|
3585
|
-
children && /* @__PURE__ */
|
|
3586
|
-
/* @__PURE__ */
|
|
3587
|
-
links && links.length > 0 && /* @__PURE__ */
|
|
3436
|
+
return /* @__PURE__ */ jsx18("footer", { className: cn("mt-8 py-6 flex justify-center border-t border-border bg-main-100", className), children: /* @__PURE__ */ jsxs13("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
|
|
3437
|
+
logo && /* @__PURE__ */ jsx18("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
|
|
3438
|
+
children && /* @__PURE__ */ jsx18(Fragment8, { children }),
|
|
3439
|
+
/* @__PURE__ */ jsx18("span", { className: "text-muted-foreground", children: copyrightText }),
|
|
3440
|
+
links && links.length > 0 && /* @__PURE__ */ jsx18("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx18("li", { children: /* @__PURE__ */ jsx18("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
|
|
3588
3441
|
] }) });
|
|
3589
3442
|
};
|
|
3590
3443
|
FooterComponent.displayName = "Footer";
|
|
@@ -3592,16 +3445,17 @@ var Footer = React15.memo(FooterComponent);
|
|
|
3592
3445
|
Footer.displayName = "Footer";
|
|
3593
3446
|
|
|
3594
3447
|
// src/components/PaceAppLayout/PaceAppLayout.tsx
|
|
3595
|
-
import { useState as
|
|
3448
|
+
import { useState as useState12, useEffect as useEffect7, useMemo as useMemo8 } from "react";
|
|
3596
3449
|
import { Outlet, useNavigate, useLocation } from "react-router-dom";
|
|
3597
|
-
import { Fragment as
|
|
3450
|
+
import { Fragment as Fragment9, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3598
3451
|
var EMPTY_PAGE_ID_MAPPING = {};
|
|
3599
3452
|
var EMPTY_ROUTE_PERMISSIONS = {};
|
|
3600
3453
|
function PaceAppLayout({
|
|
3601
3454
|
appName,
|
|
3602
3455
|
navItems,
|
|
3603
|
-
|
|
3604
|
-
|
|
3456
|
+
showContextSelector = true,
|
|
3457
|
+
showOrganisations = true,
|
|
3458
|
+
showEvents = true,
|
|
3605
3459
|
headerActions,
|
|
3606
3460
|
customLogo,
|
|
3607
3461
|
logoHref = "/dashboard",
|
|
@@ -3636,9 +3490,9 @@ function PaceAppLayout({
|
|
|
3636
3490
|
isLoading: organisationLoading
|
|
3637
3491
|
} = useOrganisations();
|
|
3638
3492
|
const { isSuperAdmin: isSuperAdminFromRBAC, isLoading: rbacLoading } = useRBAC();
|
|
3639
|
-
const [isSuperAdminDirect, setIsSuperAdminDirect] =
|
|
3640
|
-
const [isCheckingSuperAdminDirect, setIsCheckingSuperAdminDirect] =
|
|
3641
|
-
|
|
3493
|
+
const [isSuperAdminDirect, setIsSuperAdminDirect] = useState12(false);
|
|
3494
|
+
const [isCheckingSuperAdminDirect, setIsCheckingSuperAdminDirect] = useState12(false);
|
|
3495
|
+
useEffect7(() => {
|
|
3642
3496
|
const checkSuperAdminDirect = async () => {
|
|
3643
3497
|
if (!user?.id) {
|
|
3644
3498
|
setIsSuperAdminDirect(false);
|
|
@@ -3681,7 +3535,7 @@ function PaceAppLayout({
|
|
|
3681
3535
|
const scopeOrgId = resolvedScope?.organisationId || selectedOrganisation?.id || "";
|
|
3682
3536
|
const scopeEventId = resolvedScope?.eventId || selectedEvent?.event_id || void 0;
|
|
3683
3537
|
const scopeAppId = resolvedScope?.appId || resolvedAppId || void 0;
|
|
3684
|
-
const scope =
|
|
3538
|
+
const scope = useMemo8(() => {
|
|
3685
3539
|
const newScope = {};
|
|
3686
3540
|
if (scopeOrgId) {
|
|
3687
3541
|
newScope.organisationId = scopeOrgId;
|
|
@@ -3694,19 +3548,19 @@ function PaceAppLayout({
|
|
|
3694
3548
|
}
|
|
3695
3549
|
return newScope;
|
|
3696
3550
|
}, [scopeOrgId, scopeEventId, scopeAppId]);
|
|
3697
|
-
const defaultNavItems =
|
|
3551
|
+
const defaultNavItems = useMemo8(() => [
|
|
3698
3552
|
{ id: "home", label: "Home", href: "/", icon: "Home" },
|
|
3699
3553
|
{ id: "dashboard", label: "Dashboard", href: "/dashboard", icon: "LayoutDashboard" },
|
|
3700
3554
|
{ id: "settings", label: "Settings", href: "/settings", icon: "Settings" },
|
|
3701
3555
|
{ id: "ui-showcase", label: "UI Showcase", href: "/ui-showcase", icon: "Component" },
|
|
3702
3556
|
{ id: "data-table-showcase", label: "DataTable Showcase", href: "/data-table-showcase", icon: "Table" }
|
|
3703
3557
|
], []);
|
|
3704
|
-
const baseMenuItems =
|
|
3705
|
-
const currentRoutePermission =
|
|
3558
|
+
const baseMenuItems = useMemo8(() => navItems || defaultNavItems, [navItems]);
|
|
3559
|
+
const currentRoutePermission = useMemo8(() => {
|
|
3706
3560
|
const currentPath = location.pathname;
|
|
3707
3561
|
return routePermissions[currentPath] || defaultPermission;
|
|
3708
3562
|
}, [location.pathname, routePermissions, defaultPermission]);
|
|
3709
|
-
const currentPageId =
|
|
3563
|
+
const currentPageId = useMemo8(() => {
|
|
3710
3564
|
const currentPath = location.pathname;
|
|
3711
3565
|
if (pageIdMapping[currentPath]) {
|
|
3712
3566
|
return pageIdMapping[currentPath];
|
|
@@ -3714,7 +3568,7 @@ function PaceAppLayout({
|
|
|
3714
3568
|
const pathSegments = currentPath.slice(1).split("/").filter(Boolean);
|
|
3715
3569
|
return pathSegments[0] || "";
|
|
3716
3570
|
}, [location.pathname, pageIdMapping]);
|
|
3717
|
-
const currentPermission =
|
|
3571
|
+
const currentPermission = useMemo8(() => {
|
|
3718
3572
|
if (!enforcePermissions || !currentPageId) {
|
|
3719
3573
|
return "";
|
|
3720
3574
|
}
|
|
@@ -3737,7 +3591,7 @@ function PaceAppLayout({
|
|
|
3737
3591
|
);
|
|
3738
3592
|
const can = isSuperAdmin2 ? true : canFromHook;
|
|
3739
3593
|
const hasPermission = enforcePermissions ? can : true;
|
|
3740
|
-
|
|
3594
|
+
useEffect7(() => {
|
|
3741
3595
|
if (!enforcePermissions) {
|
|
3742
3596
|
return;
|
|
3743
3597
|
}
|
|
@@ -3760,8 +3614,8 @@ function PaceAppLayout({
|
|
|
3760
3614
|
onPageAccessDenied(currentPageId, currentRoutePermission);
|
|
3761
3615
|
}
|
|
3762
3616
|
}, [enforcePermissions, can, isCheckingPermission, isSuperAdmin2, currentPageId, currentRoutePermission, user?.id, strictMode, auditLog, onPageAccessDenied, onStrictModeViolation]);
|
|
3763
|
-
const [filteredMenuItems, setFilteredMenuItems] =
|
|
3764
|
-
|
|
3617
|
+
const [filteredMenuItems, setFilteredMenuItems] = useState12(baseMenuItems);
|
|
3618
|
+
useEffect7(() => {
|
|
3765
3619
|
let isMounted = true;
|
|
3766
3620
|
const filterItems = async () => {
|
|
3767
3621
|
if (!user?.id) {
|
|
@@ -3787,7 +3641,7 @@ function PaceAppLayout({
|
|
|
3787
3641
|
return;
|
|
3788
3642
|
}
|
|
3789
3643
|
try {
|
|
3790
|
-
const { isSuperAdmin: checkSuperAdminDynamic } = await import("./api-
|
|
3644
|
+
const { isSuperAdmin: checkSuperAdminDynamic } = await import("./api-IAGWF3ZG.js");
|
|
3791
3645
|
const isSuper = await checkSuperAdminDynamic(user.id);
|
|
3792
3646
|
if (isSuper) {
|
|
3793
3647
|
if (isMounted) {
|
|
@@ -3802,7 +3656,7 @@ function PaceAppLayout({
|
|
|
3802
3656
|
}
|
|
3803
3657
|
}
|
|
3804
3658
|
try {
|
|
3805
|
-
const { getPermissionMap } = await import("./api-
|
|
3659
|
+
const { getPermissionMap } = await import("./api-IAGWF3ZG.js");
|
|
3806
3660
|
const permissionScope = {
|
|
3807
3661
|
organisationId: currentScope.organisationId,
|
|
3808
3662
|
eventId: currentScope.eventId,
|
|
@@ -3813,16 +3667,80 @@ function PaceAppLayout({
|
|
|
3813
3667
|
userId: user.id,
|
|
3814
3668
|
scope: permissionScope
|
|
3815
3669
|
});
|
|
3816
|
-
const
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3670
|
+
const { getPageScopeType } = await import("./api-IAGWF3ZG.js");
|
|
3671
|
+
const effectiveAppId = currentScope.appId || resolvedAppId;
|
|
3672
|
+
const effectiveAppName = appName;
|
|
3673
|
+
const hasEventContext = !!currentScope.eventId;
|
|
3674
|
+
const hasOrgContext = !!currentScope.organisationId;
|
|
3675
|
+
const filtered = await Promise.all(
|
|
3676
|
+
baseMenuItems.map(async (item) => {
|
|
3677
|
+
if (!item.href) return { item, hasAccess: true, matchesScope: true, scopeCheckError: false };
|
|
3678
|
+
const pageId = pageIdMapping[item.href] || (item.href === "/" ? "dashboard" : item.href.slice(1)) || "dashboard";
|
|
3679
|
+
const permission = routePermissions[item.href] || defaultPermission;
|
|
3680
|
+
const fullPermission = permission.includes(":") ? permission : pageId ? `${permission}:page.${pageId}` : permission;
|
|
3681
|
+
const hasAccess = permissionMap["*"] === true || permissionMap[fullPermission] === true;
|
|
3682
|
+
let matchesScope = true;
|
|
3683
|
+
let scopeCheckError = false;
|
|
3684
|
+
if (effectiveAppId || effectiveAppName) {
|
|
3685
|
+
try {
|
|
3686
|
+
const pageScopeType = await getPageScopeType(
|
|
3687
|
+
pageId,
|
|
3688
|
+
effectiveAppId,
|
|
3689
|
+
effectiveAppName
|
|
3690
|
+
);
|
|
3691
|
+
if (hasEventContext) {
|
|
3692
|
+
matchesScope = pageScopeType === "event" || pageScopeType === "both";
|
|
3693
|
+
} else if (hasOrgContext) {
|
|
3694
|
+
matchesScope = pageScopeType === "organisation" || pageScopeType === "both";
|
|
3695
|
+
} else {
|
|
3696
|
+
matchesScope = true;
|
|
3697
|
+
}
|
|
3698
|
+
} catch (error) {
|
|
3699
|
+
scopeCheckError = true;
|
|
3700
|
+
logger.warn("PaceAppLayout", "Failed to get page scope type for navigation filtering", {
|
|
3701
|
+
pageId,
|
|
3702
|
+
href: item.href,
|
|
3703
|
+
contextType: hasEventContext ? "event" : hasOrgContext ? "organisation" : "none",
|
|
3704
|
+
error: error instanceof Error ? error.message : String(error),
|
|
3705
|
+
note: "Allowing page to prevent navigation from disappearing - this may indicate missing scope_type in database"
|
|
3706
|
+
});
|
|
3707
|
+
matchesScope = true;
|
|
3708
|
+
}
|
|
3709
|
+
} else {
|
|
3710
|
+
matchesScope = true;
|
|
3711
|
+
}
|
|
3712
|
+
return { item, hasAccess, matchesScope, scopeCheckError };
|
|
3713
|
+
})
|
|
3714
|
+
);
|
|
3824
3715
|
if (!isMounted) return;
|
|
3825
|
-
const accessibleItems = filtered.filter(({ hasAccess }) => hasAccess).map(({ item }) => item);
|
|
3716
|
+
const accessibleItems = filtered.filter(({ hasAccess, matchesScope }) => hasAccess && matchesScope).map(({ item }) => item);
|
|
3717
|
+
if (accessibleItems.length === 0 && filtered.length > 0) {
|
|
3718
|
+
const itemsWithPermissions = filtered.filter(({ hasAccess }) => hasAccess);
|
|
3719
|
+
const itemsFilteredByScope = filtered.filter(({ hasAccess, matchesScope }) => hasAccess && !matchesScope);
|
|
3720
|
+
const itemsWithScopeErrors = filtered.filter(({ hasAccess, scopeCheckError }) => hasAccess && scopeCheckError);
|
|
3721
|
+
if (itemsWithPermissions.length > 0 && itemsWithScopeErrors.length === itemsWithPermissions.length) {
|
|
3722
|
+
logger.warn("PaceAppLayout", "Scope checking failed for all items - falling back to permission-only filtering", {
|
|
3723
|
+
contextType: hasEventContext ? "event" : hasOrgContext ? "organisation" : "none",
|
|
3724
|
+
totalItems: baseMenuItems.length,
|
|
3725
|
+
itemsWithPermissions: itemsWithPermissions.length,
|
|
3726
|
+
scopeCheckErrorCount: itemsWithScopeErrors.length,
|
|
3727
|
+
note: "Showing items based on permissions only - scope filtering disabled due to errors. This may indicate database issues or missing scope_type values."
|
|
3728
|
+
});
|
|
3729
|
+
const fallbackItems = filtered.filter(({ hasAccess }) => hasAccess).map(({ item }) => item);
|
|
3730
|
+
if (isMounted && fallbackItems.length > 0) {
|
|
3731
|
+
setFilteredMenuItems(fallbackItems);
|
|
3732
|
+
return;
|
|
3733
|
+
}
|
|
3734
|
+
} else if (itemsWithPermissions.length > 0 && itemsFilteredByScope.length === itemsWithPermissions.length) {
|
|
3735
|
+
logger.info("PaceAppLayout", "All navigation items filtered out by scope type", {
|
|
3736
|
+
contextType: hasEventContext ? "event" : hasOrgContext ? "organisation" : "none",
|
|
3737
|
+
totalItems: baseMenuItems.length,
|
|
3738
|
+
itemsWithPermissions: itemsWithPermissions.length,
|
|
3739
|
+
itemsFilteredByScope: itemsFilteredByScope.length,
|
|
3740
|
+
note: "All pages appear to be scoped for a different context type - this is expected behavior. Navigation will be empty until user selects the appropriate context."
|
|
3741
|
+
});
|
|
3742
|
+
}
|
|
3743
|
+
}
|
|
3826
3744
|
setFilteredMenuItems(accessibleItems);
|
|
3827
3745
|
} catch (error) {
|
|
3828
3746
|
logger.error("PaceAppLayout", "Failed to load permission map for navigation filtering", { userId: user?.id, error });
|
|
@@ -3835,8 +3753,8 @@ function PaceAppLayout({
|
|
|
3835
3753
|
return () => {
|
|
3836
3754
|
isMounted = false;
|
|
3837
3755
|
};
|
|
3838
|
-
}, [baseMenuItems, pageIdMapping, routePermissions, defaultPermission, can, user?.id, scope, scopeLoading, contextAppId, resolvedScope?.appId, selectedOrganisation?.id]);
|
|
3839
|
-
|
|
3756
|
+
}, [baseMenuItems, pageIdMapping, routePermissions, defaultPermission, can, user?.id, scope, scopeLoading, contextAppId, resolvedScope?.appId, selectedOrganisation?.id, selectedEvent?.event_id, appName]);
|
|
3757
|
+
useEffect7(() => {
|
|
3840
3758
|
if (!roleBasedRouting || routeConfig.length === 0) return;
|
|
3841
3759
|
let isMounted = true;
|
|
3842
3760
|
const checkRouteAccess = async () => {
|
|
@@ -3858,7 +3776,7 @@ function PaceAppLayout({
|
|
|
3858
3776
|
let hasAccess = true;
|
|
3859
3777
|
if (currentRoute.pageId && currentRoute.permissions && currentRoute.permissions.length > 0) {
|
|
3860
3778
|
try {
|
|
3861
|
-
const { isPermittedCached } = await import("./api-
|
|
3779
|
+
const { isPermittedCached } = await import("./api-IAGWF3ZG.js");
|
|
3862
3780
|
const hasPagePermission = await isPermittedCached({
|
|
3863
3781
|
userId: user?.id || "",
|
|
3864
3782
|
scope,
|
|
@@ -3874,7 +3792,7 @@ function PaceAppLayout({
|
|
|
3874
3792
|
}
|
|
3875
3793
|
}
|
|
3876
3794
|
if (hasAccess && currentRoute.roles && currentRoute.roles.length > 0 && user?.id) {
|
|
3877
|
-
const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-
|
|
3795
|
+
const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-KAGUYQ4J.js");
|
|
3878
3796
|
hasAccess = true;
|
|
3879
3797
|
}
|
|
3880
3798
|
if (!isMounted) return;
|
|
@@ -3935,37 +3853,37 @@ function PaceAppLayout({
|
|
|
3935
3853
|
}
|
|
3936
3854
|
};
|
|
3937
3855
|
if (user?.id && organisationLoading && !isSuperAdmin2 && !isCheckingSuperAdminDirect && !rbacLoading && !selectedOrganisationId) {
|
|
3938
|
-
return /* @__PURE__ */
|
|
3939
|
-
/* @__PURE__ */
|
|
3940
|
-
/* @__PURE__ */
|
|
3856
|
+
return /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs14("div", { className: "text-center", children: [
|
|
3857
|
+
/* @__PURE__ */ jsx19("div", { className: "animate-spin rounded-full size-8 border-b-2 border-sec-900 mx-auto mb-4" }),
|
|
3858
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sec-600", children: "Loading organisation context..." })
|
|
3941
3859
|
] }) });
|
|
3942
3860
|
}
|
|
3943
3861
|
if (enforcePermissions && isCheckingPermission) {
|
|
3944
|
-
return /* @__PURE__ */
|
|
3945
|
-
/* @__PURE__ */
|
|
3946
|
-
/* @__PURE__ */
|
|
3862
|
+
return /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs14("div", { className: "text-center", children: [
|
|
3863
|
+
/* @__PURE__ */ jsx19("div", { className: "animate-spin rounded-full size-8 border-b-2 border-sec-900 mx-auto mb-4" }),
|
|
3864
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sec-600", children: "Checking permissions..." })
|
|
3947
3865
|
] }) });
|
|
3948
3866
|
}
|
|
3949
3867
|
if (enforcePermissions && permissionError && !isSuperAdmin2) {
|
|
3950
|
-
return /* @__PURE__ */
|
|
3951
|
-
/* @__PURE__ */
|
|
3952
|
-
/* @__PURE__ */
|
|
3953
|
-
/* @__PURE__ */
|
|
3868
|
+
return /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs14("div", { className: "text-center", children: [
|
|
3869
|
+
/* @__PURE__ */ jsx19("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Permission Error" }),
|
|
3870
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sec-600 mb-4", children: permissionError.message }),
|
|
3871
|
+
/* @__PURE__ */ jsx19(Button, { onClick: () => navigate("/"), children: "Go Home" })
|
|
3954
3872
|
] }) });
|
|
3955
3873
|
}
|
|
3956
3874
|
if (enforcePermissions && hasPermission === false && !isCheckingSuperAdminDirect && !isSuperAdmin2) {
|
|
3957
3875
|
if (enforcePagePermissions && pagePermissionFallback) {
|
|
3958
|
-
return /* @__PURE__ */
|
|
3876
|
+
return /* @__PURE__ */ jsx19(Fragment9, { children: pagePermissionFallback });
|
|
3959
3877
|
}
|
|
3960
3878
|
if (permissionFallback) {
|
|
3961
|
-
return /* @__PURE__ */
|
|
3879
|
+
return /* @__PURE__ */ jsx19(Fragment9, { children: permissionFallback });
|
|
3962
3880
|
}
|
|
3963
|
-
return /* @__PURE__ */
|
|
3964
|
-
/* @__PURE__ */
|
|
3965
|
-
/* @__PURE__ */
|
|
3966
|
-
/* @__PURE__ */
|
|
3967
|
-
/* @__PURE__ */
|
|
3968
|
-
/* @__PURE__ */
|
|
3881
|
+
return /* @__PURE__ */ jsx19("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs14("div", { className: "text-center", children: [
|
|
3882
|
+
/* @__PURE__ */ jsx19("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Access Denied" }),
|
|
3883
|
+
/* @__PURE__ */ jsx19("p", { className: "text-sec-600 mb-4", children: "You don't have permission to access this page." }),
|
|
3884
|
+
/* @__PURE__ */ jsxs14("div", { className: "flex gap-2 justify-center", children: [
|
|
3885
|
+
/* @__PURE__ */ jsx19(Button, { onClick: () => navigate("/"), children: "Go Home" }),
|
|
3886
|
+
/* @__PURE__ */ jsx19(
|
|
3969
3887
|
Button,
|
|
3970
3888
|
{
|
|
3971
3889
|
variant: "outline",
|
|
@@ -3979,8 +3897,8 @@ function PaceAppLayout({
|
|
|
3979
3897
|
] })
|
|
3980
3898
|
] }) });
|
|
3981
3899
|
}
|
|
3982
|
-
return /* @__PURE__ */
|
|
3983
|
-
/* @__PURE__ */
|
|
3900
|
+
return /* @__PURE__ */ jsxs14(Fragment9, { children: [
|
|
3901
|
+
/* @__PURE__ */ jsx19(
|
|
3984
3902
|
Header,
|
|
3985
3903
|
{
|
|
3986
3904
|
logo: customLogo || void 0,
|
|
@@ -3999,21 +3917,22 @@ function PaceAppLayout({
|
|
|
3999
3917
|
navigate(item.href);
|
|
4000
3918
|
}
|
|
4001
3919
|
},
|
|
4002
|
-
|
|
4003
|
-
|
|
3920
|
+
showContextSelector,
|
|
3921
|
+
showOrganisations,
|
|
3922
|
+
showEvents,
|
|
4004
3923
|
showUserMenu,
|
|
4005
3924
|
className: headerClassName || "sticky top-0 z-[40] w-full"
|
|
4006
3925
|
}
|
|
4007
3926
|
),
|
|
4008
|
-
/* @__PURE__ */
|
|
4009
|
-
/* @__PURE__ */
|
|
3927
|
+
/* @__PURE__ */ jsx19("main", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: /* @__PURE__ */ jsx19(Outlet, {}) }),
|
|
3928
|
+
/* @__PURE__ */ jsx19(Footer, {})
|
|
4010
3929
|
] });
|
|
4011
3930
|
}
|
|
4012
3931
|
|
|
4013
3932
|
// src/components/PaceLoginPage/PaceLoginPage.tsx
|
|
4014
|
-
import { useEffect as
|
|
3933
|
+
import { useEffect as useEffect8, useState as useState13, useContext as useContext2 } from "react";
|
|
4015
3934
|
import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
|
|
4016
|
-
import { jsx as
|
|
3935
|
+
import { jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
4017
3936
|
var PaceLoginPage = ({
|
|
4018
3937
|
appName = "Pace",
|
|
4019
3938
|
onSuccessRedirectPath = "/",
|
|
@@ -4022,21 +3941,21 @@ var PaceLoginPage = ({
|
|
|
4022
3941
|
const { signIn, isAuthenticated, isLoading, authError, user, supabase } = useUnifiedAuth();
|
|
4023
3942
|
const navigate = useNavigate2();
|
|
4024
3943
|
const location = useLocation2();
|
|
4025
|
-
const [isSigningIn, setIsSigningIn] =
|
|
4026
|
-
const [accessError, setAccessError] =
|
|
4027
|
-
const [isCheckingAccess, setIsCheckingAccess] =
|
|
3944
|
+
const [isSigningIn, setIsSigningIn] = useState13(false);
|
|
3945
|
+
const [accessError, setAccessError] = useState13(null);
|
|
3946
|
+
const [isCheckingAccess, setIsCheckingAccess] = useState13(false);
|
|
4028
3947
|
const eventServiceContext = useContext2(EventServiceContext);
|
|
4029
3948
|
const eventService = eventServiceContext?.eventService || null;
|
|
4030
|
-
|
|
3949
|
+
useEffect8(() => {
|
|
4031
3950
|
clearPalette();
|
|
4032
3951
|
}, []);
|
|
4033
|
-
|
|
3952
|
+
useEffect8(() => {
|
|
4034
3953
|
const isOnLoginPage = location.pathname === "/login" || location.pathname.startsWith("/login");
|
|
4035
3954
|
if (isOnLoginPage) {
|
|
4036
3955
|
clearPalette();
|
|
4037
3956
|
}
|
|
4038
3957
|
}, [location.pathname]);
|
|
4039
|
-
|
|
3958
|
+
useEffect8(() => {
|
|
4040
3959
|
const restoreEvent = async () => {
|
|
4041
3960
|
try {
|
|
4042
3961
|
const isOnLoginPage = window.location.pathname === "/login" || window.location.pathname.startsWith("/login");
|
|
@@ -4051,7 +3970,7 @@ var PaceLoginPage = ({
|
|
|
4051
3970
|
}, 100);
|
|
4052
3971
|
return () => clearTimeout(timeoutId);
|
|
4053
3972
|
}, [eventService]);
|
|
4054
|
-
|
|
3973
|
+
useEffect8(() => {
|
|
4055
3974
|
if (!requireAppAccess || !isAuthenticated || isLoading || !user || !supabase) {
|
|
4056
3975
|
return;
|
|
4057
3976
|
}
|
|
@@ -4139,8 +4058,8 @@ var PaceLoginPage = ({
|
|
|
4139
4058
|
setIsSigningIn(false);
|
|
4140
4059
|
}
|
|
4141
4060
|
};
|
|
4142
|
-
return /* @__PURE__ */
|
|
4143
|
-
/* @__PURE__ */
|
|
4061
|
+
return /* @__PURE__ */ jsxs15("main", { className: "min-h-screen grid mx-auto w-fit content-center justify-items-center gap-y-8", "aria-label": `${appName} Login Page`, children: [
|
|
4062
|
+
/* @__PURE__ */ jsx20(
|
|
4144
4063
|
"img",
|
|
4145
4064
|
{
|
|
4146
4065
|
src: `/${appName.toLowerCase()}_logo_square.svg`,
|
|
@@ -4148,7 +4067,7 @@ var PaceLoginPage = ({
|
|
|
4148
4067
|
className: "h-48"
|
|
4149
4068
|
}
|
|
4150
4069
|
),
|
|
4151
|
-
/* @__PURE__ */
|
|
4070
|
+
/* @__PURE__ */ jsx20(
|
|
4152
4071
|
LoginForm,
|
|
4153
4072
|
{
|
|
4154
4073
|
className: "w-md",
|
|
@@ -4162,20 +4081,20 @@ var PaceLoginPage = ({
|
|
|
4162
4081
|
),
|
|
4163
4082
|
(() => {
|
|
4164
4083
|
const benign = !!(authError && (authError.name === "AuthSessionMissingError" || /Auth session missing/i.test(authError.message)));
|
|
4165
|
-
return authError && !benign ? /* @__PURE__ */
|
|
4084
|
+
return authError && !benign ? /* @__PURE__ */ jsx20("em", { className: "mt-4 text-destructive text-center", children: authError.message }) : null;
|
|
4166
4085
|
})(),
|
|
4167
|
-
accessError && /* @__PURE__ */
|
|
4168
|
-
isCheckingAccess && /* @__PURE__ */
|
|
4086
|
+
accessError && /* @__PURE__ */ jsx20("em", { className: "mt-4 text-destructive text-center", children: accessError }),
|
|
4087
|
+
isCheckingAccess && /* @__PURE__ */ jsx20("em", { className: "mt-4 text-muted-foreground text-center", children: "Checking permissions..." })
|
|
4169
4088
|
] });
|
|
4170
4089
|
};
|
|
4171
4090
|
|
|
4172
4091
|
// src/components/SessionRestorationLoader/SessionRestorationLoader.tsx
|
|
4173
|
-
import { jsx as
|
|
4092
|
+
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
4174
4093
|
var SessionRestorationLoader = ({
|
|
4175
4094
|
message = "Restoring session...",
|
|
4176
4095
|
className
|
|
4177
4096
|
}) => {
|
|
4178
|
-
return /* @__PURE__ */
|
|
4097
|
+
return /* @__PURE__ */ jsxs16(
|
|
4179
4098
|
Alert,
|
|
4180
4099
|
{
|
|
4181
4100
|
className: cn(
|
|
@@ -4186,17 +4105,17 @@ var SessionRestorationLoader = ({
|
|
|
4186
4105
|
"aria-live": "polite",
|
|
4187
4106
|
"aria-label": message,
|
|
4188
4107
|
children: [
|
|
4189
|
-
/* @__PURE__ */
|
|
4190
|
-
/* @__PURE__ */
|
|
4108
|
+
/* @__PURE__ */ jsx21(LoadingSpinner, { size: "lg" }),
|
|
4109
|
+
/* @__PURE__ */ jsx21("span", { className: "text-sm text-sec-600", children: message })
|
|
4191
4110
|
]
|
|
4192
4111
|
}
|
|
4193
4112
|
);
|
|
4194
4113
|
};
|
|
4195
4114
|
|
|
4196
4115
|
// src/components/ProtectedRoute/ProtectedRoute.tsx
|
|
4197
|
-
import { useMemo as
|
|
4116
|
+
import { useMemo as useMemo9, useEffect as useEffect9, useRef as useRef8, useState as useState14 } from "react";
|
|
4198
4117
|
import { Navigate, Outlet as Outlet2 } from "react-router-dom";
|
|
4199
|
-
import { jsx as
|
|
4118
|
+
import { jsx as jsx22, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
4200
4119
|
function ProtectedRoute({
|
|
4201
4120
|
requireEvent = false,
|
|
4202
4121
|
noEventsFallback,
|
|
@@ -4210,17 +4129,17 @@ function ProtectedRoute({
|
|
|
4210
4129
|
const eventLoading = requireEvent ? eventsContext.isLoading || false : false;
|
|
4211
4130
|
const sessionRestoration = useSessionRestoration();
|
|
4212
4131
|
usePreventTabReload({ enabled: true, gracePeriodMs: 2e3 });
|
|
4213
|
-
const wasAuthenticatedRef =
|
|
4214
|
-
const [shouldRedirect, setShouldRedirect] =
|
|
4215
|
-
const tabJustBecameVisibleRef =
|
|
4216
|
-
|
|
4132
|
+
const wasAuthenticatedRef = useRef8(false);
|
|
4133
|
+
const [shouldRedirect, setShouldRedirect] = useState14(false);
|
|
4134
|
+
const tabJustBecameVisibleRef = useRef8(false);
|
|
4135
|
+
useEffect9(() => {
|
|
4217
4136
|
if (isAuthenticated) {
|
|
4218
4137
|
wasAuthenticatedRef.current = true;
|
|
4219
4138
|
setShouldRedirect(false);
|
|
4220
4139
|
tabJustBecameVisibleRef.current = false;
|
|
4221
4140
|
}
|
|
4222
4141
|
}, [isAuthenticated]);
|
|
4223
|
-
|
|
4142
|
+
useEffect9(() => {
|
|
4224
4143
|
if (typeof document === "undefined") return;
|
|
4225
4144
|
let timeoutId = null;
|
|
4226
4145
|
let wasHidden = document.hidden;
|
|
@@ -4264,13 +4183,13 @@ function ProtectedRoute({
|
|
|
4264
4183
|
}
|
|
4265
4184
|
};
|
|
4266
4185
|
}, [isAuthenticated]);
|
|
4267
|
-
|
|
4186
|
+
useEffect9(() => {
|
|
4268
4187
|
if (isAuthenticated) {
|
|
4269
4188
|
setShouldRedirect(false);
|
|
4270
4189
|
tabJustBecameVisibleRef.current = false;
|
|
4271
4190
|
}
|
|
4272
4191
|
}, [isAuthenticated]);
|
|
4273
|
-
const isRestoringSession =
|
|
4192
|
+
const isRestoringSession = useMemo9(() => {
|
|
4274
4193
|
return sessionRestoration.isRestoring && !sessionRestoration.restorationComplete && !sessionRestoration.restorationError && !sessionRestoration.hasTimedOut;
|
|
4275
4194
|
}, [
|
|
4276
4195
|
sessionRestoration.isRestoring,
|
|
@@ -4279,13 +4198,13 @@ function ProtectedRoute({
|
|
|
4279
4198
|
sessionRestoration.hasTimedOut
|
|
4280
4199
|
]);
|
|
4281
4200
|
if (isRestoringSession) {
|
|
4282
|
-
return /* @__PURE__ */
|
|
4201
|
+
return /* @__PURE__ */ jsx22(SessionRestorationLoader, {});
|
|
4283
4202
|
}
|
|
4284
4203
|
if (requireEvent && eventLoading) {
|
|
4285
|
-
return /* @__PURE__ */
|
|
4204
|
+
return /* @__PURE__ */ jsx22(Outlet2, {});
|
|
4286
4205
|
}
|
|
4287
4206
|
if (isLoading && !sessionRestoration.hasTimedOut) {
|
|
4288
|
-
return loadingFallback || /* @__PURE__ */
|
|
4207
|
+
return loadingFallback || /* @__PURE__ */ jsx22("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx22(LoadingSpinner, {}) });
|
|
4289
4208
|
}
|
|
4290
4209
|
if (!isAuthenticated) {
|
|
4291
4210
|
if (sessionRestoration.hasTimedOut || sessionRestoration.restorationError) {
|
|
@@ -4293,41 +4212,41 @@ function ProtectedRoute({
|
|
|
4293
4212
|
timedOut: sessionRestoration.hasTimedOut,
|
|
4294
4213
|
error: sessionRestoration.restorationError?.message
|
|
4295
4214
|
});
|
|
4296
|
-
return /* @__PURE__ */
|
|
4215
|
+
return /* @__PURE__ */ jsx22(Navigate, { to: loginPath, replace: true });
|
|
4297
4216
|
}
|
|
4298
4217
|
if (!wasAuthenticatedRef.current) {
|
|
4299
|
-
return /* @__PURE__ */
|
|
4218
|
+
return /* @__PURE__ */ jsx22(Navigate, { to: loginPath, replace: true });
|
|
4300
4219
|
}
|
|
4301
4220
|
const isTabVisible = typeof document !== "undefined" && !document.hidden;
|
|
4302
4221
|
if (tabJustBecameVisibleRef.current || isTabVisible && wasAuthenticatedRef.current && isLoading) {
|
|
4303
|
-
return loadingFallback || /* @__PURE__ */
|
|
4222
|
+
return loadingFallback || /* @__PURE__ */ jsx22("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx22(LoadingSpinner, {}) });
|
|
4304
4223
|
}
|
|
4305
4224
|
if (shouldRedirect) {
|
|
4306
|
-
return /* @__PURE__ */
|
|
4225
|
+
return /* @__PURE__ */ jsx22(Navigate, { to: loginPath, replace: true });
|
|
4307
4226
|
}
|
|
4308
4227
|
if (isLoading) {
|
|
4309
|
-
return loadingFallback || /* @__PURE__ */
|
|
4228
|
+
return loadingFallback || /* @__PURE__ */ jsx22("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx22(LoadingSpinner, {}) });
|
|
4310
4229
|
}
|
|
4311
|
-
return /* @__PURE__ */
|
|
4230
|
+
return /* @__PURE__ */ jsx22(Navigate, { to: loginPath, replace: true });
|
|
4312
4231
|
}
|
|
4313
4232
|
if (!requireEvent) {
|
|
4314
|
-
return /* @__PURE__ */
|
|
4233
|
+
return /* @__PURE__ */ jsx22(Outlet2, {});
|
|
4315
4234
|
}
|
|
4316
4235
|
if (!events || events.length === 0) {
|
|
4317
|
-
return noEventsFallback || /* @__PURE__ */
|
|
4318
|
-
/* @__PURE__ */
|
|
4319
|
-
/* @__PURE__ */
|
|
4236
|
+
return noEventsFallback || /* @__PURE__ */ jsx22("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "100vh", padding: "2rem" }, children: /* @__PURE__ */ jsxs17(Alert, { variant: "destructive", className: "max-w-md", children: [
|
|
4237
|
+
/* @__PURE__ */ jsx22(AlertTitle, { children: "No Events Available" }),
|
|
4238
|
+
/* @__PURE__ */ jsx22(AlertDescription, { children: "You don't have access to any events. Please contact your administrator if you believe this is an error." })
|
|
4320
4239
|
] }) });
|
|
4321
4240
|
}
|
|
4322
4241
|
if (!selectedEvent) {
|
|
4323
|
-
return /* @__PURE__ */
|
|
4242
|
+
return /* @__PURE__ */ jsx22(Outlet2, {});
|
|
4324
4243
|
}
|
|
4325
|
-
return /* @__PURE__ */
|
|
4244
|
+
return /* @__PURE__ */ jsx22(Outlet2, {});
|
|
4326
4245
|
}
|
|
4327
4246
|
|
|
4328
4247
|
// src/components/FileUpload/FileUpload.tsx
|
|
4329
|
-
import { useState as
|
|
4330
|
-
import { Fragment as
|
|
4248
|
+
import { useState as useState15, useCallback as useCallback10, useRef as useRef9, useEffect as useEffect10, useMemo as useMemo10 } from "react";
|
|
4249
|
+
import { Fragment as Fragment10, jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4331
4250
|
function FileUpload({
|
|
4332
4251
|
supabase,
|
|
4333
4252
|
table_name,
|
|
@@ -4360,14 +4279,14 @@ function FileUpload({
|
|
|
4360
4279
|
}
|
|
4361
4280
|
throw new Error(errorMsg);
|
|
4362
4281
|
}
|
|
4363
|
-
const [isDragging, setIsDragging] =
|
|
4364
|
-
const [uploadStates, setUploadStates] =
|
|
4365
|
-
const [resolvedAppId, setResolvedAppId] =
|
|
4366
|
-
const [isResolvingAppId, setIsResolvingAppId] =
|
|
4367
|
-
const [appIdError, setAppIdError] =
|
|
4368
|
-
const fileInputRef =
|
|
4282
|
+
const [isDragging, setIsDragging] = useState15(false);
|
|
4283
|
+
const [uploadStates, setUploadStates] = useState15(/* @__PURE__ */ new Map());
|
|
4284
|
+
const [resolvedAppId, setResolvedAppId] = useState15(app_id || null);
|
|
4285
|
+
const [isResolvingAppId, setIsResolvingAppId] = useState15(!app_id);
|
|
4286
|
+
const [appIdError, setAppIdError] = useState15(null);
|
|
4287
|
+
const fileInputRef = useRef9(null);
|
|
4369
4288
|
const { uploadFile, isLoading, error } = useFileReference(supabase);
|
|
4370
|
-
|
|
4289
|
+
useEffect10(() => {
|
|
4371
4290
|
if (app_id) {
|
|
4372
4291
|
setResolvedAppId(app_id);
|
|
4373
4292
|
setIsResolvingAppId(false);
|
|
@@ -4402,15 +4321,15 @@ function FileUpload({
|
|
|
4402
4321
|
};
|
|
4403
4322
|
resolveAppId();
|
|
4404
4323
|
}, [app_id, supabase]);
|
|
4405
|
-
const isUploading =
|
|
4324
|
+
const isUploading = useMemo10(() => {
|
|
4406
4325
|
return uploadStates.size > 0 && Array.from(uploadStates.values()).some(
|
|
4407
4326
|
(state) => state.progress.status === "uploading" || state.progress.status === "processing"
|
|
4408
4327
|
);
|
|
4409
4328
|
}, [uploadStates]);
|
|
4410
|
-
const isDisabled =
|
|
4329
|
+
const isDisabled = useMemo10(() => {
|
|
4411
4330
|
return disabled || isUploading || isResolvingAppId || !resolvedAppId;
|
|
4412
4331
|
}, [disabled, isUploading, isResolvingAppId, resolvedAppId]);
|
|
4413
|
-
const generatePreview =
|
|
4332
|
+
const generatePreview = useCallback10((file) => {
|
|
4414
4333
|
return new Promise((resolve) => {
|
|
4415
4334
|
if (!file.type.startsWith("image/")) {
|
|
4416
4335
|
resolve(null);
|
|
@@ -4424,7 +4343,7 @@ function FileUpload({
|
|
|
4424
4343
|
reader.readAsDataURL(file);
|
|
4425
4344
|
});
|
|
4426
4345
|
}, []);
|
|
4427
|
-
const validateFile =
|
|
4346
|
+
const validateFile = useCallback10((file) => {
|
|
4428
4347
|
if (file.size > maxSize) {
|
|
4429
4348
|
return `File "${file.name}" exceeds maximum size of ${Math.round(maxSize / 1024 / 1024)}MB`;
|
|
4430
4349
|
}
|
|
@@ -4448,7 +4367,7 @@ function FileUpload({
|
|
|
4448
4367
|
}
|
|
4449
4368
|
return null;
|
|
4450
4369
|
}, [accept, maxSize]);
|
|
4451
|
-
const handleFileSelect =
|
|
4370
|
+
const handleFileSelect = useCallback10(async (files) => {
|
|
4452
4371
|
if (!files || files.length === 0) return;
|
|
4453
4372
|
const fileArray = Array.from(files);
|
|
4454
4373
|
const validationErrors = [];
|
|
@@ -4629,19 +4548,19 @@ function FileUpload({
|
|
|
4629
4548
|
}
|
|
4630
4549
|
}
|
|
4631
4550
|
}, [uploadFile, table_name, record_id, organisation_id, resolvedAppId, category, folder, isPublic, maxSize, onUploadSuccess, onUploadError, onProgress, validateFile, generatePreview, showPreview, appIdError, pageContext]);
|
|
4632
|
-
const handleDragOver =
|
|
4551
|
+
const handleDragOver = useCallback10((e) => {
|
|
4633
4552
|
e.preventDefault();
|
|
4634
4553
|
e.stopPropagation();
|
|
4635
4554
|
if (!isDisabled) {
|
|
4636
4555
|
setIsDragging(true);
|
|
4637
4556
|
}
|
|
4638
4557
|
}, [isDisabled]);
|
|
4639
|
-
const handleDragLeave =
|
|
4558
|
+
const handleDragLeave = useCallback10((e) => {
|
|
4640
4559
|
e.preventDefault();
|
|
4641
4560
|
e.stopPropagation();
|
|
4642
4561
|
setIsDragging(false);
|
|
4643
4562
|
}, []);
|
|
4644
|
-
const handleDrop =
|
|
4563
|
+
const handleDrop = useCallback10((e) => {
|
|
4645
4564
|
e.preventDefault();
|
|
4646
4565
|
e.stopPropagation();
|
|
4647
4566
|
setIsDragging(false);
|
|
@@ -4649,13 +4568,13 @@ function FileUpload({
|
|
|
4649
4568
|
const files = e.dataTransfer.files;
|
|
4650
4569
|
handleFileSelect(files);
|
|
4651
4570
|
}, [isDisabled, handleFileSelect]);
|
|
4652
|
-
const handleFileInputChange =
|
|
4571
|
+
const handleFileInputChange = useCallback10((e) => {
|
|
4653
4572
|
handleFileSelect(e.target.files);
|
|
4654
4573
|
if (e.target) {
|
|
4655
4574
|
e.target.value = "";
|
|
4656
4575
|
}
|
|
4657
4576
|
}, [handleFileSelect]);
|
|
4658
|
-
const handleClick =
|
|
4577
|
+
const handleClick = useCallback10(() => {
|
|
4659
4578
|
if (!isDisabled && fileInputRef.current) {
|
|
4660
4579
|
fileInputRef.current.click();
|
|
4661
4580
|
}
|
|
@@ -4669,8 +4588,8 @@ function FileUpload({
|
|
|
4669
4588
|
};
|
|
4670
4589
|
const dragClasses = isDragging ? "border-main-500 bg-main-50" : "border-sec-300 hover:border-sec-400";
|
|
4671
4590
|
const disabledClasses = isDisabled ? "opacity-50 cursor-not-allowed" : "cursor-pointer hover:bg-sec-50";
|
|
4672
|
-
return /* @__PURE__ */
|
|
4673
|
-
/* @__PURE__ */
|
|
4591
|
+
return /* @__PURE__ */ jsxs18("div", { className: `space-y-4 ${className}`, children: [
|
|
4592
|
+
/* @__PURE__ */ jsxs18(
|
|
4674
4593
|
"div",
|
|
4675
4594
|
{
|
|
4676
4595
|
role: "button",
|
|
@@ -4689,8 +4608,8 @@ function FileUpload({
|
|
|
4689
4608
|
}
|
|
4690
4609
|
} : void 0,
|
|
4691
4610
|
children: [
|
|
4692
|
-
children || /* @__PURE__ */
|
|
4693
|
-
/* @__PURE__ */
|
|
4611
|
+
children || /* @__PURE__ */ jsxs18("div", { className: "space-y-2", children: [
|
|
4612
|
+
/* @__PURE__ */ jsx23(
|
|
4694
4613
|
"input",
|
|
4695
4614
|
{
|
|
4696
4615
|
ref: fileInputRef,
|
|
@@ -4704,64 +4623,64 @@ function FileUpload({
|
|
|
4704
4623
|
"aria-label": accept ? `Upload file${multiple ? "s" : ""} (${accept})` : `Upload file${multiple ? "s" : ""}`
|
|
4705
4624
|
}
|
|
4706
4625
|
),
|
|
4707
|
-
/* @__PURE__ */
|
|
4708
|
-
/* @__PURE__ */
|
|
4626
|
+
/* @__PURE__ */ jsx23("div", { className: "text-sec-600", children: isResolvingAppId ? "Resolving app configuration..." : isDragging ? "Drop files here..." : /* @__PURE__ */ jsxs18(Fragment10, { children: [
|
|
4627
|
+
/* @__PURE__ */ jsx23("span", { className: "font-medium", children: "Click to upload" }),
|
|
4709
4628
|
" ",
|
|
4710
4629
|
"or drag and drop"
|
|
4711
4630
|
] }) }),
|
|
4712
|
-
/* @__PURE__ */
|
|
4631
|
+
/* @__PURE__ */ jsxs18("div", { className: "text-sm text-sec-500", children: [
|
|
4713
4632
|
!isResolvingAppId && accept !== "*/*" && `Accepted formats: ${accept}`,
|
|
4714
4633
|
!isResolvingAppId && maxSize && ` \u2022 Max size: ${Math.round(maxSize / 1024 / 1024)}MB`,
|
|
4715
4634
|
!isResolvingAppId && multiple && " \u2022 Multiple files allowed"
|
|
4716
4635
|
] })
|
|
4717
4636
|
] }),
|
|
4718
|
-
isUploading && !showProgress && /* @__PURE__ */
|
|
4637
|
+
isUploading && !showProgress && /* @__PURE__ */ jsx23(
|
|
4719
4638
|
"div",
|
|
4720
4639
|
{
|
|
4721
4640
|
className: "absolute inset-0 bg-white bg-opacity-75 flex items-center justify-center",
|
|
4722
4641
|
role: "status",
|
|
4723
4642
|
"aria-live": "polite",
|
|
4724
4643
|
"aria-label": "Uploading file",
|
|
4725
|
-
children: /* @__PURE__ */
|
|
4644
|
+
children: /* @__PURE__ */ jsx23("div", { className: "animate-spin rounded-full size-8 border-b-2 border-main-500", "aria-hidden": "true" })
|
|
4726
4645
|
}
|
|
4727
4646
|
)
|
|
4728
4647
|
]
|
|
4729
4648
|
}
|
|
4730
4649
|
),
|
|
4731
|
-
showProgress && uploadStates.size > 0 && /* @__PURE__ */
|
|
4650
|
+
showProgress && uploadStates.size > 0 && /* @__PURE__ */ jsx23("div", { className: "space-y-2", children: Array.from(uploadStates.entries()).map(([fileId, uploadState]) => {
|
|
4732
4651
|
const { file, progress, preview, result } = uploadState;
|
|
4733
4652
|
const isError = progress.status === "error";
|
|
4734
4653
|
const isCompleted = progress.status === "completed";
|
|
4735
4654
|
const isUploading2 = progress.status === "uploading" || progress.status === "processing";
|
|
4736
|
-
return /* @__PURE__ */
|
|
4655
|
+
return /* @__PURE__ */ jsxs18(
|
|
4737
4656
|
"div",
|
|
4738
4657
|
{
|
|
4739
4658
|
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"}`,
|
|
4740
4659
|
children: [
|
|
4741
|
-
/* @__PURE__ */
|
|
4660
|
+
/* @__PURE__ */ jsx23("div", { className: "flex-shrink-0", children: preview ? /* @__PURE__ */ jsx23(
|
|
4742
4661
|
"img",
|
|
4743
4662
|
{
|
|
4744
4663
|
src: preview,
|
|
4745
4664
|
alt: file.name,
|
|
4746
4665
|
className: "w-12 h-12 object-cover rounded"
|
|
4747
4666
|
}
|
|
4748
|
-
) : /* @__PURE__ */
|
|
4749
|
-
/* @__PURE__ */
|
|
4750
|
-
/* @__PURE__ */
|
|
4751
|
-
/* @__PURE__ */
|
|
4667
|
+
) : /* @__PURE__ */ jsx23("div", { className: "w-12 h-12 flex items-center justify-center bg-sec-200 rounded", children: /* @__PURE__ */ jsx23("span", { className: "text-2xl", children: "\u{1F4C4}" }) }) }),
|
|
4668
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex-1 min-w-0", children: [
|
|
4669
|
+
/* @__PURE__ */ jsx23("div", { className: "font-medium text-sec-900 truncate", children: file.name }),
|
|
4670
|
+
/* @__PURE__ */ jsxs18("div", { className: "text-sm text-sec-500", children: [
|
|
4752
4671
|
formatFileSize(file.size),
|
|
4753
4672
|
isCompleted && result && " \u2022 Uploaded",
|
|
4754
4673
|
isError && progress.error && ` \u2022 ${progress.error}`
|
|
4755
4674
|
] }),
|
|
4756
|
-
showProgress && (isUploading2 || isError) && /* @__PURE__ */
|
|
4757
|
-
/* @__PURE__ */
|
|
4675
|
+
showProgress && (isUploading2 || isError) && /* @__PURE__ */ jsxs18("div", { className: "mt-2", children: [
|
|
4676
|
+
/* @__PURE__ */ jsx23("div", { className: "w-full bg-sec-200 rounded-full h-2", children: /* @__PURE__ */ jsx23(
|
|
4758
4677
|
"div",
|
|
4759
4678
|
{
|
|
4760
4679
|
className: `h-2 rounded-full transition-all duration-300 ${isError ? "bg-acc-500" : "bg-main-500"}`,
|
|
4761
4680
|
style: { width: `${progress.percentage}%` }
|
|
4762
4681
|
}
|
|
4763
4682
|
) }),
|
|
4764
|
-
isUploading2 && /* @__PURE__ */
|
|
4683
|
+
isUploading2 && /* @__PURE__ */ jsxs18("div", { className: "text-xs text-sec-500 mt-1", children: [
|
|
4765
4684
|
progress.percentage,
|
|
4766
4685
|
"% \u2022 ",
|
|
4767
4686
|
formatFileSize(progress.loaded),
|
|
@@ -4770,10 +4689,10 @@ function FileUpload({
|
|
|
4770
4689
|
] })
|
|
4771
4690
|
] })
|
|
4772
4691
|
] }),
|
|
4773
|
-
/* @__PURE__ */
|
|
4774
|
-
isCompleted && /* @__PURE__ */
|
|
4775
|
-
isError && /* @__PURE__ */
|
|
4776
|
-
isUploading2 && /* @__PURE__ */
|
|
4692
|
+
/* @__PURE__ */ jsxs18("div", { className: "flex-shrink-0", children: [
|
|
4693
|
+
isCompleted && /* @__PURE__ */ jsx23("span", { className: "text-success-500 text-xl", children: "\u2713" }),
|
|
4694
|
+
isError && /* @__PURE__ */ jsx23("span", { className: "text-acc-500 text-xl", children: "\u2715" }),
|
|
4695
|
+
isUploading2 && /* @__PURE__ */ jsx23(
|
|
4777
4696
|
"div",
|
|
4778
4697
|
{
|
|
4779
4698
|
className: "animate-spin rounded-full size-5 border-b-2 border-main-500",
|
|
@@ -4788,7 +4707,7 @@ function FileUpload({
|
|
|
4788
4707
|
fileId
|
|
4789
4708
|
);
|
|
4790
4709
|
}) }),
|
|
4791
|
-
appIdError && /* @__PURE__ */
|
|
4710
|
+
appIdError && /* @__PURE__ */ jsx23(
|
|
4792
4711
|
"div",
|
|
4793
4712
|
{
|
|
4794
4713
|
className: "p-3 bg-acc-50 border border-acc-200 rounded-lg text-sm text-acc-600",
|
|
@@ -4797,7 +4716,7 @@ function FileUpload({
|
|
|
4797
4716
|
children: appIdError
|
|
4798
4717
|
}
|
|
4799
4718
|
),
|
|
4800
|
-
error && /* @__PURE__ */
|
|
4719
|
+
error && /* @__PURE__ */ jsx23(
|
|
4801
4720
|
"div",
|
|
4802
4721
|
{
|
|
4803
4722
|
className: "p-3 bg-acc-50 border border-acc-200 rounded-lg text-sm text-acc-600",
|
|
@@ -4811,8 +4730,8 @@ function FileUpload({
|
|
|
4811
4730
|
|
|
4812
4731
|
// src/components/Table/Table.tsx
|
|
4813
4732
|
import * as React20 from "react";
|
|
4814
|
-
import { jsx as
|
|
4815
|
-
var Table = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4733
|
+
import { jsx as jsx24 } from "react/jsx-runtime";
|
|
4734
|
+
var Table = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
4816
4735
|
"table",
|
|
4817
4736
|
{
|
|
4818
4737
|
ref,
|
|
@@ -4821,9 +4740,9 @@ var Table = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
4821
4740
|
}
|
|
4822
4741
|
));
|
|
4823
4742
|
Table.displayName = "Table";
|
|
4824
|
-
var TableHeader = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4743
|
+
var TableHeader = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
|
|
4825
4744
|
TableHeader.displayName = "TableHeader";
|
|
4826
|
-
var TableBody = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4745
|
+
var TableBody = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
4827
4746
|
"tbody",
|
|
4828
4747
|
{
|
|
4829
4748
|
ref,
|
|
@@ -4832,7 +4751,7 @@ var TableBody = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
4832
4751
|
}
|
|
4833
4752
|
));
|
|
4834
4753
|
TableBody.displayName = "TableBody";
|
|
4835
|
-
var TableFooter = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4754
|
+
var TableFooter = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
4836
4755
|
"tfoot",
|
|
4837
4756
|
{
|
|
4838
4757
|
ref,
|
|
@@ -4844,7 +4763,7 @@ var TableFooter = React20.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
4844
4763
|
}
|
|
4845
4764
|
));
|
|
4846
4765
|
TableFooter.displayName = "TableFooter";
|
|
4847
|
-
var TableRow = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4766
|
+
var TableRow = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
4848
4767
|
"tr",
|
|
4849
4768
|
{
|
|
4850
4769
|
ref,
|
|
@@ -4856,7 +4775,7 @@ var TableRow = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
4856
4775
|
}
|
|
4857
4776
|
));
|
|
4858
4777
|
TableRow.displayName = "TableRow";
|
|
4859
|
-
var TableHead = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4778
|
+
var TableHead = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
4860
4779
|
"th",
|
|
4861
4780
|
{
|
|
4862
4781
|
ref,
|
|
@@ -4868,7 +4787,7 @@ var TableHead = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
4868
4787
|
}
|
|
4869
4788
|
));
|
|
4870
4789
|
TableHead.displayName = "TableHead";
|
|
4871
|
-
var TableCell = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4790
|
+
var TableCell = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
4872
4791
|
"td",
|
|
4873
4792
|
{
|
|
4874
4793
|
ref,
|
|
@@ -4877,7 +4796,7 @@ var TableCell = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
4877
4796
|
}
|
|
4878
4797
|
));
|
|
4879
4798
|
TableCell.displayName = "TableCell";
|
|
4880
|
-
var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
4799
|
+
var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx24(
|
|
4881
4800
|
"caption",
|
|
4882
4801
|
{
|
|
4883
4802
|
ref,
|
|
@@ -4888,7 +4807,7 @@ var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
4888
4807
|
TableCaption.displayName = "TableCaption";
|
|
4889
4808
|
|
|
4890
4809
|
// src/components/PublicLayout/PublicPageLayout.tsx
|
|
4891
|
-
import { Fragment as
|
|
4810
|
+
import { Fragment as Fragment11, jsx as jsx25, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4892
4811
|
function PublicPageHeader({
|
|
4893
4812
|
event,
|
|
4894
4813
|
eventCode,
|
|
@@ -4901,11 +4820,11 @@ function PublicPageHeader({
|
|
|
4901
4820
|
customEventLogo
|
|
4902
4821
|
}) {
|
|
4903
4822
|
const { appName } = useAppConfig();
|
|
4904
|
-
return /* @__PURE__ */
|
|
4823
|
+
return /* @__PURE__ */ jsxs19("header", { className: cn(
|
|
4905
4824
|
"w-full px-[max(0rem,calc((100vw-var(--app-width))/2-0.5rem))] grid grid-cols-[auto_1fr_auto] place-items-center gap-2",
|
|
4906
4825
|
className
|
|
4907
4826
|
), children: [
|
|
4908
|
-
showAppLogo && appName && /* @__PURE__ */
|
|
4827
|
+
showAppLogo && appName && /* @__PURE__ */ jsx25(
|
|
4909
4828
|
"img",
|
|
4910
4829
|
{
|
|
4911
4830
|
className: "ml-4 max-w-36 object-contain row-span-2",
|
|
@@ -4913,9 +4832,9 @@ function PublicPageHeader({
|
|
|
4913
4832
|
alt: appName
|
|
4914
4833
|
}
|
|
4915
4834
|
),
|
|
4916
|
-
event && /* @__PURE__ */
|
|
4917
|
-
/* @__PURE__ */
|
|
4918
|
-
showEventLogo && event && /* @__PURE__ */
|
|
4835
|
+
event && /* @__PURE__ */ jsxs19(Fragment11, { children: [
|
|
4836
|
+
/* @__PURE__ */ jsx25("h1", { children: event.event_name }),
|
|
4837
|
+
showEventLogo && event && /* @__PURE__ */ jsx25(Fragment11, { children: customEventLogo || /* @__PURE__ */ jsx25(
|
|
4919
4838
|
FileDisplay,
|
|
4920
4839
|
{
|
|
4921
4840
|
table_name: "event",
|
|
@@ -4932,13 +4851,13 @@ function PublicPageHeader({
|
|
|
4932
4851
|
}
|
|
4933
4852
|
}
|
|
4934
4853
|
) }),
|
|
4935
|
-
event.event_venue && /* @__PURE__ */
|
|
4854
|
+
event.event_venue && /* @__PURE__ */ jsx25("h4", { children: event.event_venue })
|
|
4936
4855
|
] }),
|
|
4937
|
-
title && /* @__PURE__ */
|
|
4938
|
-
/* @__PURE__ */
|
|
4939
|
-
description && /* @__PURE__ */
|
|
4856
|
+
title && /* @__PURE__ */ jsxs19(Fragment11, { children: [
|
|
4857
|
+
/* @__PURE__ */ jsx25("h1", { children: title }),
|
|
4858
|
+
description && /* @__PURE__ */ jsx25("p", { className: "text-lg text-sec-600 max-w-3xl mx-auto", children: description })
|
|
4940
4859
|
] }),
|
|
4941
|
-
children && /* @__PURE__ */
|
|
4860
|
+
children && /* @__PURE__ */ jsx25(Fragment11, { children })
|
|
4942
4861
|
] });
|
|
4943
4862
|
}
|
|
4944
4863
|
function PublicPageFooter({
|
|
@@ -4952,11 +4871,11 @@ function PublicPageFooter({
|
|
|
4952
4871
|
children
|
|
4953
4872
|
}) {
|
|
4954
4873
|
const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
|
|
4955
|
-
return /* @__PURE__ */
|
|
4956
|
-
logo && /* @__PURE__ */
|
|
4957
|
-
children && /* @__PURE__ */
|
|
4958
|
-
/* @__PURE__ */
|
|
4959
|
-
links && links.length > 0 && /* @__PURE__ */
|
|
4874
|
+
return /* @__PURE__ */ jsx25("footer", { className: cn("mt-8 py-6 flex justify-center", className), children: /* @__PURE__ */ jsxs19("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
|
|
4875
|
+
logo && /* @__PURE__ */ jsx25("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
|
|
4876
|
+
children && /* @__PURE__ */ jsx25(Fragment11, { children }),
|
|
4877
|
+
/* @__PURE__ */ jsx25("span", { className: "text-muted-foreground", children: copyrightText }),
|
|
4878
|
+
links && links.length > 0 && /* @__PURE__ */ jsx25("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx25("li", { children: /* @__PURE__ */ jsx25("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
|
|
4960
4879
|
] }) });
|
|
4961
4880
|
}
|
|
4962
4881
|
function PublicPageLayout({
|
|
@@ -4979,44 +4898,44 @@ function PublicPageLayout({
|
|
|
4979
4898
|
});
|
|
4980
4899
|
if (isLoading) {
|
|
4981
4900
|
if (LoadingFallback) {
|
|
4982
|
-
return /* @__PURE__ */
|
|
4901
|
+
return /* @__PURE__ */ jsx25(LoadingFallback, {});
|
|
4983
4902
|
}
|
|
4984
|
-
return /* @__PURE__ */
|
|
4985
|
-
/* @__PURE__ */
|
|
4986
|
-
loadingMessage && /* @__PURE__ */
|
|
4903
|
+
return /* @__PURE__ */ jsx25("div", { className: "min-h-screen bg-background flex items-center justify-center", children: /* @__PURE__ */ jsxs19("div", { className: "max-w-md mx-auto text-center px-4", children: [
|
|
4904
|
+
/* @__PURE__ */ jsx25(LoadingSpinner, { size: "lg", className: "mx-auto mb-4" }),
|
|
4905
|
+
loadingMessage && /* @__PURE__ */ jsx25("p", { className: "text-sec-600", children: loadingMessage })
|
|
4987
4906
|
] }) });
|
|
4988
4907
|
}
|
|
4989
4908
|
if (error && showValidationErrors) {
|
|
4990
4909
|
if (ErrorFallback) {
|
|
4991
|
-
return /* @__PURE__ */
|
|
4910
|
+
return /* @__PURE__ */ jsx25(ErrorFallback, { error, retry: handleRefetch });
|
|
4992
4911
|
}
|
|
4993
|
-
return /* @__PURE__ */
|
|
4994
|
-
/* @__PURE__ */
|
|
4995
|
-
/* @__PURE__ */
|
|
4912
|
+
return /* @__PURE__ */ jsxs19("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
|
|
4913
|
+
/* @__PURE__ */ jsx25("h1", { children: "Event Not Found" }),
|
|
4914
|
+
/* @__PURE__ */ jsxs19("p", { children: [
|
|
4996
4915
|
'The event code "',
|
|
4997
4916
|
eventCode,
|
|
4998
4917
|
'" is invalid or the event is not available for public viewing.'
|
|
4999
4918
|
] }),
|
|
5000
|
-
/* @__PURE__ */
|
|
4919
|
+
/* @__PURE__ */ jsx25(Button, { onClick: handleRefetch, children: "Try Again" })
|
|
5001
4920
|
] });
|
|
5002
4921
|
}
|
|
5003
4922
|
if (!event && showValidationErrors) {
|
|
5004
|
-
return /* @__PURE__ */
|
|
5005
|
-
/* @__PURE__ */
|
|
5006
|
-
/* @__PURE__ */
|
|
5007
|
-
handleRefetch && /* @__PURE__ */
|
|
4923
|
+
return /* @__PURE__ */ jsxs19("main", { className: "flex flex-col items-center justify-center px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: [
|
|
4924
|
+
/* @__PURE__ */ jsx25("h1", { children: "Event Not Available" }),
|
|
4925
|
+
/* @__PURE__ */ jsx25("p", { children: "This event is not available for public viewing." }),
|
|
4926
|
+
handleRefetch && /* @__PURE__ */ jsx25(Button, { onClick: handleRefetch, children: "Try Again" })
|
|
5008
4927
|
] });
|
|
5009
4928
|
}
|
|
5010
|
-
return /* @__PURE__ */
|
|
5011
|
-
customHeader || /* @__PURE__ */
|
|
4929
|
+
return /* @__PURE__ */ jsx25(ErrorBoundary, { componentName: "PublicPageLayout", children: /* @__PURE__ */ jsxs19(Fragment11, { children: [
|
|
4930
|
+
customHeader || /* @__PURE__ */ jsx25(
|
|
5012
4931
|
PublicPageHeader,
|
|
5013
4932
|
{
|
|
5014
4933
|
event: event || void 0,
|
|
5015
4934
|
eventCode
|
|
5016
4935
|
}
|
|
5017
4936
|
),
|
|
5018
|
-
/* @__PURE__ */
|
|
5019
|
-
showFooter && event && (customFooter || /* @__PURE__ */
|
|
4937
|
+
/* @__PURE__ */ jsx25("main", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children }),
|
|
4938
|
+
showFooter && event && (customFooter || /* @__PURE__ */ jsx25(PublicPageFooter, { event }))
|
|
5020
4939
|
] }) });
|
|
5021
4940
|
}
|
|
5022
4941
|
|
|
@@ -5048,8 +4967,7 @@ export {
|
|
|
5048
4967
|
Form,
|
|
5049
4968
|
FormField,
|
|
5050
4969
|
LoginForm,
|
|
5051
|
-
|
|
5052
|
-
OrganisationSelector,
|
|
4970
|
+
ContextSelector,
|
|
5053
4971
|
PasswordChangeForm,
|
|
5054
4972
|
UserMenu,
|
|
5055
4973
|
NavigationMenu,
|
|
@@ -5072,4 +4990,4 @@ export {
|
|
|
5072
4990
|
PublicPageFooter,
|
|
5073
4991
|
PublicPageLayout
|
|
5074
4992
|
};
|
|
5075
|
-
//# sourceMappingURL=chunk-
|
|
4993
|
+
//# sourceMappingURL=chunk-ZNIWI3UC.js.map
|