@jmruthers/pace-core 0.5.183 → 0.5.185
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 +38 -0
- package/README.md +60 -1
- package/core-usage-manifest.json +312 -0
- package/dist/{DataTable-QAB34V6K.js → DataTable-IX2NBUTP.js} +6 -6
- package/dist/{DataTable-Bz8ffqyA.d.ts → DataTable-Z9NLVJh0.d.ts} +1 -1
- package/dist/{index-Bl--n7-T.d.ts → PublicPageProvider-BABf6JCh.d.ts} +21 -10
- package/dist/{UnifiedAuthProvider-7F6T4B6K.js → UnifiedAuthProvider-A4BCQRJY.js} +4 -2
- package/dist/{UnifiedAuthProvider-F86d7dSi.d.ts → UnifiedAuthProvider-BG0AL5eE.d.ts} +2 -1
- package/dist/{api-ROMBCNKU.js → api-BMFCXVQX.js} +2 -2
- package/dist/{chunk-RA3JUFMW.js → chunk-445GEP27.js} +154 -4
- package/dist/{chunk-RA3JUFMW.js.map → chunk-445GEP27.js.map} +1 -1
- package/dist/{chunk-CSOFYHAG.js → chunk-AISXLWGZ.js} +374 -60
- package/dist/chunk-AISXLWGZ.js.map +1 -0
- package/dist/{chunk-FUEYYMX5.js → chunk-FXFJRTKI.js} +24 -3
- package/dist/chunk-FXFJRTKI.js.map +1 -0
- package/dist/{chunk-QETLRQI6.js → chunk-HC67NW5K.js} +380 -360
- package/dist/chunk-HC67NW5K.js.map +1 -0
- package/dist/chunk-HESYZWZW.js +388 -0
- package/dist/chunk-HESYZWZW.js.map +1 -0
- package/dist/{chunk-QUVSNGIP.js → chunk-HGPQUCBC.js} +34 -9
- package/dist/{chunk-QUVSNGIP.js.map → chunk-HGPQUCBC.js.map} +1 -1
- package/dist/{chunk-UHNYIBXL.js → chunk-IXSNYUCT.js} +1 -1
- package/dist/chunk-IXSNYUCT.js.map +1 -0
- package/dist/{chunk-MI7HBHN3.js → chunk-MX3EIJGQ.js} +4 -3
- package/dist/{chunk-MI7HBHN3.js.map → chunk-MX3EIJGQ.js.map} +1 -1
- package/dist/{chunk-PWAHJW4G.js → chunk-OKI34GZD.js} +86 -33
- package/dist/chunk-OKI34GZD.js.map +1 -0
- package/dist/{chunk-W22JP75J.js → chunk-STTZQK2I.js} +3 -3
- package/dist/chunk-THRPYOFK.js +215 -0
- package/dist/chunk-THRPYOFK.js.map +1 -0
- package/dist/{chunk-M7W4CP3M.js → chunk-U6WNSFX5.js} +2 -1
- package/dist/chunk-U6WNSFX5.js.map +1 -0
- package/dist/{chunk-QCDXODCA.js → chunk-XAUHJD3L.js} +2 -2
- package/dist/components.d.ts +182 -6
- package/dist/components.js +157 -11
- package/dist/components.js.map +1 -1
- package/dist/eslint-rules/pace-core-compliance.cjs +406 -0
- package/dist/{file-reference-D06mEEWW.d.ts → file-reference-BjR39ktt.d.ts} +7 -1
- package/dist/hooks.d.ts +7 -14
- package/dist/hooks.js +10 -22
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +11 -11
- package/dist/index.js +79 -16
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +1 -1
- package/dist/providers.js +3 -1
- package/dist/rbac/index.d.ts +205 -14
- package/dist/rbac/index.js +28 -6
- package/dist/timezone-_pgH8qrY.d.ts +530 -0
- package/dist/{types-_x1f4QBF.d.ts → types-DUyCRSTj.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/{usePublicRouteParams-JJczomYq.d.ts → usePublicRouteParams-CvnC3d-e.d.ts} +113 -2
- package/dist/utils.d.ts +109 -151
- package/dist/utils.js +128 -138
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +60 -1
- package/docs/api/classes/ColumnFactory.md +1 -1
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/InvalidScopeError.md +1 -1
- package/docs/api/classes/Logger.md +178 -0
- package/docs/api/classes/MissingUserContextError.md +1 -1
- package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
- package/docs/api/classes/PermissionDeniedError.md +1 -1
- package/docs/api/classes/RBACAuditManager.md +2 -2
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +2 -2
- package/docs/api/classes/RBACError.md +1 -1
- package/docs/api/classes/RBACNotInitializedError.md +1 -1
- package/docs/api/classes/SecureSupabaseClient.md +5 -5
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +54 -0
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +1 -1
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CalendarProps.md +18 -2
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +30 -0
- package/docs/api/interfaces/DataAccessRecord.md +1 -1
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +1 -1
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
- package/docs/api/interfaces/DatabaseComplianceResult.md +85 -0
- package/docs/api/interfaces/DatabaseIssue.md +41 -0
- package/docs/api/interfaces/EmptyStateConfig.md +1 -1
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/EventAppRoleData.md +6 -6
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +1 -1
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +24 -8
- package/docs/api/interfaces/FileUploadProps.md +24 -13
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/FormFieldProps.md +1 -1
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +9 -9
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +62 -0
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
- package/docs/api/interfaces/NavigationContextType.md +1 -1
- package/docs/api/interfaces/NavigationGuardProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/NavigationProviderProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +1 -1
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +36 -23
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
- package/docs/api/interfaces/ProgressProps.md +1 -1
- package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/QuickFix.md +52 -0
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +4 -4
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +7 -7
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +5 -5
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/RuntimeComplianceResult.md +55 -0
- package/docs/api/interfaces/SecureDataContextType.md +1 -1
- package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
- package/docs/api/interfaces/SetupIssue.md +41 -0
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/TabsContentProps.md +1 -1
- package/docs/api/interfaces/TabsListProps.md +1 -1
- package/docs/api/interfaces/TabsProps.md +1 -1
- package/docs/api/interfaces/TabsTriggerProps.md +1 -1
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseFormDialogOptions.md +62 -0
- package/docs/api/interfaces/UseFormDialogReturn.md +117 -0
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +738 -42
- package/docs/api-reference/hooks.md +111 -0
- package/docs/api-reference/rpc-functions.md +1 -1
- package/docs/api-reference/utilities.md +184 -0
- package/docs/getting-started/installation-guide.md +75 -16
- package/docs/getting-started/quick-start.md +61 -11
- package/docs/implementation-guides/authentication.md +88 -12
- package/docs/implementation-guides/file-reference-system.md +2 -1
- package/docs/implementation-guides/file-upload-storage.md +21 -0
- package/docs/rbac/README.md +1 -0
- package/docs/rbac/compliance/compliance-guide.md +544 -0
- package/docs/rbac/getting-started.md +158 -33
- package/docs/standards/pace-core-compliance.md +432 -0
- package/eslint-config-pace-core.cjs +93 -0
- package/package.json +15 -3
- package/scripts/analyze-bundle.js +232 -0
- package/scripts/build-css.js +56 -0
- package/scripts/build-docs-incremental.js +1015 -0
- package/scripts/check-pace-core-compliance.cjs +2353 -0
- package/scripts/generate-docs.js +157 -0
- package/scripts/setup-build-cache.js +73 -0
- package/scripts/utils/command-runner.js +131 -0
- package/scripts/utils/env.js +33 -0
- package/scripts/utils/index.js +10 -0
- package/scripts/utils/logger.js +88 -0
- package/scripts/utils/path-helpers.js +37 -0
- package/scripts/validate-formats.js +133 -0
- package/scripts/validate-master.js +155 -0
- package/scripts/validate-pre-publish.js +140 -0
- package/scripts/validate-theme.js +142 -0
- package/src/components/Calendar/Calendar.tsx +8 -1
- package/src/components/Card/Card.tsx +47 -8
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +314 -0
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +126 -0
- package/src/components/DatePickerWithTimezone/README.md +135 -0
- package/src/components/DatePickerWithTimezone/index.ts +10 -0
- package/src/components/DateTimeField/DateTimeField.test.tsx +358 -0
- package/src/components/DateTimeField/DateTimeField.tsx +232 -0
- package/src/components/DateTimeField/README.md +148 -0
- package/src/components/DateTimeField/index.ts +10 -0
- package/src/components/FileUpload/FileUpload.tsx +3 -0
- package/src/components/Header/Header.test.tsx +47 -18
- package/src/components/Header/Header.tsx +24 -6
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +29 -20
- package/src/components/PaceAppLayout/README.md +9 -0
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +37 -8
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +12 -4
- package/src/components/index.ts +8 -0
- package/src/eslint-rules/pace-core-compliance.cjs +406 -0
- package/src/eslint-rules/pace-core-compliance.js +640 -0
- package/src/hooks/__tests__/useFormDialog.test.ts +478 -0
- package/src/hooks/index.ts +2 -0
- package/src/hooks/useFileReference.test.ts +1 -0
- package/src/hooks/useFormDialog.ts +147 -0
- package/src/index.ts +27 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +6 -5
- package/src/providers/services/UnifiedAuthProvider.tsx +24 -3
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +3 -0
- package/src/rbac/compliance/database-validator.ts +165 -0
- package/src/rbac/compliance/index.ts +38 -0
- package/src/rbac/compliance/quick-fix-suggestions.ts +209 -0
- package/src/rbac/compliance/runtime-compliance.ts +77 -0
- package/src/rbac/compliance/setup-validator.ts +131 -0
- package/src/rbac/components/PagePermissionGuard.tsx +8 -64
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +35 -21
- package/src/rbac/docs/event-based-apps.md +285 -0
- package/src/rbac/errors.ts +11 -0
- package/src/rbac/hooks/useRoleManagement.ts +292 -12
- package/src/rbac/index.ts +30 -0
- package/src/services/OrganisationService.ts +4 -0
- package/src/types/file-reference.ts +6 -0
- package/src/utils/__tests__/timezone.test.ts +345 -0
- package/src/utils/file-reference/__tests__/file-reference.test.ts +2 -0
- package/src/utils/file-reference/index.ts +1 -0
- package/src/utils/formatting/formatDateTimeTimezone.test.ts +167 -0
- package/src/utils/formatting/formatting.ts +179 -0
- package/src/utils/index.ts +27 -1
- package/src/utils/location/index.ts +16 -0
- package/src/utils/location/location.test.ts +286 -0
- package/src/utils/location/location.ts +175 -0
- package/src/utils/timezone/index.ts +17 -0
- package/src/utils/timezone/timezone.test.ts +349 -0
- package/src/utils/timezone/timezone.ts +281 -0
- package/dist/chunk-CSOFYHAG.js.map +0 -1
- package/dist/chunk-FUEYYMX5.js.map +0 -1
- package/dist/chunk-HKIT6O7W.js +0 -198
- package/dist/chunk-HKIT6O7W.js.map +0 -1
- package/dist/chunk-KUEN3HFB.js +0 -94
- package/dist/chunk-KUEN3HFB.js.map +0 -1
- package/dist/chunk-M7W4CP3M.js.map +0 -1
- package/dist/chunk-PWAHJW4G.js.map +0 -1
- package/dist/chunk-QETLRQI6.js.map +0 -1
- package/dist/chunk-UHNYIBXL.js.map +0 -1
- package/dist/formatting-5wETwiGF.d.ts +0 -162
- /package/dist/{DataTable-QAB34V6K.js.map → DataTable-IX2NBUTP.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-7F6T4B6K.js.map → UnifiedAuthProvider-A4BCQRJY.js.map} +0 -0
- /package/dist/{api-ROMBCNKU.js.map → api-BMFCXVQX.js.map} +0 -0
- /package/dist/{chunk-W22JP75J.js.map → chunk-STTZQK2I.js.map} +0 -0
- /package/dist/{chunk-QCDXODCA.js.map → chunk-XAUHJD3L.js.map} +0 -0
|
@@ -25,16 +25,16 @@ import {
|
|
|
25
25
|
SelectSeparator,
|
|
26
26
|
SelectTrigger,
|
|
27
27
|
SelectValue
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-HGPQUCBC.js";
|
|
29
29
|
import {
|
|
30
30
|
useCan,
|
|
31
31
|
usePermissions,
|
|
32
32
|
useRBAC,
|
|
33
33
|
useResolvedScope
|
|
34
|
-
} from "./chunk-
|
|
34
|
+
} from "./chunk-445GEP27.js";
|
|
35
35
|
import {
|
|
36
36
|
isSuperAdmin
|
|
37
|
-
} from "./chunk-
|
|
37
|
+
} from "./chunk-U6WNSFX5.js";
|
|
38
38
|
import {
|
|
39
39
|
ErrorBoundary,
|
|
40
40
|
PublicPageContext,
|
|
@@ -47,26 +47,26 @@ import {
|
|
|
47
47
|
useFileDisplay,
|
|
48
48
|
useIsPublicPage,
|
|
49
49
|
usePublicFileDisplay
|
|
50
|
-
} from "./chunk-
|
|
50
|
+
} from "./chunk-MX3EIJGQ.js";
|
|
51
51
|
import {
|
|
52
52
|
useToast
|
|
53
53
|
} from "./chunk-6C4YBBJM.js";
|
|
54
54
|
import {
|
|
55
55
|
useEvents,
|
|
56
56
|
useOrganisations
|
|
57
|
-
} from "./chunk-
|
|
57
|
+
} from "./chunk-XAUHJD3L.js";
|
|
58
58
|
import {
|
|
59
59
|
EventServiceContext,
|
|
60
60
|
useSessionRestoration,
|
|
61
61
|
useUnifiedAuth
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-FXFJRTKI.js";
|
|
63
63
|
import {
|
|
64
64
|
assertAppId
|
|
65
65
|
} from "./chunk-QXHPKYJV.js";
|
|
66
66
|
import {
|
|
67
67
|
LoadingSpinner,
|
|
68
68
|
getAppId
|
|
69
|
-
} from "./chunk-
|
|
69
|
+
} from "./chunk-THRPYOFK.js";
|
|
70
70
|
import {
|
|
71
71
|
cn
|
|
72
72
|
} from "./chunk-R77UEZ4E.js";
|
|
@@ -980,14 +980,185 @@ function EventSelector({
|
|
|
980
980
|
);
|
|
981
981
|
}
|
|
982
982
|
|
|
983
|
-
// src/components/
|
|
984
|
-
import { useState as useState2 } from "react";
|
|
983
|
+
// src/components/OrganisationSelector/OrganisationSelector.tsx
|
|
984
|
+
import { useState as useState2, useCallback as useCallback2 } from "react";
|
|
985
|
+
import { RefreshCw as RefreshCw2, AlertCircle as AlertCircle2, Building2, Shield } from "lucide-react";
|
|
985
986
|
import { jsx as jsx12, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
987
|
+
function OrganisationSelector({
|
|
988
|
+
placeholder = "Select organisation",
|
|
989
|
+
className,
|
|
990
|
+
onOrganisationChange,
|
|
991
|
+
showNoOrganisationsMessage = true,
|
|
992
|
+
showRetryButton = true,
|
|
993
|
+
showRole = false,
|
|
994
|
+
compact = false,
|
|
995
|
+
disabled = false
|
|
996
|
+
}) {
|
|
997
|
+
const [isLoading, setIsLoading] = useState2(false);
|
|
998
|
+
const [switchError, setSwitchError] = useState2(null);
|
|
999
|
+
const {
|
|
1000
|
+
organisations,
|
|
1001
|
+
selectedOrganisation,
|
|
1002
|
+
isLoading: orgLoading,
|
|
1003
|
+
error: orgError,
|
|
1004
|
+
switchOrganisation,
|
|
1005
|
+
getUserRole,
|
|
1006
|
+
validateOrganisationAccess,
|
|
1007
|
+
refreshOrganisations
|
|
1008
|
+
} = useOrganisations();
|
|
1009
|
+
const handleOrganisationChange = useCallback2(async (orgId) => {
|
|
1010
|
+
if (disabled || isLoading) return;
|
|
1011
|
+
setSwitchError(null);
|
|
1012
|
+
setIsLoading(true);
|
|
1013
|
+
try {
|
|
1014
|
+
if (!validateOrganisationAccess(orgId)) {
|
|
1015
|
+
throw new Error("You do not have access to this organisation");
|
|
1016
|
+
}
|
|
1017
|
+
await switchOrganisation(orgId);
|
|
1018
|
+
const newOrganisation = organisations.find((org) => org.id === orgId);
|
|
1019
|
+
if (newOrganisation && onOrganisationChange) {
|
|
1020
|
+
onOrganisationChange(newOrganisation);
|
|
1021
|
+
}
|
|
1022
|
+
logger.debug("OrganisationSelector", "Successfully switched to organisation:", orgId);
|
|
1023
|
+
} catch (error) {
|
|
1024
|
+
logger.error("OrganisationSelector", "Failed to switch organisation:", error);
|
|
1025
|
+
setSwitchError(error instanceof Error ? error.message : "Failed to switch organisation");
|
|
1026
|
+
} finally {
|
|
1027
|
+
setIsLoading(false);
|
|
1028
|
+
}
|
|
1029
|
+
}, [
|
|
1030
|
+
disabled,
|
|
1031
|
+
isLoading,
|
|
1032
|
+
validateOrganisationAccess,
|
|
1033
|
+
switchOrganisation,
|
|
1034
|
+
organisations,
|
|
1035
|
+
onOrganisationChange
|
|
1036
|
+
]);
|
|
1037
|
+
const handleRetry = useCallback2(async () => {
|
|
1038
|
+
setIsLoading(true);
|
|
1039
|
+
setSwitchError(null);
|
|
1040
|
+
try {
|
|
1041
|
+
await refreshOrganisations();
|
|
1042
|
+
} catch (error) {
|
|
1043
|
+
logger.error("OrganisationSelector", "Failed to refresh organisations:", error);
|
|
1044
|
+
setSwitchError("Failed to refresh organisations");
|
|
1045
|
+
} finally {
|
|
1046
|
+
setIsLoading(false);
|
|
1047
|
+
}
|
|
1048
|
+
}, [refreshOrganisations]);
|
|
1049
|
+
if (orgLoading) {
|
|
1050
|
+
return /* @__PURE__ */ jsxs6("div", { className: `flex items-center gap-2 ${className}`, children: [
|
|
1051
|
+
/* @__PURE__ */ jsx12(LoadingSpinner, { size: "sm" }),
|
|
1052
|
+
/* @__PURE__ */ jsx12("span", { className: "text-sm text-muted-foreground", children: compact ? "Loading..." : "Loading organisations..." })
|
|
1053
|
+
] });
|
|
1054
|
+
}
|
|
1055
|
+
if (orgError) {
|
|
1056
|
+
return /* @__PURE__ */ jsxs6("div", { className: `space-y-2 ${className}`, children: [
|
|
1057
|
+
/* @__PURE__ */ jsxs6(Alert, { variant: "destructive", children: [
|
|
1058
|
+
/* @__PURE__ */ jsx12(AlertCircle2, { className: "h-4 w-4" }),
|
|
1059
|
+
/* @__PURE__ */ jsxs6(AlertDescription, { children: [
|
|
1060
|
+
"Failed to load organisations: ",
|
|
1061
|
+
orgError.message
|
|
1062
|
+
] })
|
|
1063
|
+
] }),
|
|
1064
|
+
showRetryButton && /* @__PURE__ */ jsxs6(
|
|
1065
|
+
Button,
|
|
1066
|
+
{
|
|
1067
|
+
variant: "outline",
|
|
1068
|
+
size: "sm",
|
|
1069
|
+
onClick: handleRetry,
|
|
1070
|
+
disabled: isLoading,
|
|
1071
|
+
className: "w-full",
|
|
1072
|
+
children: [
|
|
1073
|
+
/* @__PURE__ */ jsx12(RefreshCw2, { className: `h-4 w-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
1074
|
+
"Retry"
|
|
1075
|
+
]
|
|
1076
|
+
}
|
|
1077
|
+
)
|
|
1078
|
+
] });
|
|
1079
|
+
}
|
|
1080
|
+
if (organisations.length === 0) {
|
|
1081
|
+
if (showNoOrganisationsMessage) {
|
|
1082
|
+
return /* @__PURE__ */ jsxs6("div", { className: `space-y-2 ${className}`, children: [
|
|
1083
|
+
/* @__PURE__ */ jsxs6(Alert, { children: [
|
|
1084
|
+
/* @__PURE__ */ jsx12(Building2, { className: "h-4 w-4" }),
|
|
1085
|
+
/* @__PURE__ */ jsx12(AlertDescription, { children: "No organisations available. Please contact your administrator to be added to an organisation." })
|
|
1086
|
+
] }),
|
|
1087
|
+
showRetryButton && /* @__PURE__ */ jsxs6(
|
|
1088
|
+
Button,
|
|
1089
|
+
{
|
|
1090
|
+
variant: "outline",
|
|
1091
|
+
size: "sm",
|
|
1092
|
+
onClick: handleRetry,
|
|
1093
|
+
disabled: isLoading,
|
|
1094
|
+
className: "w-full",
|
|
1095
|
+
children: [
|
|
1096
|
+
/* @__PURE__ */ jsx12(RefreshCw2, { className: `h-4 w-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
1097
|
+
"Check Again"
|
|
1098
|
+
]
|
|
1099
|
+
}
|
|
1100
|
+
)
|
|
1101
|
+
] });
|
|
1102
|
+
}
|
|
1103
|
+
return null;
|
|
1104
|
+
}
|
|
1105
|
+
const switchErrorDisplay = switchError && /* @__PURE__ */ jsxs6(Alert, { variant: "destructive", className: "mt-2", children: [
|
|
1106
|
+
/* @__PURE__ */ jsx12(AlertCircle2, { className: "h-4 w-4" }),
|
|
1107
|
+
/* @__PURE__ */ jsx12(AlertDescription, { children: switchError })
|
|
1108
|
+
] });
|
|
1109
|
+
return /* @__PURE__ */ jsxs6("div", { className: `space-y-2 ${className}`, children: [
|
|
1110
|
+
/* @__PURE__ */ jsxs6(
|
|
1111
|
+
Select,
|
|
1112
|
+
{
|
|
1113
|
+
value: selectedOrganisation?.id || "",
|
|
1114
|
+
onValueChange: handleOrganisationChange,
|
|
1115
|
+
disabled: disabled || isLoading || !selectedOrganisation,
|
|
1116
|
+
children: [
|
|
1117
|
+
/* @__PURE__ */ jsx12(SelectTrigger, { className: `${isLoading ? "opacity-50" : ""}`, children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
1118
|
+
isLoading ? /* @__PURE__ */ jsx12(LoadingSpinner, { size: "sm" }) : /* @__PURE__ */ jsx12(Building2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
1119
|
+
/* @__PURE__ */ jsx12(SelectValue, { placeholder })
|
|
1120
|
+
] }) }),
|
|
1121
|
+
/* @__PURE__ */ jsx12(SelectContent, { children: organisations.map((org) => {
|
|
1122
|
+
const userRole = getUserRole(org.id);
|
|
1123
|
+
const hasAccess = validateOrganisationAccess(org.id);
|
|
1124
|
+
return /* @__PURE__ */ jsx12(
|
|
1125
|
+
SelectItem,
|
|
1126
|
+
{
|
|
1127
|
+
value: org.id,
|
|
1128
|
+
disabled: !hasAccess,
|
|
1129
|
+
className: !hasAccess ? "opacity-50" : "",
|
|
1130
|
+
children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between w-full", children: [
|
|
1131
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
1132
|
+
/* @__PURE__ */ jsx12(Building2, { className: "h-4 w-4" }),
|
|
1133
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex flex-col", children: [
|
|
1134
|
+
/* @__PURE__ */ jsx12("span", { className: "font-medium", children: org.display_name }),
|
|
1135
|
+
!compact && org.description && /* @__PURE__ */ jsx12("span", { className: "text-xs text-muted-foreground truncate max-w-40", children: org.description })
|
|
1136
|
+
] })
|
|
1137
|
+
] }),
|
|
1138
|
+
showRole && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1 ml-4", children: [
|
|
1139
|
+
/* @__PURE__ */ jsx12(Shield, { className: "h-3 w-3 text-muted-foreground" }),
|
|
1140
|
+
/* @__PURE__ */ jsx12("span", { className: "text-xs text-muted-foreground capitalize", children: userRole?.replace("_", " ") || "No Role" })
|
|
1141
|
+
] })
|
|
1142
|
+
] })
|
|
1143
|
+
},
|
|
1144
|
+
org.id
|
|
1145
|
+
);
|
|
1146
|
+
}) })
|
|
1147
|
+
]
|
|
1148
|
+
}
|
|
1149
|
+
),
|
|
1150
|
+
switchErrorDisplay
|
|
1151
|
+
] });
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
// src/components/PasswordChange/PasswordChangeForm.tsx
|
|
1155
|
+
import { useState as useState3 } from "react";
|
|
1156
|
+
import { jsx as jsx13, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
986
1157
|
function PasswordChangeForm({ onSubmit, className }) {
|
|
987
|
-
const [newPassword, setNewPassword] =
|
|
988
|
-
const [confirmPassword, setConfirmPassword] =
|
|
989
|
-
const [error, setError] =
|
|
990
|
-
const [isSubmitting, setIsSubmitting] =
|
|
1158
|
+
const [newPassword, setNewPassword] = useState3("");
|
|
1159
|
+
const [confirmPassword, setConfirmPassword] = useState3("");
|
|
1160
|
+
const [error, setError] = useState3(null);
|
|
1161
|
+
const [isSubmitting, setIsSubmitting] = useState3(false);
|
|
991
1162
|
const handleSubmit = async (e) => {
|
|
992
1163
|
e.preventDefault();
|
|
993
1164
|
setError(null);
|
|
@@ -1012,11 +1183,11 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
1012
1183
|
setIsSubmitting(false);
|
|
1013
1184
|
}
|
|
1014
1185
|
};
|
|
1015
|
-
return /* @__PURE__ */
|
|
1016
|
-
error && /* @__PURE__ */
|
|
1017
|
-
/* @__PURE__ */
|
|
1018
|
-
/* @__PURE__ */
|
|
1019
|
-
/* @__PURE__ */
|
|
1186
|
+
return /* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: [
|
|
1187
|
+
error && /* @__PURE__ */ jsx13("div", { role: "alert", children: error }),
|
|
1188
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
|
|
1189
|
+
/* @__PURE__ */ jsx13(Label, { htmlFor: "new-password", children: "New Password" }),
|
|
1190
|
+
/* @__PURE__ */ jsx13(
|
|
1020
1191
|
Input,
|
|
1021
1192
|
{
|
|
1022
1193
|
id: "new-password",
|
|
@@ -1028,9 +1199,9 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
1028
1199
|
}
|
|
1029
1200
|
)
|
|
1030
1201
|
] }),
|
|
1031
|
-
/* @__PURE__ */
|
|
1032
|
-
/* @__PURE__ */
|
|
1033
|
-
/* @__PURE__ */
|
|
1202
|
+
/* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
|
|
1203
|
+
/* @__PURE__ */ jsx13(Label, { htmlFor: "confirm-password", children: "Confirm Password" }),
|
|
1204
|
+
/* @__PURE__ */ jsx13(
|
|
1034
1205
|
Input,
|
|
1035
1206
|
{
|
|
1036
1207
|
id: "confirm-password",
|
|
@@ -1042,7 +1213,7 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
1042
1213
|
}
|
|
1043
1214
|
)
|
|
1044
1215
|
] }),
|
|
1045
|
-
/* @__PURE__ */
|
|
1216
|
+
/* @__PURE__ */ jsx13(
|
|
1046
1217
|
Button,
|
|
1047
1218
|
{
|
|
1048
1219
|
type: "submit",
|
|
@@ -1055,17 +1226,17 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
1055
1226
|
}
|
|
1056
1227
|
|
|
1057
1228
|
// src/components/UserMenu/UserMenu.tsx
|
|
1058
|
-
import
|
|
1229
|
+
import React12, { useCallback as useCallback3, useMemo as useMemo3, useState as useState4 } from "react";
|
|
1059
1230
|
import { ChevronDown, LogOut, KeyRound } from "lucide-react";
|
|
1060
|
-
import { jsx as
|
|
1061
|
-
var UserMenu =
|
|
1231
|
+
import { jsx as jsx14, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1232
|
+
var UserMenu = React12.memo(function UserMenu2({
|
|
1062
1233
|
user,
|
|
1063
1234
|
onSignOut,
|
|
1064
1235
|
onChangePassword,
|
|
1065
1236
|
className,
|
|
1066
1237
|
showAvatar = true
|
|
1067
1238
|
}) {
|
|
1068
|
-
const [isPasswordDialogOpen, setPasswordDialogOpen] =
|
|
1239
|
+
const [isPasswordDialogOpen, setPasswordDialogOpen] = useState4(false);
|
|
1069
1240
|
const userInfo = useMemo3(() => {
|
|
1070
1241
|
if (!user) return null;
|
|
1071
1242
|
return {
|
|
@@ -1075,42 +1246,42 @@ var UserMenu = React11.memo(function UserMenu2({
|
|
|
1075
1246
|
initial: (user.user_metadata?.display_name || user.user_metadata?.full_name || user.email || "U").charAt(0).toUpperCase()
|
|
1076
1247
|
};
|
|
1077
1248
|
}, [user]);
|
|
1078
|
-
const handleSignOut =
|
|
1249
|
+
const handleSignOut = useCallback3(async () => {
|
|
1079
1250
|
if (onSignOut) await onSignOut();
|
|
1080
1251
|
}, [onSignOut]);
|
|
1081
1252
|
if (!user || !userInfo) {
|
|
1082
1253
|
return null;
|
|
1083
1254
|
}
|
|
1084
|
-
return /* @__PURE__ */
|
|
1085
|
-
/* @__PURE__ */
|
|
1086
|
-
/* @__PURE__ */
|
|
1087
|
-
showAvatar && /* @__PURE__ */
|
|
1088
|
-
/* @__PURE__ */
|
|
1089
|
-
/* @__PURE__ */
|
|
1255
|
+
return /* @__PURE__ */ jsxs8(Dialog, { open: isPasswordDialogOpen, onOpenChange: setPasswordDialogOpen, children: [
|
|
1256
|
+
/* @__PURE__ */ jsxs8(Select, { className, children: [
|
|
1257
|
+
/* @__PURE__ */ jsx14(SelectTrigger, { asChild: true, children: /* @__PURE__ */ jsxs8(Button, { variant: "outline", className: "flex items-center gap-2", "aria-label": userInfo.displayName, children: [
|
|
1258
|
+
showAvatar && /* @__PURE__ */ jsxs8(Avatar, { className: "size-7", children: [
|
|
1259
|
+
/* @__PURE__ */ jsx14(AvatarImage, { src: userInfo.avatarUrl, alt: userInfo.displayName }),
|
|
1260
|
+
/* @__PURE__ */ jsx14(AvatarFallback, { children: userInfo.initial })
|
|
1090
1261
|
] }),
|
|
1091
|
-
/* @__PURE__ */
|
|
1092
|
-
/* @__PURE__ */
|
|
1262
|
+
/* @__PURE__ */ jsx14("span", { children: userInfo.displayName }),
|
|
1263
|
+
/* @__PURE__ */ jsx14(ChevronDown, { className: "h-4 w-4" })
|
|
1093
1264
|
] }) }),
|
|
1094
|
-
/* @__PURE__ */
|
|
1095
|
-
/* @__PURE__ */
|
|
1096
|
-
/* @__PURE__ */
|
|
1097
|
-
/* @__PURE__ */
|
|
1265
|
+
/* @__PURE__ */ jsxs8(SelectContent, { children: [
|
|
1266
|
+
/* @__PURE__ */ jsx14(SelectLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs8("div", { className: "flex flex-col space-y-1", children: [
|
|
1267
|
+
/* @__PURE__ */ jsx14("p", { className: "font-medium", children: userInfo.displayName }),
|
|
1268
|
+
/* @__PURE__ */ jsx14("p", { className: "text-muted-foreground", children: userInfo.email })
|
|
1098
1269
|
] }) }),
|
|
1099
|
-
/* @__PURE__ */
|
|
1100
|
-
/* @__PURE__ */
|
|
1101
|
-
/* @__PURE__ */
|
|
1102
|
-
/* @__PURE__ */
|
|
1270
|
+
/* @__PURE__ */ jsx14(SelectSeparator, {}),
|
|
1271
|
+
/* @__PURE__ */ jsx14(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs8(SelectItem, { value: "change-password", children: [
|
|
1272
|
+
/* @__PURE__ */ jsx14(KeyRound, { className: "mr-2 h-4 w-4" }),
|
|
1273
|
+
/* @__PURE__ */ jsx14("span", { children: "Change Password" })
|
|
1103
1274
|
] }) }),
|
|
1104
|
-
/* @__PURE__ */
|
|
1105
|
-
/* @__PURE__ */
|
|
1106
|
-
/* @__PURE__ */
|
|
1275
|
+
/* @__PURE__ */ jsxs8(SelectItem, { value: "sign-out", onClick: handleSignOut, children: [
|
|
1276
|
+
/* @__PURE__ */ jsx14(LogOut, { className: "mr-2 h-4 w-4" }),
|
|
1277
|
+
/* @__PURE__ */ jsx14("span", { children: "Sign out" })
|
|
1107
1278
|
] })
|
|
1108
1279
|
] })
|
|
1109
1280
|
] }),
|
|
1110
|
-
/* @__PURE__ */
|
|
1111
|
-
/* @__PURE__ */
|
|
1112
|
-
/* @__PURE__ */
|
|
1113
|
-
/* @__PURE__ */
|
|
1281
|
+
/* @__PURE__ */ jsx14(DialogOverlay, {}),
|
|
1282
|
+
/* @__PURE__ */ jsxs8(DialogContent, { className, children: [
|
|
1283
|
+
/* @__PURE__ */ jsx14(DialogHeader, { children: /* @__PURE__ */ jsx14(DialogTitle, { children: "Change Password" }) }),
|
|
1284
|
+
/* @__PURE__ */ jsx14(
|
|
1114
1285
|
PasswordChangeForm,
|
|
1115
1286
|
{
|
|
1116
1287
|
onSubmit: async ({ newPassword, confirmPassword }) => {
|
|
@@ -1128,31 +1299,31 @@ var UserMenu = React11.memo(function UserMenu2({
|
|
|
1128
1299
|
] })
|
|
1129
1300
|
] });
|
|
1130
1301
|
});
|
|
1131
|
-
var UserMenuLoading =
|
|
1132
|
-
return /* @__PURE__ */
|
|
1133
|
-
/* @__PURE__ */
|
|
1302
|
+
var UserMenuLoading = React12.memo(function UserMenuLoading2() {
|
|
1303
|
+
return /* @__PURE__ */ jsxs8("div", { className: "relative inline-block text-left", children: [
|
|
1304
|
+
/* @__PURE__ */ jsxs8(
|
|
1134
1305
|
"button",
|
|
1135
1306
|
{
|
|
1136
1307
|
type: "button",
|
|
1137
1308
|
disabled: true,
|
|
1138
1309
|
className: "flex items-center space-x-2 px-3 py-2 text-sm font-medium text-muted-foreground bg-muted border border-input rounded-md",
|
|
1139
1310
|
children: [
|
|
1140
|
-
/* @__PURE__ */
|
|
1141
|
-
/* @__PURE__ */
|
|
1142
|
-
/* @__PURE__ */
|
|
1311
|
+
/* @__PURE__ */ jsx14("div", { className: "w-6 h-6 rounded-full bg-muted animate-pulse" }),
|
|
1312
|
+
/* @__PURE__ */ jsx14("span", { className: "truncate max-w-[150px]", children: "Loading..." }),
|
|
1313
|
+
/* @__PURE__ */ jsx14(ChevronDown, { className: "w-4 h-4 text-muted-foreground" })
|
|
1143
1314
|
]
|
|
1144
1315
|
}
|
|
1145
1316
|
),
|
|
1146
|
-
/* @__PURE__ */
|
|
1317
|
+
/* @__PURE__ */ jsx14("div", { role: "status", "aria-label": "Loading user menu", "aria-live": "polite", className: "w-6 h-6 rounded-full bg-muted animate-pulse" })
|
|
1147
1318
|
] });
|
|
1148
1319
|
});
|
|
1149
1320
|
UserMenu.Loading = UserMenuLoading;
|
|
1150
1321
|
|
|
1151
1322
|
// src/components/NavigationMenu/NavigationMenu.tsx
|
|
1152
|
-
import * as
|
|
1323
|
+
import * as React13 from "react";
|
|
1153
1324
|
import { ChevronDown as ChevronDown2 } from "lucide-react";
|
|
1154
|
-
import { jsx as
|
|
1155
|
-
var NavigationMenu =
|
|
1325
|
+
import { jsx as jsx15, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
1326
|
+
var NavigationMenu = React13.forwardRef(({
|
|
1156
1327
|
items,
|
|
1157
1328
|
mode = "dropdown",
|
|
1158
1329
|
currentPath,
|
|
@@ -1170,8 +1341,8 @@ var NavigationMenu = React12.forwardRef(({
|
|
|
1170
1341
|
itemsPreFiltered = false,
|
|
1171
1342
|
...props
|
|
1172
1343
|
}, ref) => {
|
|
1173
|
-
const [expandedItems, setExpandedItems] =
|
|
1174
|
-
const buttonRef =
|
|
1344
|
+
const [expandedItems, setExpandedItems] = React13.useState(/* @__PURE__ */ new Set());
|
|
1345
|
+
const buttonRef = React13.useRef(null);
|
|
1175
1346
|
let authContext = null;
|
|
1176
1347
|
try {
|
|
1177
1348
|
authContext = useUnifiedAuth();
|
|
@@ -1196,15 +1367,15 @@ var NavigationMenu = React12.forwardRef(({
|
|
|
1196
1367
|
selectedOrganisationId: itemsPreFiltered ? null : selectedOrganisation?.id || null,
|
|
1197
1368
|
selectedEventId: itemsPreFiltered ? null : selectedEvent?.event_id || null
|
|
1198
1369
|
});
|
|
1199
|
-
const [resolvedAppId, setResolvedAppId] =
|
|
1200
|
-
|
|
1370
|
+
const [resolvedAppId, setResolvedAppId] = React13.useState(void 0);
|
|
1371
|
+
React13.useEffect(() => {
|
|
1201
1372
|
if (!scopeLoading && !resolvedScope?.appId && selectedOrganisation?.id && authContext?.appName && authContext?.user?.id && !resolvedAppId) {
|
|
1202
1373
|
if (!authContext.user || !authContext.appName) {
|
|
1203
1374
|
return;
|
|
1204
1375
|
}
|
|
1205
1376
|
const userId2 = authContext.user.id;
|
|
1206
1377
|
const appName = authContext.appName;
|
|
1207
|
-
import("./api-
|
|
1378
|
+
import("./api-BMFCXVQX.js").then(({ resolveAppContext }) => {
|
|
1208
1379
|
resolveAppContext({
|
|
1209
1380
|
userId: userId2,
|
|
1210
1381
|
appName
|
|
@@ -1218,7 +1389,7 @@ var NavigationMenu = React12.forwardRef(({
|
|
|
1218
1389
|
});
|
|
1219
1390
|
}
|
|
1220
1391
|
}, [scopeLoading, resolvedScope?.appId, selectedOrganisation?.id, authContext?.appName, authContext?.user?.id, resolvedAppId]);
|
|
1221
|
-
const effectiveScope =
|
|
1392
|
+
const effectiveScope = React13.useMemo(() => {
|
|
1222
1393
|
if (resolvedScope?.organisationId) {
|
|
1223
1394
|
return resolvedScope;
|
|
1224
1395
|
}
|
|
@@ -1233,7 +1404,7 @@ var NavigationMenu = React12.forwardRef(({
|
|
|
1233
1404
|
return null;
|
|
1234
1405
|
}, [resolvedScope, selectedOrganisation?.id, selectedEvent?.event_id, resolvedAppId]);
|
|
1235
1406
|
const scopeKey = effectiveScope ? `${effectiveScope.organisationId || ""}-${effectiveScope.eventId || ""}-${effectiveScope.appId || ""}` : "empty";
|
|
1236
|
-
const stableScope =
|
|
1407
|
+
const stableScope = React13.useMemo(() => {
|
|
1237
1408
|
if (effectiveScope?.organisationId) {
|
|
1238
1409
|
return {
|
|
1239
1410
|
organisationId: effectiveScope.organisationId,
|
|
@@ -1258,8 +1429,8 @@ var NavigationMenu = React12.forwardRef(({
|
|
|
1258
1429
|
itemsPreFiltered ? void 0 : stableScope.appId
|
|
1259
1430
|
// Skip if pre-filtered
|
|
1260
1431
|
);
|
|
1261
|
-
const previousFilteredItemsRef =
|
|
1262
|
-
const filteredItems =
|
|
1432
|
+
const previousFilteredItemsRef = React13.useRef([]);
|
|
1433
|
+
const filteredItems = React13.useMemo(() => {
|
|
1263
1434
|
if (itemsPreFiltered && items && items.length > 0) {
|
|
1264
1435
|
const visibleItems = (items || []).filter((item) => !item.meta?.hidden);
|
|
1265
1436
|
previousFilteredItemsRef.current = visibleItems;
|
|
@@ -1555,8 +1726,8 @@ var NavigationMenu = React12.forwardRef(({
|
|
|
1555
1726
|
const hasChildren = item.children && item.children.length > 0;
|
|
1556
1727
|
const isExpanded = expandedItems.has(item.id);
|
|
1557
1728
|
const itemIsActive = isActiveItem(item);
|
|
1558
|
-
return /* @__PURE__ */
|
|
1559
|
-
/* @__PURE__ */
|
|
1729
|
+
return /* @__PURE__ */ jsx15("li", { role: "none", children: hasChildren ? /* @__PURE__ */ jsxs9("div", { children: [
|
|
1730
|
+
/* @__PURE__ */ jsxs9(
|
|
1560
1731
|
"button",
|
|
1561
1732
|
{
|
|
1562
1733
|
onClick: () => toggleExpanded(item.id),
|
|
@@ -1565,21 +1736,21 @@ var NavigationMenu = React12.forwardRef(({
|
|
|
1565
1736
|
"aria-controls": `submenu-${item.id}`,
|
|
1566
1737
|
"aria-current": itemIsActive ? "page" : void 0,
|
|
1567
1738
|
children: [
|
|
1568
|
-
/* @__PURE__ */
|
|
1569
|
-
/* @__PURE__ */
|
|
1739
|
+
/* @__PURE__ */ jsx15("span", { children: item.label }),
|
|
1740
|
+
/* @__PURE__ */ jsx15(ChevronDown2, { "aria-hidden": "true" })
|
|
1570
1741
|
]
|
|
1571
1742
|
}
|
|
1572
1743
|
),
|
|
1573
|
-
isExpanded && item.children && /* @__PURE__ */
|
|
1744
|
+
isExpanded && item.children && /* @__PURE__ */ jsx15(
|
|
1574
1745
|
"ul",
|
|
1575
1746
|
{
|
|
1576
1747
|
id: `submenu-${item.id}`,
|
|
1577
1748
|
role: "menu",
|
|
1578
1749
|
"aria-label": `${item.label} submenu`,
|
|
1579
|
-
children: item.children.map((child) => /* @__PURE__ */
|
|
1750
|
+
children: item.children.map((child) => /* @__PURE__ */ jsx15(React13.Fragment, { children: renderHierarchicalItem(child, level + 1) }, child.id))
|
|
1580
1751
|
}
|
|
1581
1752
|
)
|
|
1582
|
-
] }) : /* @__PURE__ */
|
|
1753
|
+
] }) : /* @__PURE__ */ jsx15(
|
|
1583
1754
|
"a",
|
|
1584
1755
|
{
|
|
1585
1756
|
href: item.href || "#",
|
|
@@ -1597,26 +1768,26 @@ var NavigationMenu = React12.forwardRef(({
|
|
|
1597
1768
|
) });
|
|
1598
1769
|
};
|
|
1599
1770
|
if (mode === "dropdown") {
|
|
1600
|
-
return /* @__PURE__ */
|
|
1771
|
+
return /* @__PURE__ */ jsxs9(
|
|
1601
1772
|
Select,
|
|
1602
1773
|
{
|
|
1603
1774
|
onValueChange: handleNavigationSelect,
|
|
1604
1775
|
className,
|
|
1605
1776
|
"data-testid": "navigation-menu-root",
|
|
1606
1777
|
children: [
|
|
1607
|
-
/* @__PURE__ */
|
|
1778
|
+
/* @__PURE__ */ jsx15(
|
|
1608
1779
|
SelectTrigger,
|
|
1609
1780
|
{
|
|
1610
1781
|
ref: buttonRef,
|
|
1611
1782
|
disabled,
|
|
1612
1783
|
"aria-label": buttonText,
|
|
1613
1784
|
"data-testid": "navigation-menu-trigger",
|
|
1614
|
-
children: /* @__PURE__ */
|
|
1785
|
+
children: /* @__PURE__ */ jsx15(SelectValue, { placeholder: buttonText })
|
|
1615
1786
|
}
|
|
1616
1787
|
),
|
|
1617
|
-
/* @__PURE__ */
|
|
1788
|
+
/* @__PURE__ */ jsx15(SelectContent, { children: filteredItems.map((item) => {
|
|
1618
1789
|
const isActive = isActiveItem(item);
|
|
1619
|
-
return /* @__PURE__ */
|
|
1790
|
+
return /* @__PURE__ */ jsx15(
|
|
1620
1791
|
SelectItem,
|
|
1621
1792
|
{
|
|
1622
1793
|
value: item.id,
|
|
@@ -1631,14 +1802,14 @@ var NavigationMenu = React12.forwardRef(({
|
|
|
1631
1802
|
}
|
|
1632
1803
|
);
|
|
1633
1804
|
}
|
|
1634
|
-
return /* @__PURE__ */
|
|
1805
|
+
return /* @__PURE__ */ jsx15(
|
|
1635
1806
|
"nav",
|
|
1636
1807
|
{
|
|
1637
1808
|
ref,
|
|
1638
1809
|
className,
|
|
1639
1810
|
"aria-label": navigationLabel,
|
|
1640
1811
|
...props,
|
|
1641
|
-
children: /* @__PURE__ */
|
|
1812
|
+
children: /* @__PURE__ */ jsx15("ul", { role: "menubar", children: filteredItems.map((item) => /* @__PURE__ */ jsx15(React13.Fragment, { children: renderHierarchicalItem(item, 0) }, item.id)) })
|
|
1642
1813
|
}
|
|
1643
1814
|
);
|
|
1644
1815
|
});
|
|
@@ -1646,7 +1817,7 @@ NavigationMenu.displayName = "NavigationMenu";
|
|
|
1646
1817
|
|
|
1647
1818
|
// src/components/Header/Header.tsx
|
|
1648
1819
|
import { Link } from "react-router-dom";
|
|
1649
|
-
import { jsx as
|
|
1820
|
+
import { jsx as jsx16, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1650
1821
|
function Header({
|
|
1651
1822
|
logoUrl,
|
|
1652
1823
|
logoAlt = "Logo",
|
|
@@ -1659,37 +1830,38 @@ function Header({
|
|
|
1659
1830
|
userMenu,
|
|
1660
1831
|
className,
|
|
1661
1832
|
showEventSelector = true,
|
|
1833
|
+
showOrgSelector = false,
|
|
1662
1834
|
showUserMenu = true,
|
|
1663
1835
|
currentPath,
|
|
1664
1836
|
onNavigate,
|
|
1665
1837
|
logoHref
|
|
1666
1838
|
}) {
|
|
1667
|
-
return /* @__PURE__ */
|
|
1839
|
+
return /* @__PURE__ */ jsx16("header", { className: cn(
|
|
1668
1840
|
"w-full border-b border-main-200 h-16 shadow-sm bg-main-100 ",
|
|
1669
1841
|
className
|
|
1670
|
-
), role: "banner", children: /* @__PURE__ */
|
|
1671
|
-
logo ? logoHref ? /* @__PURE__ */
|
|
1842
|
+
), role: "banner", children: /* @__PURE__ */ jsxs10("nav", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto grid grid-cols-[auto_auto_1fr_auto] gap-4 h-full items-center", children: [
|
|
1843
|
+
logo ? logoHref ? /* @__PURE__ */ jsx16(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: logo }) : logo : logoUrl ? logoHref ? /* @__PURE__ */ jsx16(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx16(
|
|
1672
1844
|
"img",
|
|
1673
1845
|
{
|
|
1674
1846
|
src: logoUrl,
|
|
1675
1847
|
alt: logoAlt || "Logo",
|
|
1676
1848
|
className: "h-[2.15rem] w-auto max-w-[200px] object-contain rounded-md shadow-md bg-transparent"
|
|
1677
1849
|
}
|
|
1678
|
-
) }) : /* @__PURE__ */
|
|
1850
|
+
) }) : /* @__PURE__ */ jsx16(
|
|
1679
1851
|
"img",
|
|
1680
1852
|
{
|
|
1681
1853
|
src: logoUrl,
|
|
1682
1854
|
alt: logoAlt || "Logo",
|
|
1683
1855
|
className: "h-[2.15rem] w-auto max-w-[200px] object-contain rounded-md shadow-md bg-transparent"
|
|
1684
1856
|
}
|
|
1685
|
-
) : logoHref ? /* @__PURE__ */
|
|
1857
|
+
) : logoHref ? /* @__PURE__ */ jsx16(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx16(
|
|
1686
1858
|
"img",
|
|
1687
1859
|
{
|
|
1688
1860
|
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",
|
|
1689
1861
|
alt: logoAlt || "Logo",
|
|
1690
1862
|
className: "h-8 w-8 shadow-md"
|
|
1691
1863
|
}
|
|
1692
|
-
) }) : /* @__PURE__ */
|
|
1864
|
+
) }) : /* @__PURE__ */ jsx16(
|
|
1693
1865
|
"img",
|
|
1694
1866
|
{
|
|
1695
1867
|
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",
|
|
@@ -1697,7 +1869,7 @@ function Header({
|
|
|
1697
1869
|
className: "h-8 w-8 shadow-md"
|
|
1698
1870
|
}
|
|
1699
1871
|
),
|
|
1700
|
-
navItems && navItems.length > 0 && /* @__PURE__ */
|
|
1872
|
+
navItems && navItems.length > 0 && /* @__PURE__ */ jsx16(
|
|
1701
1873
|
NavigationMenu,
|
|
1702
1874
|
{
|
|
1703
1875
|
items: navItems,
|
|
@@ -1708,30 +1880,43 @@ function Header({
|
|
|
1708
1880
|
itemsPreFiltered: true
|
|
1709
1881
|
}
|
|
1710
1882
|
),
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1883
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-4 justify-end", children: [
|
|
1884
|
+
showOrgSelector ? /* @__PURE__ */ jsx16(
|
|
1885
|
+
OrganisationSelector,
|
|
1886
|
+
{
|
|
1887
|
+
placeholder: "Select organisation",
|
|
1888
|
+
className: "w-64",
|
|
1889
|
+
"data-testid": "org-selector",
|
|
1890
|
+
compact: true
|
|
1891
|
+
}
|
|
1892
|
+
) : null,
|
|
1893
|
+
showEventSelector ? /* @__PURE__ */ jsx16(
|
|
1894
|
+
EventSelector,
|
|
1895
|
+
{
|
|
1896
|
+
placeholder: "Select event",
|
|
1897
|
+
className: "w-96",
|
|
1898
|
+
"data-testid": "event-selector"
|
|
1899
|
+
}
|
|
1900
|
+
) : null
|
|
1901
|
+
] }),
|
|
1902
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-4", children: [
|
|
1903
|
+
actions,
|
|
1904
|
+
showUserMenu && (userMenu ? userMenu : /* @__PURE__ */ jsx16(
|
|
1905
|
+
UserMenu,
|
|
1906
|
+
{
|
|
1907
|
+
user: user || null,
|
|
1908
|
+
onSignOut,
|
|
1909
|
+
onChangePassword,
|
|
1910
|
+
className: "w-70"
|
|
1911
|
+
}
|
|
1912
|
+
))
|
|
1913
|
+
] })
|
|
1729
1914
|
] }) });
|
|
1730
1915
|
}
|
|
1731
1916
|
|
|
1732
1917
|
// src/components/Footer/Footer.tsx
|
|
1733
|
-
import
|
|
1734
|
-
import { Fragment as Fragment3, jsx as
|
|
1918
|
+
import React14 from "react";
|
|
1919
|
+
import { Fragment as Fragment3, jsx as jsx17, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1735
1920
|
var FooterComponent = ({
|
|
1736
1921
|
companyName = "Solvera Solutions Pty Ltd",
|
|
1737
1922
|
year = (/* @__PURE__ */ new Date()).getFullYear(),
|
|
@@ -1742,27 +1927,28 @@ var FooterComponent = ({
|
|
|
1742
1927
|
children
|
|
1743
1928
|
}) => {
|
|
1744
1929
|
const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
|
|
1745
|
-
return /* @__PURE__ */
|
|
1746
|
-
logo && /* @__PURE__ */
|
|
1747
|
-
children && /* @__PURE__ */
|
|
1748
|
-
/* @__PURE__ */
|
|
1749
|
-
links && links.length > 0 && /* @__PURE__ */
|
|
1930
|
+
return /* @__PURE__ */ jsx17("footer", { className: cn("mt-8 py-6 flex justify-center border-t border-border bg-main-100", className), children: /* @__PURE__ */ jsxs11("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
|
|
1931
|
+
logo && /* @__PURE__ */ jsx17("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
|
|
1932
|
+
children && /* @__PURE__ */ jsx17(Fragment3, { children }),
|
|
1933
|
+
/* @__PURE__ */ jsx17("span", { className: "text-muted-foreground", children: copyrightText }),
|
|
1934
|
+
links && links.length > 0 && /* @__PURE__ */ jsx17("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx17("li", { children: /* @__PURE__ */ jsx17("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
|
|
1750
1935
|
] }) });
|
|
1751
1936
|
};
|
|
1752
1937
|
FooterComponent.displayName = "Footer";
|
|
1753
|
-
var Footer =
|
|
1938
|
+
var Footer = React14.memo(FooterComponent);
|
|
1754
1939
|
Footer.displayName = "Footer";
|
|
1755
1940
|
|
|
1756
1941
|
// src/components/PaceAppLayout/PaceAppLayout.tsx
|
|
1757
|
-
import { useState as
|
|
1942
|
+
import { useState as useState6, useEffect as useEffect3, useMemo as useMemo5 } from "react";
|
|
1758
1943
|
import { Outlet, useNavigate, useLocation } from "react-router-dom";
|
|
1759
|
-
import { Fragment as Fragment4, jsx as
|
|
1944
|
+
import { Fragment as Fragment4, jsx as jsx18, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1760
1945
|
var EMPTY_PAGE_ID_MAPPING = {};
|
|
1761
1946
|
var EMPTY_ROUTE_PERMISSIONS = {};
|
|
1762
1947
|
function PaceAppLayout({
|
|
1763
1948
|
appName,
|
|
1764
1949
|
navItems,
|
|
1765
1950
|
showEventSelector,
|
|
1951
|
+
showOrgSelector,
|
|
1766
1952
|
headerActions,
|
|
1767
1953
|
customLogo,
|
|
1768
1954
|
logoHref = "/dashboard",
|
|
@@ -1849,8 +2035,8 @@ function PaceAppLayout({
|
|
|
1849
2035
|
const permissionString = `${currentRoutePermission}:page.${currentPageId}`;
|
|
1850
2036
|
return permissionString;
|
|
1851
2037
|
}, [enforcePermissions, currentRoutePermission, currentPageId]);
|
|
1852
|
-
const [isSuperAdminUser, setIsSuperAdminUser] =
|
|
1853
|
-
const [isCheckingSuperAdmin, setIsCheckingSuperAdmin] =
|
|
2038
|
+
const [isSuperAdminUser, setIsSuperAdminUser] = useState6(false);
|
|
2039
|
+
const [isCheckingSuperAdmin, setIsCheckingSuperAdmin] = useState6(false);
|
|
1854
2040
|
useEffect3(() => {
|
|
1855
2041
|
const checkSuperAdminStatus = async () => {
|
|
1856
2042
|
if (!user?.id) {
|
|
@@ -1904,7 +2090,7 @@ function PaceAppLayout({
|
|
|
1904
2090
|
onPageAccessDenied(currentPageId, currentRoutePermission);
|
|
1905
2091
|
}
|
|
1906
2092
|
}, [enforcePermissions, can, isCheckingPermission, isCheckingSuperAdmin, isSuperAdminUser, currentPageId, currentRoutePermission, user?.id, strictMode, auditLog, onPageAccessDenied, onStrictModeViolation]);
|
|
1907
|
-
const [filteredMenuItems, setFilteredMenuItems] =
|
|
2093
|
+
const [filteredMenuItems, setFilteredMenuItems] = useState6(baseMenuItems);
|
|
1908
2094
|
useEffect3(() => {
|
|
1909
2095
|
let isMounted = true;
|
|
1910
2096
|
const filterItems = async () => {
|
|
@@ -1918,15 +2104,20 @@ function PaceAppLayout({
|
|
|
1918
2104
|
const hasAppId = currentScope.appId || resolvedAppId;
|
|
1919
2105
|
const hasOrganisationContext = currentScope.organisationId;
|
|
1920
2106
|
const hasUser = !!user?.id;
|
|
1921
|
-
if (hasUser
|
|
1922
|
-
} else if (!hasUser || !hasOrganisationContext) {
|
|
2107
|
+
if (!hasUser) {
|
|
1923
2108
|
if (isMounted) {
|
|
1924
|
-
setFilteredMenuItems(
|
|
2109
|
+
setFilteredMenuItems(baseMenuItems);
|
|
2110
|
+
}
|
|
2111
|
+
return;
|
|
2112
|
+
}
|
|
2113
|
+
if (!hasOrganisationContext) {
|
|
2114
|
+
if (isMounted) {
|
|
2115
|
+
setFilteredMenuItems(baseMenuItems);
|
|
1925
2116
|
}
|
|
1926
2117
|
return;
|
|
1927
2118
|
}
|
|
1928
2119
|
try {
|
|
1929
|
-
const { isSuperAdmin: isSuperAdmin2 } = await import("./api-
|
|
2120
|
+
const { isSuperAdmin: isSuperAdmin2 } = await import("./api-BMFCXVQX.js");
|
|
1930
2121
|
const isSuper = await isSuperAdmin2(user.id);
|
|
1931
2122
|
if (isSuper) {
|
|
1932
2123
|
if (isMounted) {
|
|
@@ -1940,14 +2131,8 @@ function PaceAppLayout({
|
|
|
1940
2131
|
throw error;
|
|
1941
2132
|
}
|
|
1942
2133
|
}
|
|
1943
|
-
if (!currentScope.organisationId) {
|
|
1944
|
-
if (isMounted) {
|
|
1945
|
-
setFilteredMenuItems(baseMenuItems);
|
|
1946
|
-
}
|
|
1947
|
-
return;
|
|
1948
|
-
}
|
|
1949
2134
|
try {
|
|
1950
|
-
const { getPermissionMap } = await import("./api-
|
|
2135
|
+
const { getPermissionMap } = await import("./api-BMFCXVQX.js");
|
|
1951
2136
|
const permissionScope = {
|
|
1952
2137
|
organisationId: currentScope.organisationId,
|
|
1953
2138
|
eventId: currentScope.eventId,
|
|
@@ -1960,7 +2145,7 @@ function PaceAppLayout({
|
|
|
1960
2145
|
});
|
|
1961
2146
|
const filtered = baseMenuItems.map((item) => {
|
|
1962
2147
|
if (!item.href) return { item, hasAccess: true };
|
|
1963
|
-
const pageId = pageIdMapping[item.href] || item.href.slice(1) || "
|
|
2148
|
+
const pageId = pageIdMapping[item.href] || (item.href === "/" ? "dashboard" : item.href.slice(1)) || "dashboard";
|
|
1964
2149
|
const permission = routePermissions[item.href] || defaultPermission;
|
|
1965
2150
|
const fullPermission = permission.includes(":") ? permission : pageId ? `${permission}:page.${pageId}` : permission;
|
|
1966
2151
|
const hasAccess = permissionMap["*"] === true || permissionMap[fullPermission] === true;
|
|
@@ -1980,7 +2165,7 @@ function PaceAppLayout({
|
|
|
1980
2165
|
return () => {
|
|
1981
2166
|
isMounted = false;
|
|
1982
2167
|
};
|
|
1983
|
-
}, [baseMenuItems, pageIdMapping, routePermissions, defaultPermission, can, user?.id, scope, scopeLoading, contextAppId, resolvedScope?.appId]);
|
|
2168
|
+
}, [baseMenuItems, pageIdMapping, routePermissions, defaultPermission, can, user?.id, scope, scopeLoading, contextAppId, resolvedScope?.appId, selectedOrganisation?.id]);
|
|
1984
2169
|
useEffect3(() => {
|
|
1985
2170
|
if (!roleBasedRouting || routeConfig.length === 0) return;
|
|
1986
2171
|
let isMounted = true;
|
|
@@ -2003,7 +2188,7 @@ function PaceAppLayout({
|
|
|
2003
2188
|
let hasAccess = true;
|
|
2004
2189
|
if (currentRoute.pageId && currentRoute.permissions && currentRoute.permissions.length > 0) {
|
|
2005
2190
|
try {
|
|
2006
|
-
const { isPermittedCached } = await import("./api-
|
|
2191
|
+
const { isPermittedCached } = await import("./api-BMFCXVQX.js");
|
|
2007
2192
|
const hasPagePermission = await isPermittedCached({
|
|
2008
2193
|
userId: user?.id || "",
|
|
2009
2194
|
scope,
|
|
@@ -2019,7 +2204,7 @@ function PaceAppLayout({
|
|
|
2019
2204
|
}
|
|
2020
2205
|
}
|
|
2021
2206
|
if (hasAccess && currentRoute.roles && currentRoute.roles.length > 0 && user?.id) {
|
|
2022
|
-
const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-
|
|
2207
|
+
const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-A4BCQRJY.js");
|
|
2023
2208
|
hasAccess = true;
|
|
2024
2209
|
}
|
|
2025
2210
|
if (!isMounted) return;
|
|
@@ -2066,31 +2251,31 @@ function PaceAppLayout({
|
|
|
2066
2251
|
return {};
|
|
2067
2252
|
};
|
|
2068
2253
|
if (enforcePermissions && (isCheckingSuperAdmin || isCheckingPermission)) {
|
|
2069
|
-
return /* @__PURE__ */
|
|
2070
|
-
/* @__PURE__ */
|
|
2071
|
-
/* @__PURE__ */
|
|
2254
|
+
return /* @__PURE__ */ jsx18("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs12("div", { className: "text-center", children: [
|
|
2255
|
+
/* @__PURE__ */ jsx18("div", { className: "animate-spin rounded-full h-8 w-8 border-b-2 border-sec-900 mx-auto mb-4" }),
|
|
2256
|
+
/* @__PURE__ */ jsx18("p", { className: "text-sec-600", children: "Checking permissions..." })
|
|
2072
2257
|
] }) });
|
|
2073
2258
|
}
|
|
2074
2259
|
if (enforcePermissions && permissionError && !isSuperAdminUser) {
|
|
2075
|
-
return /* @__PURE__ */
|
|
2076
|
-
/* @__PURE__ */
|
|
2077
|
-
/* @__PURE__ */
|
|
2078
|
-
/* @__PURE__ */
|
|
2260
|
+
return /* @__PURE__ */ jsx18("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs12("div", { className: "text-center", children: [
|
|
2261
|
+
/* @__PURE__ */ jsx18("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Permission Error" }),
|
|
2262
|
+
/* @__PURE__ */ jsx18("p", { className: "text-sec-600 mb-4", children: permissionError.message }),
|
|
2263
|
+
/* @__PURE__ */ jsx18(Button, { onClick: () => navigate("/"), children: "Go Home" })
|
|
2079
2264
|
] }) });
|
|
2080
2265
|
}
|
|
2081
2266
|
if (enforcePermissions && hasPermission === false && !isCheckingSuperAdmin && !isSuperAdminUser) {
|
|
2082
2267
|
if (enforcePagePermissions && pagePermissionFallback) {
|
|
2083
|
-
return /* @__PURE__ */
|
|
2268
|
+
return /* @__PURE__ */ jsx18(Fragment4, { children: pagePermissionFallback });
|
|
2084
2269
|
}
|
|
2085
2270
|
if (permissionFallback) {
|
|
2086
|
-
return /* @__PURE__ */
|
|
2271
|
+
return /* @__PURE__ */ jsx18(Fragment4, { children: permissionFallback });
|
|
2087
2272
|
}
|
|
2088
|
-
return /* @__PURE__ */
|
|
2089
|
-
/* @__PURE__ */
|
|
2090
|
-
/* @__PURE__ */
|
|
2091
|
-
/* @__PURE__ */
|
|
2092
|
-
/* @__PURE__ */
|
|
2093
|
-
/* @__PURE__ */
|
|
2273
|
+
return /* @__PURE__ */ jsx18("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs12("div", { className: "text-center", children: [
|
|
2274
|
+
/* @__PURE__ */ jsx18("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Access Denied" }),
|
|
2275
|
+
/* @__PURE__ */ jsx18("p", { className: "text-sec-600 mb-4", children: "You don't have permission to access this page." }),
|
|
2276
|
+
/* @__PURE__ */ jsxs12("div", { className: "flex gap-2 justify-center", children: [
|
|
2277
|
+
/* @__PURE__ */ jsx18(Button, { onClick: () => navigate("/"), children: "Go Home" }),
|
|
2278
|
+
/* @__PURE__ */ jsx18(
|
|
2094
2279
|
Button,
|
|
2095
2280
|
{
|
|
2096
2281
|
variant: "outline",
|
|
@@ -2104,8 +2289,8 @@ function PaceAppLayout({
|
|
|
2104
2289
|
] })
|
|
2105
2290
|
] }) });
|
|
2106
2291
|
}
|
|
2107
|
-
return /* @__PURE__ */
|
|
2108
|
-
/* @__PURE__ */
|
|
2292
|
+
return /* @__PURE__ */ jsxs12(Fragment4, { children: [
|
|
2293
|
+
/* @__PURE__ */ jsx18(
|
|
2109
2294
|
Header,
|
|
2110
2295
|
{
|
|
2111
2296
|
logo: customLogo || void 0,
|
|
@@ -2125,30 +2310,31 @@ function PaceAppLayout({
|
|
|
2125
2310
|
}
|
|
2126
2311
|
},
|
|
2127
2312
|
showEventSelector,
|
|
2313
|
+
showOrgSelector,
|
|
2128
2314
|
showUserMenu,
|
|
2129
2315
|
className: headerClassName || "sticky top-0 z-[40] w-full"
|
|
2130
2316
|
}
|
|
2131
2317
|
),
|
|
2132
|
-
/* @__PURE__ */
|
|
2133
|
-
/* @__PURE__ */
|
|
2318
|
+
/* @__PURE__ */ jsx18("main", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto py-8", children: /* @__PURE__ */ jsx18(Outlet, {}) }),
|
|
2319
|
+
/* @__PURE__ */ jsx18(Footer, {})
|
|
2134
2320
|
] });
|
|
2135
2321
|
}
|
|
2136
2322
|
|
|
2137
2323
|
// src/components/PaceLoginPage/PaceLoginPage.tsx
|
|
2138
|
-
import { useEffect as useEffect4, useState as
|
|
2324
|
+
import { useEffect as useEffect4, useState as useState7, useContext } from "react";
|
|
2139
2325
|
import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
|
|
2140
|
-
import { jsx as
|
|
2326
|
+
import { jsx as jsx19, jsxs as jsxs13 } from "react/jsx-runtime";
|
|
2141
2327
|
var PaceLoginPage = ({
|
|
2142
2328
|
appName = "Pace",
|
|
2143
|
-
onSuccessRedirectPath = "/
|
|
2329
|
+
onSuccessRedirectPath = "/",
|
|
2144
2330
|
requireAppAccess = false
|
|
2145
2331
|
}) => {
|
|
2146
2332
|
const { signIn, isAuthenticated, isLoading, authError, user, supabase } = useUnifiedAuth();
|
|
2147
2333
|
const navigate = useNavigate2();
|
|
2148
2334
|
const location = useLocation2();
|
|
2149
|
-
const [isSigningIn, setIsSigningIn] =
|
|
2150
|
-
const [accessError, setAccessError] =
|
|
2151
|
-
const [isCheckingAccess, setIsCheckingAccess] =
|
|
2335
|
+
const [isSigningIn, setIsSigningIn] = useState7(false);
|
|
2336
|
+
const [accessError, setAccessError] = useState7(null);
|
|
2337
|
+
const [isCheckingAccess, setIsCheckingAccess] = useState7(false);
|
|
2152
2338
|
const eventServiceContext = useContext(EventServiceContext);
|
|
2153
2339
|
const eventService = eventServiceContext?.eventService || null;
|
|
2154
2340
|
useEffect4(() => {
|
|
@@ -2268,8 +2454,8 @@ var PaceLoginPage = ({
|
|
|
2268
2454
|
setIsSigningIn(false);
|
|
2269
2455
|
}
|
|
2270
2456
|
};
|
|
2271
|
-
return /* @__PURE__ */
|
|
2272
|
-
/* @__PURE__ */
|
|
2457
|
+
return /* @__PURE__ */ jsxs13("main", { className: "min-h-screen grid mx-auto w-fit content-center justify-items-center gap-y-8", "aria-label": `${appName} Login Page`, children: [
|
|
2458
|
+
/* @__PURE__ */ jsx19(
|
|
2273
2459
|
"img",
|
|
2274
2460
|
{
|
|
2275
2461
|
src: `/${appName.toLowerCase()}_logo_square.svg`,
|
|
@@ -2277,7 +2463,7 @@ var PaceLoginPage = ({
|
|
|
2277
2463
|
className: "h-48"
|
|
2278
2464
|
}
|
|
2279
2465
|
),
|
|
2280
|
-
/* @__PURE__ */
|
|
2466
|
+
/* @__PURE__ */ jsx19(
|
|
2281
2467
|
LoginForm,
|
|
2282
2468
|
{
|
|
2283
2469
|
className: "w-md",
|
|
@@ -2291,20 +2477,20 @@ var PaceLoginPage = ({
|
|
|
2291
2477
|
),
|
|
2292
2478
|
(() => {
|
|
2293
2479
|
const benign = !!(authError && (authError.name === "AuthSessionMissingError" || /Auth session missing/i.test(authError.message)));
|
|
2294
|
-
return authError && !benign ? /* @__PURE__ */
|
|
2480
|
+
return authError && !benign ? /* @__PURE__ */ jsx19("em", { className: "mt-4 text-destructive text-center", children: authError.message }) : null;
|
|
2295
2481
|
})(),
|
|
2296
|
-
accessError && /* @__PURE__ */
|
|
2297
|
-
isCheckingAccess && /* @__PURE__ */
|
|
2482
|
+
accessError && /* @__PURE__ */ jsx19("em", { className: "mt-4 text-destructive text-center", children: accessError }),
|
|
2483
|
+
isCheckingAccess && /* @__PURE__ */ jsx19("em", { className: "mt-4 text-muted-foreground text-center", children: "Checking permissions..." })
|
|
2298
2484
|
] });
|
|
2299
2485
|
};
|
|
2300
2486
|
|
|
2301
2487
|
// src/components/SessionRestorationLoader/SessionRestorationLoader.tsx
|
|
2302
|
-
import { jsx as
|
|
2488
|
+
import { jsx as jsx20, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
2303
2489
|
var SessionRestorationLoader = ({
|
|
2304
2490
|
message = "Restoring session...",
|
|
2305
2491
|
className
|
|
2306
2492
|
}) => {
|
|
2307
|
-
return /* @__PURE__ */
|
|
2493
|
+
return /* @__PURE__ */ jsxs14(
|
|
2308
2494
|
"div",
|
|
2309
2495
|
{
|
|
2310
2496
|
className: cn(
|
|
@@ -2315,8 +2501,8 @@ var SessionRestorationLoader = ({
|
|
|
2315
2501
|
"aria-live": "polite",
|
|
2316
2502
|
"aria-label": message,
|
|
2317
2503
|
children: [
|
|
2318
|
-
/* @__PURE__ */
|
|
2319
|
-
/* @__PURE__ */
|
|
2504
|
+
/* @__PURE__ */ jsx20(LoadingSpinner, { size: "lg" }),
|
|
2505
|
+
/* @__PURE__ */ jsx20("div", { className: "text-sm text-sec-600", children: message })
|
|
2320
2506
|
]
|
|
2321
2507
|
}
|
|
2322
2508
|
);
|
|
@@ -2325,16 +2511,19 @@ var SessionRestorationLoader = ({
|
|
|
2325
2511
|
// src/components/ProtectedRoute/ProtectedRoute.tsx
|
|
2326
2512
|
import { useMemo as useMemo6 } from "react";
|
|
2327
2513
|
import { Navigate, Outlet as Outlet2 } from "react-router-dom";
|
|
2328
|
-
import { jsx as
|
|
2514
|
+
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2329
2515
|
function ProtectedRoute({
|
|
2330
|
-
requireEvent =
|
|
2516
|
+
requireEvent = false,
|
|
2331
2517
|
allowSuperAdminBypass = false,
|
|
2332
2518
|
noEventsFallback,
|
|
2333
2519
|
loadingFallback,
|
|
2334
2520
|
loginPath = "/login"
|
|
2335
2521
|
}) {
|
|
2336
|
-
const { isAuthenticated,
|
|
2337
|
-
const
|
|
2522
|
+
const { isAuthenticated, isLoading } = useUnifiedAuth();
|
|
2523
|
+
const eventsContext = useEvents();
|
|
2524
|
+
const selectedEvent = requireEvent ? eventsContext.selectedEvent : null;
|
|
2525
|
+
const events = requireEvent ? eventsContext.events || [] : [];
|
|
2526
|
+
const eventLoading = requireEvent ? eventsContext.isLoading || false : false;
|
|
2338
2527
|
const sessionRestoration = useSessionRestoration();
|
|
2339
2528
|
const isRestoringSession = useMemo6(() => {
|
|
2340
2529
|
return sessionRestoration.isRestoring && !sessionRestoration.restorationComplete && !sessionRestoration.restorationError && !sessionRestoration.hasTimedOut;
|
|
@@ -2345,13 +2534,13 @@ function ProtectedRoute({
|
|
|
2345
2534
|
sessionRestoration.hasTimedOut
|
|
2346
2535
|
]);
|
|
2347
2536
|
if (isRestoringSession) {
|
|
2348
|
-
return /* @__PURE__ */
|
|
2537
|
+
return /* @__PURE__ */ jsx21(SessionRestorationLoader, {});
|
|
2349
2538
|
}
|
|
2350
2539
|
if (requireEvent && eventLoading) {
|
|
2351
|
-
return /* @__PURE__ */
|
|
2540
|
+
return /* @__PURE__ */ jsx21(Outlet2, {});
|
|
2352
2541
|
}
|
|
2353
|
-
if (
|
|
2354
|
-
return loadingFallback || /* @__PURE__ */
|
|
2542
|
+
if (isLoading && !sessionRestoration.hasTimedOut) {
|
|
2543
|
+
return loadingFallback || /* @__PURE__ */ jsx21("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", height: "100vh" }, children: /* @__PURE__ */ jsx21(LoadingSpinner, {}) });
|
|
2355
2544
|
}
|
|
2356
2545
|
if (!isAuthenticated) {
|
|
2357
2546
|
if (sessionRestoration.hasTimedOut || sessionRestoration.restorationError) {
|
|
@@ -2360,193 +2549,22 @@ function ProtectedRoute({
|
|
|
2360
2549
|
error: sessionRestoration.restorationError?.message
|
|
2361
2550
|
});
|
|
2362
2551
|
}
|
|
2363
|
-
return /* @__PURE__ */
|
|
2552
|
+
return /* @__PURE__ */ jsx21(Navigate, { to: loginPath, replace: true });
|
|
2364
2553
|
}
|
|
2365
2554
|
if (!requireEvent) {
|
|
2366
|
-
return /* @__PURE__ */
|
|
2555
|
+
return /* @__PURE__ */ jsx21(Outlet2, {});
|
|
2367
2556
|
}
|
|
2368
2557
|
if (!events || events.length === 0) {
|
|
2369
|
-
return noEventsFallback || /* @__PURE__ */
|
|
2370
|
-
/* @__PURE__ */
|
|
2371
|
-
/* @__PURE__ */
|
|
2558
|
+
return noEventsFallback || /* @__PURE__ */ jsx21("div", { style: { display: "flex", justifyContent: "center", alignItems: "center", minHeight: "100vh", padding: "2rem" }, children: /* @__PURE__ */ jsxs15(Alert, { variant: "destructive", className: "max-w-md", children: [
|
|
2559
|
+
/* @__PURE__ */ jsx21(AlertTitle, { children: "No Events Available" }),
|
|
2560
|
+
/* @__PURE__ */ jsx21(AlertDescription, { children: "You don't have access to any events. Please contact your administrator if you believe this is an error." })
|
|
2372
2561
|
] }) });
|
|
2373
2562
|
}
|
|
2374
2563
|
if (!selectedEvent) {
|
|
2375
2564
|
logger.debug("ProtectedRoute", "Events available but none selected - allowing render so selector is visible");
|
|
2376
|
-
return /* @__PURE__ */
|
|
2565
|
+
return /* @__PURE__ */ jsx21(Outlet2, {});
|
|
2377
2566
|
}
|
|
2378
|
-
return /* @__PURE__ */
|
|
2379
|
-
}
|
|
2380
|
-
|
|
2381
|
-
// src/components/OrganisationSelector/OrganisationSelector.tsx
|
|
2382
|
-
import { useState as useState7, useCallback as useCallback4 } from "react";
|
|
2383
|
-
import { RefreshCw as RefreshCw2, AlertCircle as AlertCircle2, Building2, Shield } from "lucide-react";
|
|
2384
|
-
import { jsx as jsx21, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2385
|
-
function OrganisationSelector({
|
|
2386
|
-
placeholder = "Select organisation",
|
|
2387
|
-
className,
|
|
2388
|
-
onOrganisationChange,
|
|
2389
|
-
showNoOrganisationsMessage = true,
|
|
2390
|
-
showRetryButton = true,
|
|
2391
|
-
showRole = false,
|
|
2392
|
-
compact = false,
|
|
2393
|
-
disabled = false
|
|
2394
|
-
}) {
|
|
2395
|
-
const [isLoading, setIsLoading] = useState7(false);
|
|
2396
|
-
const [switchError, setSwitchError] = useState7(null);
|
|
2397
|
-
const {
|
|
2398
|
-
organisations,
|
|
2399
|
-
selectedOrganisation,
|
|
2400
|
-
isLoading: orgLoading,
|
|
2401
|
-
error: orgError,
|
|
2402
|
-
switchOrganisation,
|
|
2403
|
-
getUserRole,
|
|
2404
|
-
validateOrganisationAccess,
|
|
2405
|
-
refreshOrganisations
|
|
2406
|
-
} = useOrganisations();
|
|
2407
|
-
const handleOrganisationChange = useCallback4(async (orgId) => {
|
|
2408
|
-
if (disabled || isLoading) return;
|
|
2409
|
-
setSwitchError(null);
|
|
2410
|
-
setIsLoading(true);
|
|
2411
|
-
try {
|
|
2412
|
-
if (!validateOrganisationAccess(orgId)) {
|
|
2413
|
-
throw new Error("You do not have access to this organisation");
|
|
2414
|
-
}
|
|
2415
|
-
await switchOrganisation(orgId);
|
|
2416
|
-
const newOrganisation = organisations.find((org) => org.id === orgId);
|
|
2417
|
-
if (newOrganisation && onOrganisationChange) {
|
|
2418
|
-
onOrganisationChange(newOrganisation);
|
|
2419
|
-
}
|
|
2420
|
-
logger.debug("OrganisationSelector", "Successfully switched to organisation:", orgId);
|
|
2421
|
-
} catch (error) {
|
|
2422
|
-
logger.error("OrganisationSelector", "Failed to switch organisation:", error);
|
|
2423
|
-
setSwitchError(error instanceof Error ? error.message : "Failed to switch organisation");
|
|
2424
|
-
} finally {
|
|
2425
|
-
setIsLoading(false);
|
|
2426
|
-
}
|
|
2427
|
-
}, [
|
|
2428
|
-
disabled,
|
|
2429
|
-
isLoading,
|
|
2430
|
-
validateOrganisationAccess,
|
|
2431
|
-
switchOrganisation,
|
|
2432
|
-
organisations,
|
|
2433
|
-
onOrganisationChange
|
|
2434
|
-
]);
|
|
2435
|
-
const handleRetry = useCallback4(async () => {
|
|
2436
|
-
setIsLoading(true);
|
|
2437
|
-
setSwitchError(null);
|
|
2438
|
-
try {
|
|
2439
|
-
await refreshOrganisations();
|
|
2440
|
-
} catch (error) {
|
|
2441
|
-
logger.error("OrganisationSelector", "Failed to refresh organisations:", error);
|
|
2442
|
-
setSwitchError("Failed to refresh organisations");
|
|
2443
|
-
} finally {
|
|
2444
|
-
setIsLoading(false);
|
|
2445
|
-
}
|
|
2446
|
-
}, [refreshOrganisations]);
|
|
2447
|
-
if (orgLoading) {
|
|
2448
|
-
return /* @__PURE__ */ jsxs15("div", { className: `flex items-center gap-2 ${className}`, children: [
|
|
2449
|
-
/* @__PURE__ */ jsx21(LoadingSpinner, { size: "sm" }),
|
|
2450
|
-
/* @__PURE__ */ jsx21("span", { className: "text-sm text-muted-foreground", children: compact ? "Loading..." : "Loading organisations..." })
|
|
2451
|
-
] });
|
|
2452
|
-
}
|
|
2453
|
-
if (orgError) {
|
|
2454
|
-
return /* @__PURE__ */ jsxs15("div", { className: `space-y-2 ${className}`, children: [
|
|
2455
|
-
/* @__PURE__ */ jsxs15(Alert, { variant: "destructive", children: [
|
|
2456
|
-
/* @__PURE__ */ jsx21(AlertCircle2, { className: "h-4 w-4" }),
|
|
2457
|
-
/* @__PURE__ */ jsxs15(AlertDescription, { children: [
|
|
2458
|
-
"Failed to load organisations: ",
|
|
2459
|
-
orgError.message
|
|
2460
|
-
] })
|
|
2461
|
-
] }),
|
|
2462
|
-
showRetryButton && /* @__PURE__ */ jsxs15(
|
|
2463
|
-
Button,
|
|
2464
|
-
{
|
|
2465
|
-
variant: "outline",
|
|
2466
|
-
size: "sm",
|
|
2467
|
-
onClick: handleRetry,
|
|
2468
|
-
disabled: isLoading,
|
|
2469
|
-
className: "w-full",
|
|
2470
|
-
children: [
|
|
2471
|
-
/* @__PURE__ */ jsx21(RefreshCw2, { className: `h-4 w-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
2472
|
-
"Retry"
|
|
2473
|
-
]
|
|
2474
|
-
}
|
|
2475
|
-
)
|
|
2476
|
-
] });
|
|
2477
|
-
}
|
|
2478
|
-
if (organisations.length === 0) {
|
|
2479
|
-
if (showNoOrganisationsMessage) {
|
|
2480
|
-
return /* @__PURE__ */ jsxs15("div", { className: `space-y-2 ${className}`, children: [
|
|
2481
|
-
/* @__PURE__ */ jsxs15(Alert, { children: [
|
|
2482
|
-
/* @__PURE__ */ jsx21(Building2, { className: "h-4 w-4" }),
|
|
2483
|
-
/* @__PURE__ */ jsx21(AlertDescription, { children: "No organisations available. Please contact your administrator to be added to an organisation." })
|
|
2484
|
-
] }),
|
|
2485
|
-
showRetryButton && /* @__PURE__ */ jsxs15(
|
|
2486
|
-
Button,
|
|
2487
|
-
{
|
|
2488
|
-
variant: "outline",
|
|
2489
|
-
size: "sm",
|
|
2490
|
-
onClick: handleRetry,
|
|
2491
|
-
disabled: isLoading,
|
|
2492
|
-
className: "w-full",
|
|
2493
|
-
children: [
|
|
2494
|
-
/* @__PURE__ */ jsx21(RefreshCw2, { className: `h-4 w-4 mr-2 ${isLoading ? "animate-spin" : ""}` }),
|
|
2495
|
-
"Check Again"
|
|
2496
|
-
]
|
|
2497
|
-
}
|
|
2498
|
-
)
|
|
2499
|
-
] });
|
|
2500
|
-
}
|
|
2501
|
-
return null;
|
|
2502
|
-
}
|
|
2503
|
-
const switchErrorDisplay = switchError && /* @__PURE__ */ jsxs15(Alert, { variant: "destructive", className: "mt-2", children: [
|
|
2504
|
-
/* @__PURE__ */ jsx21(AlertCircle2, { className: "h-4 w-4" }),
|
|
2505
|
-
/* @__PURE__ */ jsx21(AlertDescription, { children: switchError })
|
|
2506
|
-
] });
|
|
2507
|
-
return /* @__PURE__ */ jsxs15("div", { className: `space-y-2 ${className}`, children: [
|
|
2508
|
-
/* @__PURE__ */ jsxs15(
|
|
2509
|
-
Select,
|
|
2510
|
-
{
|
|
2511
|
-
value: selectedOrganisation?.id || "",
|
|
2512
|
-
onValueChange: handleOrganisationChange,
|
|
2513
|
-
disabled: disabled || isLoading || !selectedOrganisation,
|
|
2514
|
-
children: [
|
|
2515
|
-
/* @__PURE__ */ jsx21(SelectTrigger, { className: `${isLoading ? "opacity-50" : ""}`, children: /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
2516
|
-
isLoading ? /* @__PURE__ */ jsx21(LoadingSpinner, { size: "sm" }) : /* @__PURE__ */ jsx21(Building2, { className: "h-4 w-4 text-muted-foreground" }),
|
|
2517
|
-
/* @__PURE__ */ jsx21(SelectValue, { placeholder })
|
|
2518
|
-
] }) }),
|
|
2519
|
-
/* @__PURE__ */ jsx21(SelectContent, { children: organisations.map((org) => {
|
|
2520
|
-
const userRole = getUserRole(org.id);
|
|
2521
|
-
const hasAccess = validateOrganisationAccess(org.id);
|
|
2522
|
-
return /* @__PURE__ */ jsx21(
|
|
2523
|
-
SelectItem,
|
|
2524
|
-
{
|
|
2525
|
-
value: org.id,
|
|
2526
|
-
disabled: !hasAccess,
|
|
2527
|
-
className: !hasAccess ? "opacity-50" : "",
|
|
2528
|
-
children: /* @__PURE__ */ jsxs15("div", { className: "flex items-center justify-between w-full", children: [
|
|
2529
|
-
/* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
|
|
2530
|
-
/* @__PURE__ */ jsx21(Building2, { className: "h-4 w-4" }),
|
|
2531
|
-
/* @__PURE__ */ jsxs15("div", { className: "flex flex-col", children: [
|
|
2532
|
-
/* @__PURE__ */ jsx21("span", { className: "font-medium", children: org.display_name }),
|
|
2533
|
-
!compact && org.description && /* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground truncate max-w-40", children: org.description })
|
|
2534
|
-
] })
|
|
2535
|
-
] }),
|
|
2536
|
-
showRole && /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-1 ml-4", children: [
|
|
2537
|
-
/* @__PURE__ */ jsx21(Shield, { className: "h-3 w-3 text-muted-foreground" }),
|
|
2538
|
-
/* @__PURE__ */ jsx21("span", { className: "text-xs text-muted-foreground capitalize", children: userRole?.replace("_", " ") || "No Role" })
|
|
2539
|
-
] })
|
|
2540
|
-
] })
|
|
2541
|
-
},
|
|
2542
|
-
org.id
|
|
2543
|
-
);
|
|
2544
|
-
}) })
|
|
2545
|
-
]
|
|
2546
|
-
}
|
|
2547
|
-
),
|
|
2548
|
-
switchErrorDisplay
|
|
2549
|
-
] });
|
|
2567
|
+
return /* @__PURE__ */ jsx21(Outlet2, {});
|
|
2550
2568
|
}
|
|
2551
2569
|
|
|
2552
2570
|
// src/hooks/useFileReference.ts
|
|
@@ -2897,6 +2915,7 @@ function FileUpload({
|
|
|
2897
2915
|
organisation_id,
|
|
2898
2916
|
app_id,
|
|
2899
2917
|
category,
|
|
2918
|
+
pageContext,
|
|
2900
2919
|
accept = "*/*",
|
|
2901
2920
|
maxSize = 10 * 1024 * 1024,
|
|
2902
2921
|
// 10MB default
|
|
@@ -3084,6 +3103,7 @@ function FileUpload({
|
|
|
3084
3103
|
organisation_id,
|
|
3085
3104
|
app_id: resolvedAppId ? assertAppId(resolvedAppId) : assertAppId(""),
|
|
3086
3105
|
category,
|
|
3106
|
+
pageContext,
|
|
3087
3107
|
is_public: isPublic
|
|
3088
3108
|
}, file);
|
|
3089
3109
|
clearInterval(progressInterval);
|
|
@@ -4231,6 +4251,7 @@ export {
|
|
|
4231
4251
|
FormField,
|
|
4232
4252
|
LoginForm,
|
|
4233
4253
|
EventSelector,
|
|
4254
|
+
OrganisationSelector,
|
|
4234
4255
|
PasswordChangeForm,
|
|
4235
4256
|
UserMenu,
|
|
4236
4257
|
NavigationMenu,
|
|
@@ -4240,7 +4261,6 @@ export {
|
|
|
4240
4261
|
PaceLoginPage,
|
|
4241
4262
|
SessionRestorationLoader,
|
|
4242
4263
|
ProtectedRoute,
|
|
4243
|
-
OrganisationSelector,
|
|
4244
4264
|
useFileReference,
|
|
4245
4265
|
useFileReferenceForRecord,
|
|
4246
4266
|
useFileReferenceById,
|
|
@@ -4259,4 +4279,4 @@ export {
|
|
|
4259
4279
|
PublicPageFooter,
|
|
4260
4280
|
PublicPageLayout
|
|
4261
4281
|
};
|
|
4262
|
-
//# sourceMappingURL=chunk-
|
|
4282
|
+
//# sourceMappingURL=chunk-HC67NW5K.js.map
|