@jmruthers/pace-core 0.5.193 → 0.6.2
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 +62 -0
- package/README.md +7 -1
- package/cursor-rules/00-pace-core-compliance.mdc +299 -0
- package/cursor-rules/01-standards-compliance.mdc +244 -0
- package/cursor-rules/02-project-structure.mdc +200 -0
- package/cursor-rules/03-solid-principles.mdc +222 -0
- package/cursor-rules/04-testing-standards.mdc +268 -0
- package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
- package/cursor-rules/06-code-quality.mdc +309 -0
- package/cursor-rules/07-tech-stack-compliance.mdc +214 -0
- package/cursor-rules/08-markup-quality.mdc +452 -0
- package/cursor-rules/CHANGELOG.md +119 -0
- package/cursor-rules/README.md +192 -0
- package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-BPvc3Ka0.d.ts} +54 -0
- package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-BMRU8a1j.d.ts} +34 -2
- package/dist/{DataTable-5FU7IESH.js → DataTable-TPTKCX4D.js} +10 -9
- package/dist/{PublicPageProvider-C0Sm_e5k.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +385 -261
- package/dist/{UnifiedAuthProvider-RGJTDE2C.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
- package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
- package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
- package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
- package/dist/chunk-24UVZUZG.js.map +1 -0
- package/dist/{chunk-HWIIPPNI.js → chunk-2UOI2FG5.js} +20 -20
- package/dist/chunk-2UOI2FG5.js.map +1 -0
- package/dist/{chunk-E3SPN4VZ 5.js → chunk-3XC4CPTD.js} +4345 -3986
- package/dist/chunk-3XC4CPTD.js.map +1 -0
- package/dist/{chunk-7EQTDTTJ.js → chunk-6J4GEEJR.js} +172 -45
- package/dist/chunk-6J4GEEJR.js.map +1 -0
- package/dist/{chunk-6C4YBBJM 5.js → chunk-6SOIHG6Z.js} +1 -1
- package/dist/chunk-6SOIHG6Z.js.map +1 -0
- package/dist/{chunk-7FLMSG37.js → chunk-EHMR7VYL.js} +25 -25
- package/dist/chunk-EHMR7VYL.js.map +1 -0
- package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
- package/dist/chunk-F2IMUDXZ.js.map +1 -0
- package/dist/{chunk-QWWZ5CAQ.js → chunk-FFQEQTNW.js} +7 -9
- package/dist/chunk-FFQEQTNW.js.map +1 -0
- package/dist/chunk-FMUCXFII.js +76 -0
- package/dist/chunk-FMUCXFII.js.map +1 -0
- package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
- package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
- package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
- package/dist/chunk-L4OXEN46.js.map +1 -0
- package/dist/{chunk-R77UEZ4E 3.js → chunk-M43Y4SSO.js} +1 -1
- package/dist/chunk-M43Y4SSO.js.map +1 -0
- package/dist/{chunk-IIELH4DL.js → chunk-MMZ7JXPU.js} +60 -223
- package/dist/chunk-MMZ7JXPU.js.map +1 -0
- package/dist/{chunk-NOAYCWCX 5.js → chunk-NECFR5MM.js} +394 -312
- package/dist/chunk-NECFR5MM.js.map +1 -0
- package/dist/{chunk-BC4IJKSL.js → chunk-SFZUDBL5.js} +40 -4
- package/dist/chunk-SFZUDBL5.js.map +1 -0
- package/dist/{chunk-XNXXZ43G.js → chunk-XWQCNGTQ.js} +748 -364
- package/dist/chunk-XWQCNGTQ.js.map +1 -0
- package/dist/components.d.ts +6 -6
- package/dist/components.js +15 -12
- package/dist/components.js.map +1 -1
- package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
- package/dist/hooks.d.ts +59 -126
- package/dist/hooks.js +19 -28
- package/dist/hooks.js.map +1 -1
- package/dist/index.d.ts +63 -16
- package/dist/index.js +23 -24
- package/dist/index.js.map +1 -1
- package/dist/providers.d.ts +21 -3
- package/dist/providers.js +2 -2
- package/dist/rbac/index.d.ts +146 -115
- package/dist/rbac/index.js +8 -11
- package/dist/theming/runtime.d.ts +1 -13
- package/dist/theming/runtime.js +1 -1
- package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
- package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
- package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
- package/dist/types.d.ts +2 -2
- package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +34 -4
- package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
- package/dist/utils.d.ts +4 -5
- package/dist/utils.js +15 -15
- package/dist/utils.js.map +1 -1
- package/docs/api/README.md +7 -1
- package/docs/api/classes/ColumnFactory.md +8 -8
- package/docs/api/classes/InvalidScopeError.md +4 -4
- package/docs/api/classes/Logger.md +1 -1
- package/docs/api/classes/MissingUserContextError.md +4 -4
- package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
- package/docs/api/classes/PermissionDeniedError.md +4 -4
- package/docs/api/classes/RBACAuditManager.md +1 -1
- package/docs/api/classes/RBACCache.md +1 -1
- package/docs/api/classes/RBACEngine.md +1 -1
- package/docs/api/classes/RBACError.md +4 -4
- package/docs/api/classes/RBACNotInitializedError.md +4 -4
- package/docs/api/classes/SecureSupabaseClient.md +18 -15
- package/docs/api/classes/StorageUtils.md +1 -1
- package/docs/api/enums/FileCategory.md +1 -1
- package/docs/api/enums/LogLevel.md +1 -1
- package/docs/api/enums/RBACErrorCode.md +1 -1
- package/docs/api/enums/RPCFunction.md +1 -1
- package/docs/api/interfaces/AddressFieldProps.md +1 -1
- package/docs/api/interfaces/AddressFieldRef.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +4 -4
- package/docs/api/interfaces/AutocompleteOptions.md +1 -1
- package/docs/api/interfaces/AvatarProps.md +1 -1
- package/docs/api/interfaces/BadgeProps.md +9 -2
- package/docs/api/interfaces/ButtonProps.md +7 -4
- package/docs/api/interfaces/CalendarProps.md +8 -5
- package/docs/api/interfaces/CardProps.md +8 -5
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/ComplianceResult.md +1 -1
- package/docs/api/interfaces/DataAccessRecord.md +9 -9
- package/docs/api/interfaces/DataRecord.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +24 -21
- package/docs/api/interfaces/DataTableColumn.md +31 -31
- package/docs/api/interfaces/DataTableProps.md +1 -1
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
- package/docs/api/interfaces/DatabaseIssue.md +1 -1
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
- package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
- package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
- package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
- package/docs/api/interfaces/EventAppRoleData.md +1 -1
- package/docs/api/interfaces/ExportColumn.md +1 -1
- package/docs/api/interfaces/ExportOptions.md +8 -8
- package/docs/api/interfaces/FileDisplayProps.md +1 -1
- package/docs/api/interfaces/FileMetadata.md +1 -1
- package/docs/api/interfaces/FileReference.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadOptions.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +26 -23
- package/docs/api/interfaces/FooterProps.md +10 -8
- package/docs/api/interfaces/FormFieldProps.md +10 -10
- package/docs/api/interfaces/FormProps.md +1 -1
- package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +7 -4
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoggerConfig.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +14 -11
- 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 +11 -11
- package/docs/api/interfaces/NavigationMenuProps.md +15 -15
- 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 +30 -27
- package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
- package/docs/api/interfaces/PageAccessRecord.md +1 -1
- package/docs/api/interfaces/PagePermissionContextType.md +1 -1
- package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
- package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/ParsedAddress.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 +7 -26
- package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
- package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
- package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
- package/docs/api/interfaces/QuickFix.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
- package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
- package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
- package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
- package/docs/api/interfaces/RBACConfig.md +1 -1
- package/docs/api/interfaces/RBACContext.md +1 -1
- package/docs/api/interfaces/RBACLogger.md +1 -1
- package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
- package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
- package/docs/api/interfaces/RBACResult.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
- package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
- package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
- package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
- package/docs/api/interfaces/RBACRolesListParams.md +1 -1
- package/docs/api/interfaces/RBACRolesListResult.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
- package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
- package/docs/api/interfaces/ResourcePermissions.md +1 -1
- package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
- package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
- package/docs/api/interfaces/RoleManagementResult.md +1 -1
- package/docs/api/interfaces/RouteAccessRecord.md +1 -1
- package/docs/api/interfaces/RouteConfig.md +1 -1
- package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
- package/docs/api/interfaces/SecureDataContextType.md +9 -9
- package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
- package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
- package/docs/api/interfaces/SetupIssue.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/SwitchProps.md +1 -1
- package/docs/api/interfaces/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 +3 -3
- package/docs/api/interfaces/TextareaProps.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +4 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
- package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
- package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
- package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
- package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
- package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
- package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
- package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
- package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
- package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +14 -11
- package/docs/api/interfaces/UserMenuProps.md +8 -6
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +575 -634
- package/docs/architecture/database-schema-requirements.md +161 -0
- package/docs/core-concepts/rbac-system.md +3 -3
- package/docs/documentation-index.md +2 -4
- package/docs/getting-started/cursor-rules.md +263 -0
- package/docs/getting-started/installation-guide.md +6 -1
- package/docs/getting-started/quick-start.md +6 -1
- package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
- package/docs/migration/MIGRATION_GUIDE.md +6 -28
- package/docs/migration/README.md +52 -6
- package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
- package/docs/migration/V0.6.0_REACT_19_MIGRATION.md +227 -0
- package/docs/migration/database-changes-december-2025.md +3 -3
- package/docs/rbac/event-based-apps.md +1 -1
- package/docs/rbac/getting-started.md +1 -1
- package/docs/rbac/quick-start.md +1 -1
- package/docs/standards/README.md +40 -0
- package/docs/troubleshooting/migration.md +4 -4
- package/examples/PublicPages/PublicEventPage.tsx +1 -1
- package/package.json +12 -6
- package/scripts/audit/core/checks/accessibility.cjs +197 -0
- package/scripts/audit/core/checks/api-usage.cjs +191 -0
- package/scripts/audit/core/checks/bundle.cjs +142 -0
- package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +737 -691
- package/scripts/audit/core/checks/config.cjs +54 -0
- package/scripts/audit/core/checks/coverage.cjs +84 -0
- package/scripts/audit/core/checks/dependencies.cjs +454 -0
- package/scripts/audit/core/checks/documentation.cjs +203 -0
- package/scripts/audit/core/checks/environment.cjs +128 -0
- package/scripts/audit/core/checks/error-handling.cjs +299 -0
- package/scripts/audit/core/checks/forms.cjs +172 -0
- package/scripts/audit/core/checks/heuristics.cjs +68 -0
- package/scripts/audit/core/checks/hooks.cjs +334 -0
- package/scripts/audit/core/checks/imports.cjs +244 -0
- package/scripts/audit/core/checks/performance.cjs +325 -0
- package/scripts/audit/core/checks/routes.cjs +117 -0
- package/scripts/audit/core/checks/state.cjs +130 -0
- package/scripts/audit/core/checks/structure.cjs +65 -0
- package/scripts/audit/core/checks/style.cjs +584 -0
- package/scripts/audit/core/checks/testing.cjs +122 -0
- package/scripts/audit/core/checks/typescript.cjs +61 -0
- package/scripts/audit/core/scanner.cjs +199 -0
- package/scripts/audit/core/utils.cjs +137 -0
- package/scripts/audit/index.cjs +223 -0
- package/scripts/audit/reporters/console.cjs +151 -0
- package/scripts/audit/reporters/json.cjs +54 -0
- package/scripts/audit/reporters/markdown.cjs +124 -0
- package/scripts/audit-consuming-app.cjs +86 -0
- package/scripts/build-docs/build-decision.js +240 -0
- package/scripts/build-docs/cache-utils.js +105 -0
- package/scripts/build-docs/content-normalization.js +150 -0
- package/scripts/build-docs/file-utils.js +105 -0
- package/scripts/build-docs/git-utils.js +86 -0
- package/scripts/build-docs/hash-utils.js +116 -0
- package/scripts/build-docs/typedoc-runner.js +220 -0
- package/scripts/build-docs-incremental.js +77 -913
- package/scripts/install-cursor-rules.cjs +236 -0
- package/scripts/utils/command-runner.js +16 -11
- package/scripts/validate-formats.js +61 -56
- package/scripts/validate-master.js +74 -69
- package/scripts/validate-pre-publish.js +70 -65
- package/src/__tests__/helpers/test-providers.tsx +1 -1
- package/src/__tests__/helpers/test-utils.tsx +1 -1
- package/src/__tests__/hooks/usePermissions.test.ts +2 -2
- package/src/components/Alert/Alert.test.tsx +12 -18
- package/src/components/Alert/Alert.tsx +5 -7
- package/src/components/Avatar/Avatar.test.tsx +4 -4
- package/src/components/Badge/Badge.tsx +16 -4
- package/src/components/Button/Button.tsx +27 -4
- package/src/components/Calendar/Calendar.tsx +9 -3
- package/src/components/Card/Card.tsx +4 -0
- package/src/components/Checkbox/Checkbox.test.tsx +12 -12
- package/src/components/Checkbox/Checkbox.tsx +2 -2
- package/src/components/DataTable/DataTable.test.tsx +57 -93
- package/src/components/DataTable/DataTable.tsx +40 -6
- package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
- package/src/components/DataTable/__tests__/pagination.modes.test.tsx +29 -7
- package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
- package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
- package/src/components/DataTable/components/AccessDeniedPage.tsx +17 -26
- package/src/components/DataTable/components/ActionButtons.tsx +10 -7
- package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
- package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
- package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
- package/src/components/DataTable/components/DataTableBody.tsx +8 -0
- package/src/components/DataTable/components/DataTableCore.tsx +200 -561
- package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
- package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
- package/src/components/DataTable/components/DataTableModals.tsx +9 -1
- package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
- package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
- package/src/components/DataTable/components/EditFields.tsx +307 -0
- package/src/components/DataTable/components/EditableRow.tsx +9 -1
- package/src/components/DataTable/components/EmptyState.tsx +10 -0
- package/src/components/DataTable/components/FilterRow.tsx +12 -0
- package/src/components/DataTable/components/GroupHeader.tsx +12 -0
- package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
- package/src/components/DataTable/components/ImportModal.tsx +7 -0
- package/src/components/DataTable/components/LoadingState.tsx +6 -0
- package/src/components/DataTable/components/PaginationControls.tsx +16 -1
- package/src/components/DataTable/components/RowComponent.tsx +391 -0
- package/src/components/DataTable/components/UnifiedTableBody.tsx +62 -852
- package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
- package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
- package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
- package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
- package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
- package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
- package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
- package/src/components/DataTable/components/cellValueUtils.ts +40 -0
- package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
- package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
- package/src/components/DataTable/context/DataTableContext.tsx +50 -0
- package/src/components/DataTable/core/ColumnFactory.ts +31 -0
- package/src/components/DataTable/core/DataTableContext.tsx +32 -1
- package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
- package/src/components/DataTable/hooks/useColumnReordering.ts +14 -2
- package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
- package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
- package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
- package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
- package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
- package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
- package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
- package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
- package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
- package/src/components/DataTable/styles.ts +6 -6
- package/src/components/DataTable/types.ts +6 -10
- package/src/components/DataTable/utils/a11yUtils.ts +7 -0
- package/src/components/DataTable/utils/debugTools.ts +18 -113
- package/src/components/DataTable/utils/errorHandling.ts +12 -0
- package/src/components/DataTable/utils/exportUtils.ts +9 -0
- package/src/components/DataTable/utils/flexibleImport.ts +12 -48
- package/src/components/DataTable/utils/paginationUtils.ts +8 -0
- package/src/components/DataTable/utils/performanceUtils.ts +5 -1
- package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
- package/src/components/Dialog/Dialog.tsx +8 -7
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +46 -6
- package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
- package/src/components/ErrorBoundary/index.ts +27 -2
- package/src/components/EventSelector/EventSelector.tsx +4 -1
- package/src/components/FileDisplay/FileDisplay.test.tsx +2 -2
- package/src/components/FileDisplay/FileDisplay.tsx +32 -18
- package/src/components/FileUpload/FileUpload.tsx +22 -2
- package/src/components/Footer/Footer.test.tsx +16 -16
- package/src/components/Footer/Footer.tsx +15 -12
- package/src/components/Form/Form.test.tsx +36 -15
- package/src/components/Form/Form.tsx +31 -26
- package/src/components/Header/Header.tsx +22 -11
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
- package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
- package/src/components/Input/Input.test.tsx +2 -2
- package/src/components/Input/Input.tsx +36 -34
- package/src/components/Label/Label.tsx +1 -1
- package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
- package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
- package/src/components/LoginForm/LoginForm.test.tsx +42 -42
- package/src/components/LoginForm/LoginForm.tsx +12 -8
- package/src/components/NavigationMenu/NavigationMenu.tsx +15 -514
- package/src/components/NavigationMenu/types.ts +56 -0
- package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
- package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
- package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
- package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +54 -52
- package/src/components/PaceAppLayout/PaceAppLayout.tsx +33 -12
- package/src/components/PaceAppLayout/README.md +1 -1
- package/src/components/PaceAppLayout/test-setup.tsx +1 -2
- package/src/components/PaceLoginPage/PaceLoginPage.tsx +4 -1
- package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
- package/src/components/PasswordChange/PasswordChangeForm.tsx +10 -1
- package/src/components/Progress/Progress.tsx +1 -1
- package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
- package/src/components/PublicLayout/PublicPageLayout.tsx +3 -6
- package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
- package/src/components/Select/Select.tsx +95 -438
- package/src/components/Select/context.ts +23 -0
- package/src/components/Select/hooks/useSelectEvents.ts +87 -0
- package/src/components/Select/hooks/useSelectSearch.ts +91 -0
- package/src/components/Select/hooks/useSelectState.ts +104 -0
- package/src/components/Select/index.ts +9 -1
- package/src/components/Select/types.ts +123 -0
- package/src/components/Select/utils/text.ts +26 -0
- package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +5 -6
- package/src/components/Switch/Switch.tsx +4 -4
- package/src/components/Table/Table.tsx +1 -1
- package/src/components/Tabs/Tabs.tsx +1 -1
- package/src/components/Textarea/Textarea.tsx +27 -29
- package/src/components/Toast/Toast.tsx +5 -1
- package/src/components/Tooltip/Tooltip.tsx +3 -3
- package/src/components/UserMenu/UserMenu.test.tsx +24 -11
- package/src/components/UserMenu/UserMenu.tsx +22 -19
- package/src/components/index.ts +2 -2
- package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
- package/src/hooks/__tests__/index.unit.test.ts +2 -5
- package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
- package/src/hooks/index.ts +1 -2
- package/src/hooks/public/usePublicEvent.ts +5 -1
- package/src/hooks/public/usePublicEventLogo.ts +5 -1
- package/src/hooks/public/usePublicFileDisplay.ts +4 -0
- package/src/hooks/public/usePublicRouteParams.ts +5 -1
- package/src/hooks/services/useAuth.ts +32 -0
- package/src/hooks/services/useCurrentEvent.ts +6 -0
- package/src/hooks/services/useCurrentOrganisation.ts +6 -0
- package/src/hooks/useDataTableState.ts +8 -18
- package/src/hooks/useDebounce.ts +9 -0
- package/src/hooks/useEventTheme.ts +6 -0
- package/src/hooks/useFileDisplay.ts +4 -0
- package/src/hooks/useFileReference.ts +25 -7
- package/src/hooks/useFileUrl.ts +11 -1
- package/src/hooks/useFocusManagement.ts +16 -2
- package/src/hooks/useFocusTrap.ts +7 -4
- package/src/hooks/useFormDialog.ts +8 -7
- package/src/hooks/useInactivityTracker.ts +4 -1
- package/src/hooks/useKeyboardShortcuts.ts +4 -0
- package/src/hooks/useOrganisationPermissions.ts +4 -0
- package/src/hooks/useOrganisationSecurity.ts +4 -0
- package/src/hooks/usePerformanceMonitor.ts +4 -0
- package/src/hooks/usePermissionCache.ts +8 -1
- package/src/hooks/useQueryCache.ts +12 -1
- package/src/hooks/useSessionRestoration.ts +4 -0
- package/src/hooks/useStorage.ts +4 -0
- package/src/hooks/useToast.ts +3 -3
- package/src/index.ts +2 -1
- package/src/providers/__tests__/OrganisationProvider.test.tsx +115 -49
- package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
- package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
- package/src/providers/services/AuthServiceProvider.tsx +18 -0
- package/src/providers/services/EventServiceProvider.tsx +18 -0
- package/src/providers/services/InactivityServiceProvider.tsx +18 -0
- package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
- package/src/providers/services/UnifiedAuthProvider.tsx +58 -22
- package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +33 -7
- package/src/rbac/README.md +1 -1
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +26 -26
- package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
- package/src/rbac/adapters.tsx +14 -5
- package/src/rbac/api.ts +100 -67
- package/src/rbac/components/EnhancedNavigationMenu.tsx +1 -1
- package/src/rbac/components/NavigationGuard.tsx +1 -1
- package/src/rbac/components/NavigationProvider.tsx +5 -2
- package/src/rbac/components/PagePermissionGuard.tsx +158 -18
- package/src/rbac/components/PagePermissionProvider.tsx +1 -1
- package/src/rbac/components/PermissionEnforcer.tsx +1 -1
- package/src/rbac/components/RoleBasedRouter.tsx +6 -2
- package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
- package/src/rbac/components/SecureDataProvider.tsx +21 -6
- package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
- package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
- package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
- package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
- package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
- package/src/rbac/engine.ts +38 -14
- package/src/rbac/hooks/permissions/index.ts +7 -0
- package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
- package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
- package/src/rbac/hooks/permissions/useCan.ts +347 -0
- package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
- package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
- package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
- package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
- package/src/rbac/hooks/useCan.test.ts +71 -64
- package/src/rbac/hooks/usePermissions.ts +14 -995
- package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
- package/src/rbac/hooks/useResourcePermissions.ts +14 -4
- package/src/rbac/hooks/useSecureSupabase.ts +33 -13
- package/src/rbac/permissions.ts +0 -30
- package/src/rbac/secureClient.ts +212 -61
- package/src/rbac/types.ts +8 -0
- package/src/theming/__tests__/parseEventColours.test.ts +6 -9
- package/src/theming/parseEventColours.ts +5 -19
- package/src/types/vitest-globals.d.ts +51 -26
- package/src/utils/__mocks__/supabaseMock.ts +1 -3
- package/src/utils/__tests__/formatting.unit.test.ts +4 -4
- package/src/utils/__tests__/index.unit.test.ts +2 -2
- package/src/utils/audit/audit.ts +0 -3
- package/src/utils/core/cn.ts +1 -1
- package/src/utils/file-reference/index.ts +53 -1
- package/src/utils/formatting/formatting.ts +8 -18
- package/src/utils/index.ts +0 -1
- package/src/utils/security/secureDataAccess.test.ts +31 -20
- package/src/utils/security/secureDataAccess.ts +4 -3
- package/dist/chunk-6C4YBBJM.js +0 -628
- package/dist/chunk-6C4YBBJM.js.map +0 -1
- package/dist/chunk-7D4SUZUM.js 2.map +0 -1
- package/dist/chunk-7EQTDTTJ.js 2.map +0 -1
- package/dist/chunk-7EQTDTTJ.js.map +0 -1
- package/dist/chunk-7FLMSG37.js 2.map +0 -1
- package/dist/chunk-7FLMSG37.js.map +0 -1
- package/dist/chunk-BC4IJKSL.js.map +0 -1
- package/dist/chunk-E3SPN4VZ.js +0 -12917
- package/dist/chunk-E3SPN4VZ.js.map +0 -1
- package/dist/chunk-E66EQZE6 5.js +0 -37
- package/dist/chunk-E66EQZE6.js 2.map +0 -1
- package/dist/chunk-HWIIPPNI.js.map +0 -1
- package/dist/chunk-I7PSE6JW 5.js +0 -191
- package/dist/chunk-I7PSE6JW.js 2.map +0 -1
- package/dist/chunk-I7PSE6JW.js.map +0 -1
- package/dist/chunk-IIELH4DL.js.map +0 -1
- package/dist/chunk-KNC55RTG.js 5.map +0 -1
- package/dist/chunk-KNC55RTG.js.map +0 -1
- package/dist/chunk-KQCRWDSA.js 5.map +0 -1
- package/dist/chunk-LFNCN2SP.js +0 -412
- package/dist/chunk-LFNCN2SP.js 2.map +0 -1
- package/dist/chunk-LFNCN2SP.js.map +0 -1
- package/dist/chunk-LMC26NLJ 2.js +0 -84
- package/dist/chunk-NOAYCWCX.js +0 -4993
- package/dist/chunk-NOAYCWCX.js.map +0 -1
- package/dist/chunk-QWWZ5CAQ.js 3.map +0 -1
- package/dist/chunk-QWWZ5CAQ.js.map +0 -1
- package/dist/chunk-QXHPKYJV 3.js +0 -113
- package/dist/chunk-R77UEZ4E.js +0 -68
- package/dist/chunk-R77UEZ4E.js.map +0 -1
- package/dist/chunk-SQGMNID3.js.map +0 -1
- package/dist/chunk-VBXEHIUJ.js 6.map +0 -1
- package/dist/chunk-XNXXZ43G.js.map +0 -1
- package/dist/chunk-ZSAAAMVR 6.js +0 -25
- package/dist/components.js 5.map +0 -1
- package/dist/styles/index 2.js +0 -12
- package/dist/styles/index.js 5.map +0 -1
- package/dist/theming/runtime 5.js +0 -19
- package/dist/theming/runtime.js 5.map +0 -1
- package/docs/api/classes/ErrorBoundary.md +0 -144
- package/docs/migration/quick-migration-guide.md +0 -356
- package/docs/migration/service-architecture.md +0 -281
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
- package/src/hooks/useSecureDataAccess.test.ts +0 -559
- package/src/hooks/useSecureDataAccess.ts +0 -666
- /package/dist/{DataTable-5FU7IESH.js.map → DataTable-TPTKCX4D.js.map} +0 -0
- /package/dist/{UnifiedAuthProvider-RGJTDE2C.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
- /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
- /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
- /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
- /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
- /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
- /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
- /package/examples/{rbac → RBAC}/index.ts +0 -0
|
@@ -25,12 +25,13 @@ import {
|
|
|
25
25
|
SelectSeparator,
|
|
26
26
|
SelectTrigger,
|
|
27
27
|
SelectValue
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-3XC4CPTD.js";
|
|
29
29
|
import {
|
|
30
30
|
useCan,
|
|
31
31
|
usePermissions,
|
|
32
|
-
useRBAC
|
|
33
|
-
|
|
32
|
+
useRBAC,
|
|
33
|
+
useResolvedScope
|
|
34
|
+
} from "./chunk-XWQCNGTQ.js";
|
|
34
35
|
import {
|
|
35
36
|
createFileReferenceService,
|
|
36
37
|
generateFileUrlsBatch,
|
|
@@ -42,43 +43,42 @@ import {
|
|
|
42
43
|
useFileDisplay,
|
|
43
44
|
usePreventTabReload,
|
|
44
45
|
usePublicFileDisplay
|
|
45
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-SFZUDBL5.js";
|
|
46
47
|
import {
|
|
47
48
|
useToast
|
|
48
|
-
} from "./chunk-
|
|
49
|
+
} from "./chunk-6SOIHG6Z.js";
|
|
49
50
|
import {
|
|
50
51
|
ErrorBoundary,
|
|
51
52
|
PublicPageContext,
|
|
52
53
|
useAppConfig,
|
|
53
54
|
useEvents,
|
|
54
|
-
useIsPublicPage
|
|
55
|
-
|
|
56
|
-
} from "./chunk-IIELH4DL.js";
|
|
55
|
+
useIsPublicPage
|
|
56
|
+
} from "./chunk-MMZ7JXPU.js";
|
|
57
57
|
import {
|
|
58
58
|
EventServiceContext,
|
|
59
59
|
useOrganisations,
|
|
60
60
|
useSessionRestoration,
|
|
61
61
|
useUnifiedAuth
|
|
62
|
-
} from "./chunk-
|
|
62
|
+
} from "./chunk-EHMR7VYL.js";
|
|
63
63
|
import {
|
|
64
64
|
isSuperAdmin
|
|
65
|
-
} from "./chunk-
|
|
65
|
+
} from "./chunk-24UVZUZG.js";
|
|
66
66
|
import {
|
|
67
67
|
assertAppId
|
|
68
68
|
} from "./chunk-QXHPKYJV.js";
|
|
69
69
|
import {
|
|
70
70
|
LoadingSpinner,
|
|
71
71
|
getAppId
|
|
72
|
-
} from "./chunk-
|
|
72
|
+
} from "./chunk-J36DSWQK.js";
|
|
73
73
|
import {
|
|
74
74
|
cn
|
|
75
|
-
} from "./chunk-
|
|
75
|
+
} from "./chunk-M43Y4SSO.js";
|
|
76
76
|
import {
|
|
77
77
|
getCurrentAppName
|
|
78
|
-
} from "./chunk-
|
|
78
|
+
} from "./chunk-F2IMUDXZ.js";
|
|
79
79
|
import {
|
|
80
80
|
clearPalette
|
|
81
|
-
} from "./chunk-
|
|
81
|
+
} from "./chunk-L4OXEN46.js";
|
|
82
82
|
import {
|
|
83
83
|
createLogger,
|
|
84
84
|
logger
|
|
@@ -375,35 +375,32 @@ var Label = React2.forwardRef(({
|
|
|
375
375
|
Label.displayName = LabelPrimitive.Root.displayName;
|
|
376
376
|
|
|
377
377
|
// src/components/Textarea/Textarea.tsx
|
|
378
|
-
import * as React3 from "react";
|
|
379
378
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
}
|
|
406
|
-
);
|
|
379
|
+
function Textarea({ className, variant = "default", size = "md", error, ref, ...props }) {
|
|
380
|
+
return /* @__PURE__ */ jsx3(
|
|
381
|
+
"textarea",
|
|
382
|
+
{
|
|
383
|
+
className: cn(
|
|
384
|
+
// Base styles (matching Input component)
|
|
385
|
+
"flex w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
386
|
+
// Variant styles
|
|
387
|
+
{
|
|
388
|
+
"border-input": variant === "default" && !error,
|
|
389
|
+
"border-destructive focus-visible:ring-destructive": variant === "destructive" || error
|
|
390
|
+
},
|
|
391
|
+
// Size styles
|
|
392
|
+
{
|
|
393
|
+
"min-h-[60px] px-2 py-1 text-xs": size === "sm",
|
|
394
|
+
"min-h-[80px] px-3 py-2 text-sm": size === "md",
|
|
395
|
+
"min-h-[100px] px-4 py-3 text-base": size === "lg"
|
|
396
|
+
},
|
|
397
|
+
className
|
|
398
|
+
),
|
|
399
|
+
ref,
|
|
400
|
+
...props
|
|
401
|
+
}
|
|
402
|
+
);
|
|
403
|
+
}
|
|
407
404
|
Textarea.displayName = "Textarea";
|
|
408
405
|
|
|
409
406
|
// src/components/FileDisplay/FileDisplay.tsx
|
|
@@ -426,6 +423,12 @@ function useFileUrl(fileReference, options) {
|
|
|
426
423
|
setError(null);
|
|
427
424
|
return;
|
|
428
425
|
}
|
|
426
|
+
if (!supabase) {
|
|
427
|
+
setUrl(null);
|
|
428
|
+
setIsLoading(false);
|
|
429
|
+
setError(new Error("Supabase client is required for URL generation"));
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
429
432
|
if (isLoading || url && fileReferenceIdRef.current === fileReference.id) {
|
|
430
433
|
return;
|
|
431
434
|
}
|
|
@@ -557,10 +560,14 @@ function FileDisplayContent({
|
|
|
557
560
|
};
|
|
558
561
|
const handleDeleteConfirm = async () => {
|
|
559
562
|
setDeleteDialogOpen(false);
|
|
560
|
-
|
|
561
|
-
|
|
563
|
+
try {
|
|
564
|
+
if (onDelete) {
|
|
565
|
+
await onDelete();
|
|
566
|
+
}
|
|
567
|
+
setImageError(false);
|
|
568
|
+
} catch (error2) {
|
|
569
|
+
setImageError(false);
|
|
562
570
|
}
|
|
563
|
-
setImageError(false);
|
|
564
571
|
};
|
|
565
572
|
const handleImageError = () => {
|
|
566
573
|
setImageError(true);
|
|
@@ -974,9 +981,7 @@ function FileDisplayAuthenticated({
|
|
|
974
981
|
showMetadata
|
|
975
982
|
}) {
|
|
976
983
|
const { supabase } = useUnifiedAuth();
|
|
977
|
-
|
|
978
|
-
return /* @__PURE__ */ jsx4("figure", { className, title: "Error", children: /* @__PURE__ */ jsx4("p", { className: getFallbackClasses(fallbackSize || "md"), children: "Supabase client not available in authenticated context" }) });
|
|
979
|
-
}
|
|
984
|
+
const [displayOnlyFileReference, setDisplayOnlyFileReference] = useState3(null);
|
|
980
985
|
const {
|
|
981
986
|
fileUrl,
|
|
982
987
|
fileReference,
|
|
@@ -991,16 +996,15 @@ function FileDisplayAuthenticated({
|
|
|
991
996
|
record_id,
|
|
992
997
|
organisation_id,
|
|
993
998
|
category,
|
|
994
|
-
{ supabase }
|
|
999
|
+
{ supabase: supabase || null }
|
|
995
1000
|
);
|
|
996
|
-
const [displayOnlyFileReference, setDisplayOnlyFileReference] = useState3(null);
|
|
997
1001
|
const displayOnlyFileUrlFromMap = displayOnlyFileReference ? fileUrls.get(displayOnlyFileReference.id) : null;
|
|
998
1002
|
const displayOnlyFileUrlHook = useFileUrl(
|
|
999
1003
|
displayOnlyFileReference && !displayOnlyFileUrlFromMap ? displayOnlyFileReference : null,
|
|
1000
1004
|
{
|
|
1001
|
-
supabase,
|
|
1005
|
+
supabase: supabase || null,
|
|
1002
1006
|
organisation_id,
|
|
1003
|
-
autoLoad: !displayOnlyFileUrlFromMap && !!displayOnlyFileReference
|
|
1007
|
+
autoLoad: !displayOnlyFileUrlFromMap && !!displayOnlyFileReference && !!supabase
|
|
1004
1008
|
}
|
|
1005
1009
|
);
|
|
1006
1010
|
const displayOnlyFileUrl = displayOnlyFileUrlFromMap || displayOnlyFileUrlHook.url;
|
|
@@ -1015,6 +1019,9 @@ function FileDisplayAuthenticated({
|
|
|
1015
1019
|
setDisplayOnlyFileReference(null);
|
|
1016
1020
|
}
|
|
1017
1021
|
}, [displayOnly, category, fileReferences, fileUrls]);
|
|
1022
|
+
if (!supabase) {
|
|
1023
|
+
return /* @__PURE__ */ jsx4("figure", { className, title: "Error", children: /* @__PURE__ */ jsx4("p", { className: getFallbackClasses(fallbackSize || "md"), children: "Supabase client not available in authenticated context" }) });
|
|
1024
|
+
}
|
|
1018
1025
|
const handleDelete = async () => {
|
|
1019
1026
|
};
|
|
1020
1027
|
let finalFileReference = fileReference;
|
|
@@ -1431,13 +1438,17 @@ function useFileReferenceById(supabase, fileReferenceId, organisationId) {
|
|
|
1431
1438
|
return;
|
|
1432
1439
|
}
|
|
1433
1440
|
const loadUrl = async () => {
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
+
try {
|
|
1442
|
+
const service = createFileReferenceService(supabase);
|
|
1443
|
+
const url = await service.getFileUrl(
|
|
1444
|
+
fileReference.table_name,
|
|
1445
|
+
fileReference.record_id,
|
|
1446
|
+
organisationId
|
|
1447
|
+
);
|
|
1448
|
+
setFileUrl(url);
|
|
1449
|
+
} catch (error2) {
|
|
1450
|
+
setFileUrl(null);
|
|
1451
|
+
}
|
|
1441
1452
|
};
|
|
1442
1453
|
loadUrl();
|
|
1443
1454
|
}, [fileReference, fileReferenceId, organisationId, supabase]);
|
|
@@ -1489,7 +1500,7 @@ function useFilesByCategory(supabase, table_name, record_id, category, organisat
|
|
|
1489
1500
|
}
|
|
1490
1501
|
|
|
1491
1502
|
// src/components/Avatar/Avatar.tsx
|
|
1492
|
-
import * as
|
|
1503
|
+
import * as React4 from "react";
|
|
1493
1504
|
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
1494
1505
|
var sizeClasses = {
|
|
1495
1506
|
xs: "size-4 text-xs",
|
|
@@ -1499,7 +1510,7 @@ var sizeClasses = {
|
|
|
1499
1510
|
xl: "size-16 text-xl",
|
|
1500
1511
|
"2xl": "size-20 text-2xl"
|
|
1501
1512
|
};
|
|
1502
|
-
var Avatar =
|
|
1513
|
+
var Avatar = React4.forwardRef(
|
|
1503
1514
|
({
|
|
1504
1515
|
table_name,
|
|
1505
1516
|
record_id,
|
|
@@ -1513,7 +1524,7 @@ var Avatar = React5.forwardRef(
|
|
|
1513
1524
|
size = "md",
|
|
1514
1525
|
...props
|
|
1515
1526
|
}, ref) => {
|
|
1516
|
-
const [imageError, setImageError] =
|
|
1527
|
+
const [imageError, setImageError] = React4.useState(false);
|
|
1517
1528
|
const { supabase } = useUnifiedAuth();
|
|
1518
1529
|
const canFetchFileId = Boolean(fileId && organisation_id && supabase);
|
|
1519
1530
|
const { fileReference, fileUrl: fileIdUrl, isLoading: fileIdLoading } = useFileReferenceById(
|
|
@@ -1530,10 +1541,10 @@ var Avatar = React5.forwardRef(
|
|
|
1530
1541
|
const fallbackClasses = "size-full grid place-items-center text-center text-sec-50 bg-sec-500";
|
|
1531
1542
|
const imageClasses = "object-cover size-full";
|
|
1532
1543
|
const containerClasses = cn(baseClasses, className);
|
|
1533
|
-
const handleImageError =
|
|
1544
|
+
const handleImageError = React4.useCallback(() => {
|
|
1534
1545
|
setImageError(true);
|
|
1535
1546
|
}, []);
|
|
1536
|
-
|
|
1547
|
+
React4.useEffect(() => {
|
|
1537
1548
|
if (src) {
|
|
1538
1549
|
setImageError(false);
|
|
1539
1550
|
}
|
|
@@ -1592,7 +1603,6 @@ var Avatar = React5.forwardRef(
|
|
|
1592
1603
|
Avatar.displayName = "Avatar";
|
|
1593
1604
|
|
|
1594
1605
|
// src/components/Badge/Badge.tsx
|
|
1595
|
-
import * as React6 from "react";
|
|
1596
1606
|
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
1597
1607
|
var shadeConfig = {
|
|
1598
1608
|
muted: {
|
|
@@ -1658,42 +1668,40 @@ function getBadgeClasses(variant = "solid-main-normal") {
|
|
|
1658
1668
|
const baseClasses = "text-balance rounded-2xl px-3 py-1 mr-1 text-xs font-medium transition-colors box-border";
|
|
1659
1669
|
return `${baseClasses} ${variantClassesMap[variant]}`;
|
|
1660
1670
|
}
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
const finalClasses = `${mergedClasses} shadow-badge-soft ${shadowColorClass}`.trim();
|
|
1671
|
-
return /* @__PURE__ */ jsx6(
|
|
1672
|
-
"span",
|
|
1673
|
-
{
|
|
1674
|
-
ref,
|
|
1675
|
-
className: finalClasses,
|
|
1676
|
-
...props
|
|
1677
|
-
}
|
|
1678
|
-
);
|
|
1679
|
-
}
|
|
1671
|
+
function Badge({ className, variant = "solid-main-normal", ref, ...props }) {
|
|
1672
|
+
const isSoftVariant = variant.startsWith("soft-");
|
|
1673
|
+
if (isSoftVariant) {
|
|
1674
|
+
const variantClasses = getBadgeClasses(variant);
|
|
1675
|
+
const shadowColorMatch = variantClasses.match(/\bshadow-(\w+)-(\d+)\b/);
|
|
1676
|
+
const shadowColorClass = shadowColorMatch ? shadowColorMatch[0] : "";
|
|
1677
|
+
const classesWithoutShadows = variantClasses.replace(/\bshadow-badge-soft\b/g, "").replace(/\bshadow-\w+-\d+\b/g, "").replace(/\s+/g, " ").trim();
|
|
1678
|
+
const mergedClasses = cn(classesWithoutShadows, className);
|
|
1679
|
+
const finalClasses = `${mergedClasses} shadow-badge-soft ${shadowColorClass}`.trim();
|
|
1680
1680
|
return /* @__PURE__ */ jsx6(
|
|
1681
1681
|
"span",
|
|
1682
1682
|
{
|
|
1683
1683
|
ref,
|
|
1684
|
-
className:
|
|
1684
|
+
className: finalClasses,
|
|
1685
1685
|
...props
|
|
1686
1686
|
}
|
|
1687
1687
|
);
|
|
1688
1688
|
}
|
|
1689
|
-
|
|
1689
|
+
return /* @__PURE__ */ jsx6(
|
|
1690
|
+
"span",
|
|
1691
|
+
{
|
|
1692
|
+
ref,
|
|
1693
|
+
className: cn(getBadgeClasses(variant), className),
|
|
1694
|
+
...props
|
|
1695
|
+
}
|
|
1696
|
+
);
|
|
1697
|
+
}
|
|
1690
1698
|
Badge.displayName = "Badge";
|
|
1691
1699
|
|
|
1692
1700
|
// src/components/Switch/Switch.tsx
|
|
1693
|
-
import * as
|
|
1701
|
+
import * as React5 from "react";
|
|
1694
1702
|
import * as SwitchPrimitive from "@radix-ui/react-switch";
|
|
1695
1703
|
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
1696
|
-
var Switch =
|
|
1704
|
+
var Switch = React5.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx7(
|
|
1697
1705
|
SwitchPrimitive.Root,
|
|
1698
1706
|
{
|
|
1699
1707
|
className: cn(
|
|
@@ -1736,12 +1744,12 @@ var Switch = React7.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
1736
1744
|
Switch.displayName = SwitchPrimitive.Root.displayName;
|
|
1737
1745
|
|
|
1738
1746
|
// src/components/Tabs/Tabs.tsx
|
|
1739
|
-
import * as
|
|
1747
|
+
import * as React6 from "react";
|
|
1740
1748
|
import * as TabsPrimitive from "@radix-ui/react-tabs";
|
|
1741
1749
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
1742
|
-
var Tabs =
|
|
1750
|
+
var Tabs = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx8(TabsPrimitive.Root, { asChild: true, ...props, children: /* @__PURE__ */ jsx8("section", { ref, className, children }) }));
|
|
1743
1751
|
Tabs.displayName = TabsPrimitive.Root.displayName || "Tabs";
|
|
1744
|
-
var TabsList =
|
|
1752
|
+
var TabsList = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx8(TabsPrimitive.List, { asChild: true, ...props, children: /* @__PURE__ */ jsx8(
|
|
1745
1753
|
"nav",
|
|
1746
1754
|
{
|
|
1747
1755
|
ref,
|
|
@@ -1753,7 +1761,7 @@ var TabsList = React8.forwardRef(({ className, children, ...props }, ref) => /*
|
|
|
1753
1761
|
}
|
|
1754
1762
|
) }));
|
|
1755
1763
|
TabsList.displayName = TabsPrimitive.List.displayName || "TabsList";
|
|
1756
|
-
var TabsTrigger =
|
|
1764
|
+
var TabsTrigger = React6.forwardRef(({ className, variant, size, children, ...props }, ref) => {
|
|
1757
1765
|
return /* @__PURE__ */ jsx8(TabsPrimitive.Trigger, { asChild: true, ...props, children: /* @__PURE__ */ jsx8(
|
|
1758
1766
|
Button,
|
|
1759
1767
|
{
|
|
@@ -1772,7 +1780,7 @@ var TabsTrigger = React8.forwardRef(({ className, variant, size, children, ...pr
|
|
|
1772
1780
|
) });
|
|
1773
1781
|
});
|
|
1774
1782
|
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName || "TabsTrigger";
|
|
1775
|
-
var TabsContent =
|
|
1783
|
+
var TabsContent = React6.forwardRef(({ className, children, ...props }, ref) => /* @__PURE__ */ jsx8(TabsPrimitive.Content, { asChild: true, ...props, children: /* @__PURE__ */ jsx8(
|
|
1776
1784
|
"aside",
|
|
1777
1785
|
{
|
|
1778
1786
|
ref,
|
|
@@ -1786,7 +1794,7 @@ var TabsContent = React8.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
1786
1794
|
TabsContent.displayName = TabsPrimitive.Content.displayName || "TabsContent";
|
|
1787
1795
|
|
|
1788
1796
|
// src/components/Calendar/Calendar.tsx
|
|
1789
|
-
import * as
|
|
1797
|
+
import * as React7 from "react";
|
|
1790
1798
|
import {
|
|
1791
1799
|
DayPicker,
|
|
1792
1800
|
useDayPicker
|
|
@@ -1803,10 +1811,10 @@ var assignToRef = (ref, value) => {
|
|
|
1803
1811
|
}
|
|
1804
1812
|
ref.current = value;
|
|
1805
1813
|
};
|
|
1806
|
-
var Calendar =
|
|
1814
|
+
var Calendar = React7.forwardRef(
|
|
1807
1815
|
({ className, classNames, mode, components, locale, month: controlledMonth, onMonthChange: controlledOnMonthChange, onSelect, ...props }, ref) => {
|
|
1808
|
-
const tableRef =
|
|
1809
|
-
const setForwardedRef =
|
|
1816
|
+
const tableRef = React7.useRef(null);
|
|
1817
|
+
const setForwardedRef = React7.useCallback(
|
|
1810
1818
|
(node) => {
|
|
1811
1819
|
tableRef.current = node;
|
|
1812
1820
|
if (!ref) {
|
|
@@ -1820,14 +1828,14 @@ var Calendar = React9.forwardRef(
|
|
|
1820
1828
|
},
|
|
1821
1829
|
[ref]
|
|
1822
1830
|
);
|
|
1823
|
-
const rootPropsRef =
|
|
1831
|
+
const rootPropsRef = React7.useRef(null);
|
|
1824
1832
|
const selected = props.selected;
|
|
1825
1833
|
const isMonthControlled = controlledMonth !== void 0;
|
|
1826
|
-
const [internalMonth, setInternalMonth] =
|
|
1834
|
+
const [internalMonth, setInternalMonth] = React7.useState(() => {
|
|
1827
1835
|
const now = /* @__PURE__ */ new Date();
|
|
1828
1836
|
return new Date(now.getFullYear(), now.getMonth(), 1);
|
|
1829
1837
|
});
|
|
1830
|
-
const month =
|
|
1838
|
+
const month = React7.useMemo(() => {
|
|
1831
1839
|
const monthToUse = isMonthControlled ? controlledMonth : internalMonth;
|
|
1832
1840
|
if (!monthToUse) {
|
|
1833
1841
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1836,16 +1844,16 @@ var Calendar = React9.forwardRef(
|
|
|
1836
1844
|
const normalized = new Date(monthToUse.getFullYear(), monthToUse.getMonth(), 1);
|
|
1837
1845
|
return normalized;
|
|
1838
1846
|
}, [isMonthControlled, controlledMonth, internalMonth]);
|
|
1839
|
-
const handleMonthChange =
|
|
1847
|
+
const handleMonthChange = React7.useCallback((newMonth) => {
|
|
1840
1848
|
if (!isMonthControlled) {
|
|
1841
1849
|
setInternalMonth(newMonth);
|
|
1842
1850
|
}
|
|
1843
1851
|
controlledOnMonthChange?.(newMonth);
|
|
1844
1852
|
}, [isMonthControlled, controlledOnMonthChange]);
|
|
1845
|
-
const wrappedHandleMonthChange =
|
|
1853
|
+
const wrappedHandleMonthChange = React7.useCallback((newMonth) => {
|
|
1846
1854
|
handleMonthChange(newMonth);
|
|
1847
1855
|
}, [handleMonthChange]);
|
|
1848
|
-
const CustomRoot =
|
|
1856
|
+
const CustomRoot = React7.memo(({ children, rootRef: dayPickerRootRef, ...rootProps }) => {
|
|
1849
1857
|
const {
|
|
1850
1858
|
className: rootClassName,
|
|
1851
1859
|
style: rootStyle,
|
|
@@ -1861,29 +1869,29 @@ var Calendar = React9.forwardRef(
|
|
|
1861
1869
|
return /* @__PURE__ */ jsx9(Fragment4, { children });
|
|
1862
1870
|
});
|
|
1863
1871
|
CustomRoot.displayName = "CustomRoot";
|
|
1864
|
-
const CustomMonths =
|
|
1872
|
+
const CustomMonths = React7.memo(({ children }) => {
|
|
1865
1873
|
return /* @__PURE__ */ jsx9(Fragment4, { children });
|
|
1866
1874
|
});
|
|
1867
1875
|
CustomMonths.displayName = "CustomMonths";
|
|
1868
|
-
const CustomMonthGrid =
|
|
1876
|
+
const CustomMonthGrid = React7.forwardRef((props2, forwardedRef) => {
|
|
1869
1877
|
return /* @__PURE__ */ jsx9("table", { ref: forwardedRef, ...props2 });
|
|
1870
1878
|
});
|
|
1871
1879
|
CustomMonthGrid.displayName = "CustomMonthGrid";
|
|
1872
|
-
const CustomMonth =
|
|
1880
|
+
const CustomMonth = React7.memo(({ calendarMonth, displayIndex, className: className2, children }) => {
|
|
1873
1881
|
const { formatters, components: components2, labels, classNames: classNames2, previousMonth, nextMonth, goToMonth } = useDayPicker();
|
|
1874
1882
|
const caption = formatters.formatCaption(calendarMonth.date, {});
|
|
1875
1883
|
const Chevron = components2?.Chevron;
|
|
1876
|
-
const childrenArray =
|
|
1884
|
+
const childrenArray = React7.Children.toArray(children);
|
|
1877
1885
|
const monthGridIndex = childrenArray.findIndex((child) => {
|
|
1878
|
-
if (!
|
|
1886
|
+
if (!React7.isValidElement(child)) return false;
|
|
1879
1887
|
const childType = child.type;
|
|
1880
1888
|
return typeof childType === "function" && childType.displayName === "MonthGrid" || child.type === "table";
|
|
1881
1889
|
});
|
|
1882
1890
|
return /* @__PURE__ */ jsx9(Fragment4, { children: childrenArray.map((child, index) => {
|
|
1883
|
-
if (
|
|
1891
|
+
if (React7.isValidElement(child) && child.type?.displayName === "MonthCaption") {
|
|
1884
1892
|
return null;
|
|
1885
1893
|
}
|
|
1886
|
-
if (index === monthGridIndex &&
|
|
1894
|
+
if (index === monthGridIndex && React7.isValidElement(child)) {
|
|
1887
1895
|
const monthGridChild = child;
|
|
1888
1896
|
const applyRootProps = displayIndex === 0 && index === monthGridIndex;
|
|
1889
1897
|
const storedRootProps = applyRootProps ? rootPropsRef.current : null;
|
|
@@ -1933,7 +1941,7 @@ var Calendar = React9.forwardRef(
|
|
|
1933
1941
|
}
|
|
1934
1942
|
assignToRef(monthGridElement.ref, node);
|
|
1935
1943
|
} : void 0;
|
|
1936
|
-
return
|
|
1944
|
+
return React7.cloneElement(
|
|
1937
1945
|
monthGridElement,
|
|
1938
1946
|
{
|
|
1939
1947
|
key: child.key ?? `month-grid-${displayIndex}`,
|
|
@@ -1988,15 +1996,15 @@ var Calendar = React9.forwardRef(
|
|
|
1988
1996
|
] })
|
|
1989
1997
|
);
|
|
1990
1998
|
}
|
|
1991
|
-
return child;
|
|
1999
|
+
return React7.isValidElement(child) ? React7.cloneElement(child, { key: child.key ?? `calendar-child-${index}` }) : child;
|
|
1992
2000
|
}) });
|
|
1993
2001
|
});
|
|
1994
2002
|
CustomMonth.displayName = "CustomMonth";
|
|
1995
|
-
const CustomWeekdays =
|
|
2003
|
+
const CustomWeekdays = React7.memo(({ className: className2, children, ...props2 }) => {
|
|
1996
2004
|
return /* @__PURE__ */ jsx9("thead", { children: /* @__PURE__ */ jsx9("tr", { className: cn("text-xs text-sec-500", className2), ...props2, children }) });
|
|
1997
2005
|
});
|
|
1998
2006
|
CustomWeekdays.displayName = "CustomWeekdays";
|
|
1999
|
-
const defaultComponents =
|
|
2007
|
+
const defaultComponents = React7.useMemo(() => ({
|
|
2000
2008
|
Root: CustomRoot,
|
|
2001
2009
|
Months: CustomMonths,
|
|
2002
2010
|
Month: CustomMonth,
|
|
@@ -2084,12 +2092,12 @@ var Calendar = React9.forwardRef(
|
|
|
2084
2092
|
Calendar.displayName = "Calendar";
|
|
2085
2093
|
|
|
2086
2094
|
// src/components/Toast/Toast.tsx
|
|
2087
|
-
import * as
|
|
2095
|
+
import * as React8 from "react";
|
|
2088
2096
|
import * as ToastPrimitives from "@radix-ui/react-toast";
|
|
2089
2097
|
import { X } from "lucide-react";
|
|
2090
2098
|
import { jsx as jsx10, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
2091
2099
|
var ToastProvider = ToastPrimitives.Provider;
|
|
2092
|
-
var ToastViewport =
|
|
2100
|
+
var ToastViewport = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx10(
|
|
2093
2101
|
ToastPrimitives.Viewport,
|
|
2094
2102
|
{
|
|
2095
2103
|
ref,
|
|
@@ -2102,7 +2110,7 @@ var ToastViewport = React10.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
2102
2110
|
}
|
|
2103
2111
|
));
|
|
2104
2112
|
ToastViewport.displayName = ToastPrimitives.Viewport.displayName;
|
|
2105
|
-
var Toast =
|
|
2113
|
+
var Toast = React8.forwardRef(({ className, ...props }, ref) => {
|
|
2106
2114
|
return /* @__PURE__ */ jsx10(
|
|
2107
2115
|
ToastPrimitives.Root,
|
|
2108
2116
|
{
|
|
@@ -2117,7 +2125,7 @@ var Toast = React10.forwardRef(({ className, ...props }, ref) => {
|
|
|
2117
2125
|
);
|
|
2118
2126
|
});
|
|
2119
2127
|
Toast.displayName = ToastPrimitives.Root.displayName;
|
|
2120
|
-
var ToastAction =
|
|
2128
|
+
var ToastAction = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx10(
|
|
2121
2129
|
ToastPrimitives.Action,
|
|
2122
2130
|
{
|
|
2123
2131
|
ref,
|
|
@@ -2130,7 +2138,7 @@ var ToastAction = React10.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
2130
2138
|
}
|
|
2131
2139
|
));
|
|
2132
2140
|
ToastAction.displayName = ToastPrimitives.Action.displayName;
|
|
2133
|
-
var ToastClose =
|
|
2141
|
+
var ToastClose = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx10(
|
|
2134
2142
|
ToastPrimitives.Close,
|
|
2135
2143
|
{
|
|
2136
2144
|
ref,
|
|
@@ -2145,7 +2153,7 @@ var ToastClose = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
2145
2153
|
}
|
|
2146
2154
|
));
|
|
2147
2155
|
ToastClose.displayName = ToastPrimitives.Close.displayName;
|
|
2148
|
-
var ToastTitle =
|
|
2156
|
+
var ToastTitle = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx10(
|
|
2149
2157
|
ToastPrimitives.Title,
|
|
2150
2158
|
{
|
|
2151
2159
|
ref,
|
|
@@ -2155,7 +2163,7 @@ var ToastTitle = React10.forwardRef(({ className, ...props }, ref) => /* @__PURE
|
|
|
2155
2163
|
}
|
|
2156
2164
|
));
|
|
2157
2165
|
ToastTitle.displayName = ToastPrimitives.Title.displayName;
|
|
2158
|
-
var ToastDescription =
|
|
2166
|
+
var ToastDescription = React8.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx10(
|
|
2159
2167
|
ToastPrimitives.Description,
|
|
2160
2168
|
{
|
|
2161
2169
|
ref,
|
|
@@ -2184,7 +2192,7 @@ function Toaster() {
|
|
|
2184
2192
|
// src/components/Form/Form.tsx
|
|
2185
2193
|
import { useForm, FormProvider, useFormContext, Controller } from "react-hook-form";
|
|
2186
2194
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
2187
|
-
import { jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2195
|
+
import { Fragment as Fragment5, jsx as jsx11, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
2188
2196
|
function Form({
|
|
2189
2197
|
schema,
|
|
2190
2198
|
defaultValues,
|
|
@@ -2197,7 +2205,8 @@ function Form({
|
|
|
2197
2205
|
const methods = useForm({
|
|
2198
2206
|
resolver: schema ? zodResolver(schema) : void 0,
|
|
2199
2207
|
defaultValues,
|
|
2200
|
-
mode
|
|
2208
|
+
mode,
|
|
2209
|
+
shouldUnregister: false
|
|
2201
2210
|
});
|
|
2202
2211
|
const handleSubmit = methods.handleSubmit(onSubmit, onError);
|
|
2203
2212
|
return /* @__PURE__ */ jsx11(FormProvider, { ...methods, children: /* @__PURE__ */ jsx11("form", { onSubmit: handleSubmit, className: cn("space-y-4", className), children: typeof children === "function" ? children(methods) : children }) });
|
|
@@ -2213,9 +2222,7 @@ function FormField({
|
|
|
2213
2222
|
"data-testid": testId,
|
|
2214
2223
|
className
|
|
2215
2224
|
}) {
|
|
2216
|
-
const { control
|
|
2217
|
-
const fieldError = errors[name];
|
|
2218
|
-
const errorMessage = fieldError && typeof fieldError === "object" && "message" in fieldError ? String(fieldError.message) : void 0;
|
|
2225
|
+
const { control } = useFormContext();
|
|
2219
2226
|
return /* @__PURE__ */ jsxs6("div", { className: cn("space-y-2", className), children: [
|
|
2220
2227
|
label && /* @__PURE__ */ jsxs6(Label, { htmlFor: name, children: [
|
|
2221
2228
|
label,
|
|
@@ -2228,35 +2235,41 @@ function FormField({
|
|
|
2228
2235
|
control,
|
|
2229
2236
|
rules: validation,
|
|
2230
2237
|
render: (props) => {
|
|
2238
|
+
const { field, fieldState } = props;
|
|
2239
|
+
const fieldError = fieldState.error;
|
|
2240
|
+
const errorMessage = fieldError && typeof fieldError === "object" && "message" in fieldError ? String(fieldError.message) : void 0;
|
|
2231
2241
|
if (render) {
|
|
2232
2242
|
return render(props);
|
|
2233
2243
|
}
|
|
2234
|
-
return /* @__PURE__ */
|
|
2235
|
-
|
|
2236
|
-
|
|
2237
|
-
|
|
2238
|
-
|
|
2239
|
-
|
|
2240
|
-
|
|
2241
|
-
|
|
2242
|
-
|
|
2243
|
-
"
|
|
2244
|
-
|
|
2245
|
-
|
|
2246
|
-
|
|
2247
|
-
|
|
2248
|
-
|
|
2244
|
+
return /* @__PURE__ */ jsxs6(Fragment5, { children: [
|
|
2245
|
+
/* @__PURE__ */ jsx11(
|
|
2246
|
+
"input",
|
|
2247
|
+
{
|
|
2248
|
+
...field,
|
|
2249
|
+
id: name,
|
|
2250
|
+
type,
|
|
2251
|
+
placeholder,
|
|
2252
|
+
"data-testid": testId,
|
|
2253
|
+
"aria-label": label || placeholder || name,
|
|
2254
|
+
className: cn(
|
|
2255
|
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
|
|
2256
|
+
fieldError && "border-destructive focus-visible:ring-destructive"
|
|
2257
|
+
),
|
|
2258
|
+
...inputProps
|
|
2259
|
+
}
|
|
2260
|
+
),
|
|
2261
|
+
errorMessage && /* @__PURE__ */ jsx11("p", { className: "text-destructive", role: "alert", children: errorMessage })
|
|
2262
|
+
] });
|
|
2249
2263
|
}
|
|
2250
2264
|
}
|
|
2251
|
-
)
|
|
2252
|
-
errorMessage && /* @__PURE__ */ jsx11("p", { className: "text-destructive", role: "alert", children: errorMessage })
|
|
2265
|
+
)
|
|
2253
2266
|
] });
|
|
2254
2267
|
}
|
|
2255
2268
|
|
|
2256
2269
|
// src/components/LoginForm/LoginForm.tsx
|
|
2257
|
-
import
|
|
2270
|
+
import React9, { useState as useState7, useCallback as useCallback7, useMemo as useMemo4 } from "react";
|
|
2258
2271
|
import { jsx as jsx12, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
2259
|
-
var LoginForm =
|
|
2272
|
+
var LoginForm = React9.memo(({
|
|
2260
2273
|
onSignIn,
|
|
2261
2274
|
onSuccess,
|
|
2262
2275
|
onError,
|
|
@@ -2273,12 +2286,12 @@ var LoginForm = React11.memo(({
|
|
|
2273
2286
|
const isFormValid = useMemo4(() => {
|
|
2274
2287
|
return formData.email.length > 0 && formData.password.length > 0;
|
|
2275
2288
|
}, [formData.email, formData.password]);
|
|
2276
|
-
const handleEmailChange =
|
|
2289
|
+
const handleEmailChange = (e) => {
|
|
2277
2290
|
setFormData((prev) => ({ ...prev, email: e.target.value }));
|
|
2278
|
-
}
|
|
2279
|
-
const handlePasswordChange =
|
|
2291
|
+
};
|
|
2292
|
+
const handlePasswordChange = (e) => {
|
|
2280
2293
|
setFormData((prev) => ({ ...prev, password: e.target.value }));
|
|
2281
|
-
}
|
|
2294
|
+
};
|
|
2282
2295
|
const handleSubmit = useCallback7(async (e) => {
|
|
2283
2296
|
e.preventDefault();
|
|
2284
2297
|
setError(null);
|
|
@@ -2292,9 +2305,9 @@ var LoginForm = React11.memo(({
|
|
|
2292
2305
|
onError?.(err instanceof Error ? err : new Error(errorMessage));
|
|
2293
2306
|
}
|
|
2294
2307
|
}, [formData, isFormValid, isLoading, onSignIn, onSuccess, onError]);
|
|
2295
|
-
const handleSignUpClick =
|
|
2308
|
+
const handleSignUpClick = () => {
|
|
2296
2309
|
onSignUp?.();
|
|
2297
|
-
}
|
|
2310
|
+
};
|
|
2298
2311
|
const displayTitle = useMemo4(() => title || (appName ? `Sign in to ${appName}` : "Sign In"), [title, appName]);
|
|
2299
2312
|
const displaySubtitle = useMemo4(() => subtitle || "Enter your credentials to continue.", [subtitle]);
|
|
2300
2313
|
return /* @__PURE__ */ jsx12(Card, { className: cn("w-full max-w-md mx-auto", className), children: /* @__PURE__ */ jsxs7("form", { onSubmit: handleSubmit, "data-testid": "login-form", children: [
|
|
@@ -2824,10 +2837,10 @@ function PasswordChangeForm({ onSubmit, className }) {
|
|
|
2824
2837
|
}
|
|
2825
2838
|
|
|
2826
2839
|
// src/components/UserMenu/UserMenu.tsx
|
|
2827
|
-
import
|
|
2840
|
+
import React12, { useCallback as useCallback9, useMemo as useMemo7, useState as useState10 } from "react";
|
|
2828
2841
|
import { ChevronDown, LogOut, KeyRound } from "lucide-react";
|
|
2829
2842
|
import { jsx as jsx16, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
2830
|
-
var UserMenu =
|
|
2843
|
+
var UserMenu = React12.memo(function UserMenu2({
|
|
2831
2844
|
user,
|
|
2832
2845
|
onSignOut,
|
|
2833
2846
|
onChangePassword,
|
|
@@ -2866,9 +2879,10 @@ var UserMenu = React14.memo(function UserMenu2({
|
|
|
2866
2879
|
/* @__PURE__ */ jsx16(ChevronDown, { className: "size-4" })
|
|
2867
2880
|
] }) }),
|
|
2868
2881
|
/* @__PURE__ */ jsxs11(SelectContent, { children: [
|
|
2869
|
-
/* @__PURE__ */ jsx16(SelectLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs11("
|
|
2870
|
-
|
|
2871
|
-
/* @__PURE__ */ jsx16("
|
|
2882
|
+
/* @__PURE__ */ jsx16(SelectLabel, { className: "font-normal", children: /* @__PURE__ */ jsxs11("li", { className: "pt-2", children: [
|
|
2883
|
+
userInfo.displayName,
|
|
2884
|
+
/* @__PURE__ */ jsx16("br", {}),
|
|
2885
|
+
/* @__PURE__ */ jsx16("span", { className: "text-muted-foreground", children: userInfo.email })
|
|
2872
2886
|
] }) }),
|
|
2873
2887
|
/* @__PURE__ */ jsx16(SelectSeparator, {}),
|
|
2874
2888
|
/* @__PURE__ */ jsx16(DialogTrigger, { asChild: true, children: /* @__PURE__ */ jsxs11(SelectItem, { value: "change-password", children: [
|
|
@@ -2902,61 +2916,55 @@ var UserMenu = React14.memo(function UserMenu2({
|
|
|
2902
2916
|
] })
|
|
2903
2917
|
] });
|
|
2904
2918
|
});
|
|
2905
|
-
var UserMenuLoading =
|
|
2906
|
-
return /* @__PURE__ */ jsxs11(
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
|
|
2913
|
-
|
|
2914
|
-
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
|
|
2921
|
-
] });
|
|
2919
|
+
var UserMenuLoading = React12.memo(function UserMenuLoading2() {
|
|
2920
|
+
return /* @__PURE__ */ jsxs11(
|
|
2921
|
+
Button,
|
|
2922
|
+
{
|
|
2923
|
+
type: "button",
|
|
2924
|
+
disabled: true,
|
|
2925
|
+
variant: "outline",
|
|
2926
|
+
className: "flex items-center space-x-2",
|
|
2927
|
+
"aria-label": "Loading user menu",
|
|
2928
|
+
children: [
|
|
2929
|
+
/* @__PURE__ */ jsx16(LoadingSpinner, { size: "sm", className: "inline-block mr-2" }),
|
|
2930
|
+
/* @__PURE__ */ jsx16("span", { className: "truncate max-w-[150px]", children: "Loading..." }),
|
|
2931
|
+
/* @__PURE__ */ jsx16(ChevronDown, { className: "w-4 h-4 text-muted-foreground" })
|
|
2932
|
+
]
|
|
2933
|
+
}
|
|
2934
|
+
);
|
|
2922
2935
|
});
|
|
2923
2936
|
UserMenu.Loading = UserMenuLoading;
|
|
2924
2937
|
|
|
2925
2938
|
// src/components/NavigationMenu/NavigationMenu.tsx
|
|
2926
|
-
import * as
|
|
2939
|
+
import * as React14 from "react";
|
|
2927
2940
|
import { ChevronDown as ChevronDown2 } from "lucide-react";
|
|
2928
|
-
|
|
2929
|
-
|
|
2941
|
+
|
|
2942
|
+
// src/components/NavigationMenu/useNavigationFiltering.ts
|
|
2943
|
+
import * as React13 from "react";
|
|
2944
|
+
function useNavigationFiltering({
|
|
2930
2945
|
items,
|
|
2931
|
-
mode = "dropdown",
|
|
2932
|
-
currentPath,
|
|
2933
|
-
onNavigate,
|
|
2934
|
-
className,
|
|
2935
|
-
disabled = false,
|
|
2936
|
-
buttonText = "Menu",
|
|
2937
|
-
showIcons = true,
|
|
2938
|
-
navigationLabel = "Main navigation",
|
|
2939
|
-
// NEW: Phase 2 - Enhanced Security Features
|
|
2940
|
-
strictMode = true,
|
|
2941
|
-
auditLog = true,
|
|
2942
|
-
onNavigationAccessDenied,
|
|
2943
|
-
onStrictModeViolation,
|
|
2944
2946
|
itemsPreFiltered = false,
|
|
2945
|
-
|
|
2946
|
-
}
|
|
2947
|
-
const [
|
|
2948
|
-
const
|
|
2947
|
+
auditLog = true
|
|
2948
|
+
}) {
|
|
2949
|
+
const [resolvedAppId, setResolvedAppId] = React13.useState(void 0);
|
|
2950
|
+
const previousFilteredItemsRef = React13.useRef([]);
|
|
2949
2951
|
let authContext = null;
|
|
2950
2952
|
try {
|
|
2951
2953
|
authContext = useUnifiedAuth();
|
|
2952
2954
|
} catch (error) {
|
|
2953
|
-
logger.warn(
|
|
2955
|
+
logger.warn(
|
|
2956
|
+
"NavigationMenu",
|
|
2957
|
+
"useUnifiedAuth not available, running in unauthenticated mode"
|
|
2958
|
+
);
|
|
2954
2959
|
}
|
|
2955
2960
|
let rbacContext = null;
|
|
2956
2961
|
try {
|
|
2957
2962
|
rbacContext = useRBAC();
|
|
2958
2963
|
} catch (error) {
|
|
2959
|
-
logger.warn(
|
|
2964
|
+
logger.warn(
|
|
2965
|
+
"NavigationMenu",
|
|
2966
|
+
"useRBAC not available, permission filtering disabled"
|
|
2967
|
+
);
|
|
2960
2968
|
}
|
|
2961
2969
|
const eventLoadingRaw = authContext?.eventLoading;
|
|
2962
2970
|
const eventLoading = eventLoadingRaw ?? false;
|
|
@@ -2966,19 +2974,17 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
2966
2974
|
const { selectedOrganisation } = authContext || {};
|
|
2967
2975
|
const { resolvedScope, isLoading: scopeLoading, error: scopeError } = useResolvedScope({
|
|
2968
2976
|
supabase: itemsPreFiltered ? null : supabase || null,
|
|
2969
|
-
// Skip expensive resolution if pre-filtered
|
|
2970
2977
|
selectedOrganisationId: itemsPreFiltered ? null : selectedOrganisation?.id || null,
|
|
2971
2978
|
selectedEventId: itemsPreFiltered ? null : selectedEvent?.event_id || null
|
|
2972
2979
|
});
|
|
2973
|
-
|
|
2974
|
-
React15.useEffect(() => {
|
|
2980
|
+
React13.useEffect(() => {
|
|
2975
2981
|
if (!scopeLoading && !resolvedScope?.appId && selectedOrganisation?.id && authContext?.appName && authContext?.user?.id && !resolvedAppId) {
|
|
2976
2982
|
if (!authContext.user || !authContext.appName) {
|
|
2977
2983
|
return;
|
|
2978
2984
|
}
|
|
2979
2985
|
const userId2 = authContext.user.id;
|
|
2980
2986
|
const appName = authContext.appName;
|
|
2981
|
-
import("./api-
|
|
2987
|
+
import("./api-MVVQZLJI.js").then(({ resolveAppContext }) => {
|
|
2982
2988
|
resolveAppContext({
|
|
2983
2989
|
userId: userId2,
|
|
2984
2990
|
appName
|
|
@@ -2986,12 +2992,20 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
2986
2992
|
if (result?.appId) {
|
|
2987
2993
|
setResolvedAppId(result.appId);
|
|
2988
2994
|
}
|
|
2989
|
-
}).catch((
|
|
2995
|
+
}).catch(() => {
|
|
2990
2996
|
});
|
|
2997
|
+
}).catch(() => {
|
|
2991
2998
|
});
|
|
2992
2999
|
}
|
|
2993
|
-
}, [
|
|
2994
|
-
|
|
3000
|
+
}, [
|
|
3001
|
+
scopeLoading,
|
|
3002
|
+
resolvedScope?.appId,
|
|
3003
|
+
selectedOrganisation?.id,
|
|
3004
|
+
authContext?.appName,
|
|
3005
|
+
authContext?.user?.id,
|
|
3006
|
+
resolvedAppId
|
|
3007
|
+
]);
|
|
3008
|
+
const effectiveScope = React13.useMemo(() => {
|
|
2995
3009
|
if (resolvedScope?.organisationId) {
|
|
2996
3010
|
return resolvedScope;
|
|
2997
3011
|
}
|
|
@@ -3006,7 +3020,7 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3006
3020
|
return null;
|
|
3007
3021
|
}, [resolvedScope, selectedOrganisation?.id, selectedEvent?.event_id, resolvedAppId]);
|
|
3008
3022
|
const scopeKey = effectiveScope ? `${effectiveScope.organisationId || ""}-${effectiveScope.eventId || ""}-${effectiveScope.appId || ""}` : "empty";
|
|
3009
|
-
const stableScope =
|
|
3023
|
+
const stableScope = React13.useMemo(() => {
|
|
3010
3024
|
if (effectiveScope?.organisationId) {
|
|
3011
3025
|
return {
|
|
3012
3026
|
organisationId: effectiveScope.organisationId,
|
|
@@ -3021,18 +3035,18 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3021
3035
|
};
|
|
3022
3036
|
}, [scopeKey, effectiveScope]);
|
|
3023
3037
|
const userId = authContext?.user?.id || "";
|
|
3024
|
-
const {
|
|
3038
|
+
const {
|
|
3039
|
+
permissions: permissionMap,
|
|
3040
|
+
hasAnyPermission,
|
|
3041
|
+
isLoading: permissionsLoading,
|
|
3042
|
+
error: permissionsError
|
|
3043
|
+
} = usePermissions(
|
|
3025
3044
|
itemsPreFiltered ? null : userId,
|
|
3026
|
-
// Pass null to trigger early return (empty string would wait 3s)
|
|
3027
3045
|
itemsPreFiltered ? void 0 : stableScope.organisationId,
|
|
3028
|
-
// Pass undefined to skip timeout
|
|
3029
3046
|
itemsPreFiltered ? void 0 : stableScope.eventId,
|
|
3030
|
-
// Skip if pre-filtered
|
|
3031
3047
|
itemsPreFiltered ? void 0 : stableScope.appId
|
|
3032
|
-
// Skip if pre-filtered
|
|
3033
3048
|
);
|
|
3034
|
-
const
|
|
3035
|
-
const filteredItems = React15.useMemo(() => {
|
|
3049
|
+
const filteredItems = React13.useMemo(() => {
|
|
3036
3050
|
if (itemsPreFiltered && items && items.length > 0) {
|
|
3037
3051
|
const visibleItems = (items || []).filter((item) => !item.meta?.hidden);
|
|
3038
3052
|
previousFilteredItemsRef.current = visibleItems;
|
|
@@ -3061,9 +3075,13 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3061
3075
|
return [];
|
|
3062
3076
|
}
|
|
3063
3077
|
if (permissionsError) {
|
|
3064
|
-
logger.warn(
|
|
3065
|
-
|
|
3066
|
-
|
|
3078
|
+
logger.warn(
|
|
3079
|
+
"NavigationMenu",
|
|
3080
|
+
"Permission check error - showing no items for security",
|
|
3081
|
+
{
|
|
3082
|
+
permissionsError: permissionsError?.message
|
|
3083
|
+
}
|
|
3084
|
+
);
|
|
3067
3085
|
return [];
|
|
3068
3086
|
}
|
|
3069
3087
|
if (!permissionMap || Object.keys(permissionMap).length === 0) {
|
|
@@ -3089,7 +3107,7 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3089
3107
|
if (item.permissions && item.permissions.length > 0 && !item.href) {
|
|
3090
3108
|
const permissions = item.permissions.filter((p) => typeof p === "string").map((p) => p);
|
|
3091
3109
|
if (permissions.length > 0) {
|
|
3092
|
-
const hasPermission = hasAnyPermission(permissions);
|
|
3110
|
+
const hasPermission = hasAnyPermission?.(permissions);
|
|
3093
3111
|
if (!hasPermission) {
|
|
3094
3112
|
return false;
|
|
3095
3113
|
}
|
|
@@ -3121,13 +3139,12 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3121
3139
|
if (typeof item.accessLevel === "string") {
|
|
3122
3140
|
const accessLevel = item.accessLevel.toLowerCase();
|
|
3123
3141
|
const userEventRole = rbacContext.eventAppRole;
|
|
3124
|
-
if (rbacContext.isSuperAdmin) {
|
|
3125
|
-
} else {
|
|
3142
|
+
if (!rbacContext.isSuperAdmin) {
|
|
3126
3143
|
const roleToAccessLevel = {
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3144
|
+
viewer: "viewer",
|
|
3145
|
+
participant: "participant",
|
|
3146
|
+
planner: "planner",
|
|
3147
|
+
event_admin: "admin"
|
|
3131
3148
|
};
|
|
3132
3149
|
const userAccessLevel = userEventRole ? roleToAccessLevel[userEventRole] || "viewer" : null;
|
|
3133
3150
|
const levelHierarchy = {
|
|
@@ -3180,7 +3197,6 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3180
3197
|
}, [
|
|
3181
3198
|
items,
|
|
3182
3199
|
itemsPreFiltered,
|
|
3183
|
-
// Add itemsPreFiltered to dependencies
|
|
3184
3200
|
authContext,
|
|
3185
3201
|
rbacContext,
|
|
3186
3202
|
permissionMap,
|
|
@@ -3191,13 +3207,48 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3191
3207
|
resolvedScope,
|
|
3192
3208
|
effectiveScope,
|
|
3193
3209
|
auditLog,
|
|
3194
|
-
// Add event context state to dependencies so we re-check permissions when event context becomes available
|
|
3195
3210
|
eventLoadingRaw,
|
|
3196
3211
|
eventLoading,
|
|
3197
3212
|
selectedEvent,
|
|
3198
3213
|
orgContextReady,
|
|
3199
|
-
selectedOrganisation?.id
|
|
3214
|
+
selectedOrganisation?.id,
|
|
3215
|
+
permissionsError,
|
|
3216
|
+
stableScope.organisationId,
|
|
3217
|
+
stableScope.eventId,
|
|
3218
|
+
stableScope.appId
|
|
3200
3219
|
]);
|
|
3220
|
+
return {
|
|
3221
|
+
authContext,
|
|
3222
|
+
rbacContext,
|
|
3223
|
+
filteredItems,
|
|
3224
|
+
permissionMap,
|
|
3225
|
+
hasAnyPermission: hasAnyPermission || null
|
|
3226
|
+
};
|
|
3227
|
+
}
|
|
3228
|
+
|
|
3229
|
+
// src/components/NavigationMenu/NavigationMenu.tsx
|
|
3230
|
+
import { jsx as jsx17, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
3231
|
+
var NavigationMenu = React14.forwardRef(({
|
|
3232
|
+
items,
|
|
3233
|
+
mode = "dropdown",
|
|
3234
|
+
currentPath,
|
|
3235
|
+
onNavigate,
|
|
3236
|
+
className,
|
|
3237
|
+
disabled = false,
|
|
3238
|
+
buttonText = "Menu",
|
|
3239
|
+
showIcons = true,
|
|
3240
|
+
navigationLabel = "Main navigation",
|
|
3241
|
+
// NEW: Phase 2 - Enhanced Security Features
|
|
3242
|
+
strictMode = true,
|
|
3243
|
+
auditLog = true,
|
|
3244
|
+
onNavigationAccessDenied,
|
|
3245
|
+
onStrictModeViolation,
|
|
3246
|
+
itemsPreFiltered = false,
|
|
3247
|
+
...props
|
|
3248
|
+
}, ref) => {
|
|
3249
|
+
const [expandedItems, setExpandedItems] = React14.useState(/* @__PURE__ */ new Set());
|
|
3250
|
+
const buttonRef = React14.useRef(null);
|
|
3251
|
+
const { authContext, rbacContext, filteredItems, permissionMap, hasAnyPermission } = useNavigationFiltering({ items, itemsPreFiltered, auditLog });
|
|
3201
3252
|
const handleHierarchicalKeyDown = (event, item) => {
|
|
3202
3253
|
switch (event.key) {
|
|
3203
3254
|
case "Enter":
|
|
@@ -3340,7 +3391,7 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3340
3391
|
id: `submenu-${item.id}`,
|
|
3341
3392
|
role: "menu",
|
|
3342
3393
|
"aria-label": `${item.label} submenu`,
|
|
3343
|
-
children: item.children.map((child) => /* @__PURE__ */ jsx17(
|
|
3394
|
+
children: item.children.map((child) => /* @__PURE__ */ jsx17(React14.Fragment, { children: renderHierarchicalItem(child, level + 1) }, child.id))
|
|
3344
3395
|
}
|
|
3345
3396
|
)
|
|
3346
3397
|
] }) : /* @__PURE__ */ jsx17(
|
|
@@ -3402,7 +3453,7 @@ var NavigationMenu = React15.forwardRef(({
|
|
|
3402
3453
|
className,
|
|
3403
3454
|
"aria-label": navigationLabel,
|
|
3404
3455
|
...props,
|
|
3405
|
-
children: /* @__PURE__ */ jsx17("ul", { role: "menubar", children: filteredItems.map((item) => /* @__PURE__ */ jsx17(
|
|
3456
|
+
children: /* @__PURE__ */ jsx17("ul", { role: "menubar", children: filteredItems.map((item) => /* @__PURE__ */ jsx17(React14.Fragment, { children: renderHierarchicalItem(item, 0) }, item.id)) })
|
|
3406
3457
|
}
|
|
3407
3458
|
);
|
|
3408
3459
|
});
|
|
@@ -3447,7 +3498,7 @@ function Header({
|
|
|
3447
3498
|
return /* @__PURE__ */ jsx18("header", { className: cn(
|
|
3448
3499
|
"w-full border-b border-main-200 h-16 shadow-sm bg-main-100 ",
|
|
3449
3500
|
className
|
|
3450
|
-
), role: "banner", children: /* @__PURE__ */ jsxs13("nav", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto
|
|
3501
|
+
), role: "banner", children: /* @__PURE__ */ jsxs13("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: [
|
|
3451
3502
|
logo ? logoHref ? /* @__PURE__ */ jsx18(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: logo }) : logo : logoUrl ? logoHref ? /* @__PURE__ */ jsx18(Link, { to: logoHref, className: "cursor-pointer hover:opacity-80 transition-opacity", children: /* @__PURE__ */ jsx18(
|
|
3452
3503
|
"img",
|
|
3453
3504
|
{
|
|
@@ -3488,33 +3539,37 @@ function Header({
|
|
|
3488
3539
|
itemsPreFiltered: true
|
|
3489
3540
|
}
|
|
3490
3541
|
),
|
|
3491
|
-
/* @__PURE__ */
|
|
3492
|
-
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3542
|
+
showOrgSelector ? /* @__PURE__ */ jsx18(OrganisationSelectorConditional, {}) : null,
|
|
3543
|
+
showEventSelector ? /* @__PURE__ */ jsx18(
|
|
3544
|
+
EventSelector,
|
|
3545
|
+
{
|
|
3546
|
+
placeholder: "Select event",
|
|
3547
|
+
className: cn(
|
|
3548
|
+
"w-96",
|
|
3549
|
+
// If both org selector and actions exist, EventSelector uses 1 column
|
|
3550
|
+
// If only one exists, EventSelector spans 2 columns
|
|
3551
|
+
// If neither exists, EventSelector spans 3 columns
|
|
3552
|
+
showOrgSelector && actions ? "col-span-1" : showOrgSelector || actions ? "col-span-2" : "col-span-3"
|
|
3553
|
+
),
|
|
3554
|
+
"data-testid": "event-selector"
|
|
3555
|
+
}
|
|
3556
|
+
) : null,
|
|
3557
|
+
actions,
|
|
3558
|
+
showUserMenu && (userMenu ? userMenu : /* @__PURE__ */ jsx18(
|
|
3559
|
+
UserMenu,
|
|
3560
|
+
{
|
|
3561
|
+
user: user || null,
|
|
3562
|
+
onSignOut,
|
|
3563
|
+
onChangePassword,
|
|
3564
|
+
className: "w-70"
|
|
3565
|
+
}
|
|
3566
|
+
))
|
|
3512
3567
|
] }) });
|
|
3513
3568
|
}
|
|
3514
3569
|
|
|
3515
3570
|
// src/components/Footer/Footer.tsx
|
|
3516
|
-
import
|
|
3517
|
-
import { Fragment as
|
|
3571
|
+
import React15 from "react";
|
|
3572
|
+
import { Fragment as Fragment7, jsx as jsx19, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
3518
3573
|
var FooterComponent = ({
|
|
3519
3574
|
companyName = "Solvera Solutions Pty Ltd",
|
|
3520
3575
|
year = (/* @__PURE__ */ new Date()).getFullYear(),
|
|
@@ -3527,19 +3582,19 @@ var FooterComponent = ({
|
|
|
3527
3582
|
const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
|
|
3528
3583
|
return /* @__PURE__ */ jsx19("footer", { className: cn("mt-8 py-6 flex justify-center border-t border-border bg-main-100", className), children: /* @__PURE__ */ jsxs14("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
|
|
3529
3584
|
logo && /* @__PURE__ */ jsx19("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
|
|
3530
|
-
children && /* @__PURE__ */ jsx19(
|
|
3585
|
+
children && /* @__PURE__ */ jsx19(Fragment7, { children }),
|
|
3531
3586
|
/* @__PURE__ */ jsx19("span", { className: "text-muted-foreground", children: copyrightText }),
|
|
3532
3587
|
links && links.length > 0 && /* @__PURE__ */ jsx19("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx19("li", { children: /* @__PURE__ */ jsx19("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
|
|
3533
3588
|
] }) });
|
|
3534
3589
|
};
|
|
3535
3590
|
FooterComponent.displayName = "Footer";
|
|
3536
|
-
var Footer =
|
|
3591
|
+
var Footer = React15.memo(FooterComponent);
|
|
3537
3592
|
Footer.displayName = "Footer";
|
|
3538
3593
|
|
|
3539
3594
|
// src/components/PaceAppLayout/PaceAppLayout.tsx
|
|
3540
|
-
import { useState as
|
|
3595
|
+
import { useState as useState13, useEffect as useEffect8, useMemo as useMemo9 } from "react";
|
|
3541
3596
|
import { Outlet, useNavigate, useLocation } from "react-router-dom";
|
|
3542
|
-
import { Fragment as
|
|
3597
|
+
import { Fragment as Fragment8, jsx as jsx20, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
3543
3598
|
var EMPTY_PAGE_ID_MAPPING = {};
|
|
3544
3599
|
var EMPTY_ROUTE_PERMISSIONS = {};
|
|
3545
3600
|
function PaceAppLayout({
|
|
@@ -3581,8 +3636,8 @@ function PaceAppLayout({
|
|
|
3581
3636
|
isLoading: organisationLoading
|
|
3582
3637
|
} = useOrganisations();
|
|
3583
3638
|
const { isSuperAdmin: isSuperAdminFromRBAC, isLoading: rbacLoading } = useRBAC();
|
|
3584
|
-
const [isSuperAdminDirect, setIsSuperAdminDirect] =
|
|
3585
|
-
const [isCheckingSuperAdminDirect, setIsCheckingSuperAdminDirect] =
|
|
3639
|
+
const [isSuperAdminDirect, setIsSuperAdminDirect] = useState13(false);
|
|
3640
|
+
const [isCheckingSuperAdminDirect, setIsCheckingSuperAdminDirect] = useState13(false);
|
|
3586
3641
|
useEffect8(() => {
|
|
3587
3642
|
const checkSuperAdminDirect = async () => {
|
|
3588
3643
|
if (!user?.id) {
|
|
@@ -3596,8 +3651,8 @@ function PaceAppLayout({
|
|
|
3596
3651
|
}
|
|
3597
3652
|
setIsCheckingSuperAdminDirect(true);
|
|
3598
3653
|
try {
|
|
3599
|
-
const
|
|
3600
|
-
setIsSuperAdminDirect(
|
|
3654
|
+
const superAdminStatus2 = await isSuperAdmin(user.id);
|
|
3655
|
+
setIsSuperAdminDirect(superAdminStatus2);
|
|
3601
3656
|
} catch (error) {
|
|
3602
3657
|
logger.error("PaceAppLayout", "Error checking super admin status directly", { userId: user?.id, error });
|
|
3603
3658
|
setIsSuperAdminDirect(false);
|
|
@@ -3667,6 +3722,7 @@ function PaceAppLayout({
|
|
|
3667
3722
|
return permissionString;
|
|
3668
3723
|
}, [enforcePermissions, currentRoutePermission, currentPageId]);
|
|
3669
3724
|
const shouldCheckPermission = enforcePermissions && !!currentPermission && !!currentPageId;
|
|
3725
|
+
const superAdminStatus = isSuperAdminFromRBAC ? true : isCheckingSuperAdminDirect ? null : isSuperAdminDirect;
|
|
3670
3726
|
const { can: canFromHook, isLoading: isCheckingPermission, error: permissionError } = useCan(
|
|
3671
3727
|
user?.id || "",
|
|
3672
3728
|
scope,
|
|
@@ -3674,6 +3730,8 @@ function PaceAppLayout({
|
|
|
3674
3730
|
shouldCheckPermission ? currentPageId : "",
|
|
3675
3731
|
true,
|
|
3676
3732
|
// useCache
|
|
3733
|
+
superAdminStatus,
|
|
3734
|
+
// Pass super admin status to avoid duplicate check
|
|
3677
3735
|
appName
|
|
3678
3736
|
// Pass appName for PORTAL/ADMIN special case
|
|
3679
3737
|
);
|
|
@@ -3702,7 +3760,7 @@ function PaceAppLayout({
|
|
|
3702
3760
|
onPageAccessDenied(currentPageId, currentRoutePermission);
|
|
3703
3761
|
}
|
|
3704
3762
|
}, [enforcePermissions, can, isCheckingPermission, isSuperAdmin2, currentPageId, currentRoutePermission, user?.id, strictMode, auditLog, onPageAccessDenied, onStrictModeViolation]);
|
|
3705
|
-
const [filteredMenuItems, setFilteredMenuItems] =
|
|
3763
|
+
const [filteredMenuItems, setFilteredMenuItems] = useState13(baseMenuItems);
|
|
3706
3764
|
useEffect8(() => {
|
|
3707
3765
|
let isMounted = true;
|
|
3708
3766
|
const filterItems = async () => {
|
|
@@ -3729,7 +3787,7 @@ function PaceAppLayout({
|
|
|
3729
3787
|
return;
|
|
3730
3788
|
}
|
|
3731
3789
|
try {
|
|
3732
|
-
const { isSuperAdmin: checkSuperAdminDynamic } = await import("./api-
|
|
3790
|
+
const { isSuperAdmin: checkSuperAdminDynamic } = await import("./api-MVVQZLJI.js");
|
|
3733
3791
|
const isSuper = await checkSuperAdminDynamic(user.id);
|
|
3734
3792
|
if (isSuper) {
|
|
3735
3793
|
if (isMounted) {
|
|
@@ -3744,7 +3802,7 @@ function PaceAppLayout({
|
|
|
3744
3802
|
}
|
|
3745
3803
|
}
|
|
3746
3804
|
try {
|
|
3747
|
-
const { getPermissionMap } = await import("./api-
|
|
3805
|
+
const { getPermissionMap } = await import("./api-MVVQZLJI.js");
|
|
3748
3806
|
const permissionScope = {
|
|
3749
3807
|
organisationId: currentScope.organisationId,
|
|
3750
3808
|
eventId: currentScope.eventId,
|
|
@@ -3800,7 +3858,7 @@ function PaceAppLayout({
|
|
|
3800
3858
|
let hasAccess = true;
|
|
3801
3859
|
if (currentRoute.pageId && currentRoute.permissions && currentRoute.permissions.length > 0) {
|
|
3802
3860
|
try {
|
|
3803
|
-
const { isPermittedCached } = await import("./api-
|
|
3861
|
+
const { isPermittedCached } = await import("./api-MVVQZLJI.js");
|
|
3804
3862
|
const hasPagePermission = await isPermittedCached({
|
|
3805
3863
|
userId: user?.id || "",
|
|
3806
3864
|
scope,
|
|
@@ -3816,7 +3874,7 @@ function PaceAppLayout({
|
|
|
3816
3874
|
}
|
|
3817
3875
|
}
|
|
3818
3876
|
if (hasAccess && currentRoute.roles && currentRoute.roles.length > 0 && user?.id) {
|
|
3819
|
-
const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-
|
|
3877
|
+
const { useUnifiedAuth: useUnifiedAuth2 } = await import("./UnifiedAuthProvider-CH6Z342H.js");
|
|
3820
3878
|
hasAccess = true;
|
|
3821
3879
|
}
|
|
3822
3880
|
if (!isMounted) return;
|
|
@@ -3847,20 +3905,34 @@ function PaceAppLayout({
|
|
|
3847
3905
|
};
|
|
3848
3906
|
}, [roleBasedRouting, routeConfig, location.pathname, strictMode, user?.id, fallbackRoute, scope, navigate, auditLog, onRouteAccessDenied, onRouteStrictModeViolation]);
|
|
3849
3907
|
const handleSignOut = async () => {
|
|
3850
|
-
|
|
3908
|
+
try {
|
|
3909
|
+
await signOut();
|
|
3910
|
+
} catch (error) {
|
|
3911
|
+
logger.error("PaceAppLayout", "Failed to sign out", { error: error instanceof Error ? error.message : String(error) });
|
|
3912
|
+
}
|
|
3851
3913
|
};
|
|
3852
3914
|
const handleChangePassword = async (newPassword, confirmPassword) => {
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3915
|
+
try {
|
|
3916
|
+
const result = await updatePassword(newPassword);
|
|
3917
|
+
if (result?.error) {
|
|
3918
|
+
logger.error("PaceAppLayout", "Failed to change password", { error: result.error.message });
|
|
3919
|
+
return {
|
|
3920
|
+
error: {
|
|
3921
|
+
message: result.error.message,
|
|
3922
|
+
code: result.error.name || "PASSWORD_UPDATE_ERROR"
|
|
3923
|
+
}
|
|
3924
|
+
};
|
|
3925
|
+
}
|
|
3926
|
+
return {};
|
|
3927
|
+
} catch (error) {
|
|
3928
|
+
logger.error("PaceAppLayout", "Failed to change password", { error: error instanceof Error ? error.message : String(error) });
|
|
3856
3929
|
return {
|
|
3857
3930
|
error: {
|
|
3858
|
-
message:
|
|
3859
|
-
code:
|
|
3931
|
+
message: error instanceof Error ? error.message : "An unexpected error occurred",
|
|
3932
|
+
code: "PASSWORD_UPDATE_ERROR"
|
|
3860
3933
|
}
|
|
3861
3934
|
};
|
|
3862
3935
|
}
|
|
3863
|
-
return {};
|
|
3864
3936
|
};
|
|
3865
3937
|
if (user?.id && organisationLoading && !isSuperAdmin2 && !isCheckingSuperAdminDirect && !rbacLoading && !selectedOrganisationId) {
|
|
3866
3938
|
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
|
|
@@ -3883,10 +3955,10 @@ function PaceAppLayout({
|
|
|
3883
3955
|
}
|
|
3884
3956
|
if (enforcePermissions && hasPermission === false && !isCheckingSuperAdminDirect && !isSuperAdmin2) {
|
|
3885
3957
|
if (enforcePagePermissions && pagePermissionFallback) {
|
|
3886
|
-
return /* @__PURE__ */ jsx20(
|
|
3958
|
+
return /* @__PURE__ */ jsx20(Fragment8, { children: pagePermissionFallback });
|
|
3887
3959
|
}
|
|
3888
3960
|
if (permissionFallback) {
|
|
3889
|
-
return /* @__PURE__ */ jsx20(
|
|
3961
|
+
return /* @__PURE__ */ jsx20(Fragment8, { children: permissionFallback });
|
|
3890
3962
|
}
|
|
3891
3963
|
return /* @__PURE__ */ jsx20("div", { className: "flex items-center justify-center min-h-screen", children: /* @__PURE__ */ jsxs15("div", { className: "text-center", children: [
|
|
3892
3964
|
/* @__PURE__ */ jsx20("h2", { className: "text-xl font-semibold text-acc-600 mb-2", children: "Access Denied" }),
|
|
@@ -3907,7 +3979,7 @@ function PaceAppLayout({
|
|
|
3907
3979
|
] })
|
|
3908
3980
|
] }) });
|
|
3909
3981
|
}
|
|
3910
|
-
return /* @__PURE__ */ jsxs15(
|
|
3982
|
+
return /* @__PURE__ */ jsxs15(Fragment8, { children: [
|
|
3911
3983
|
/* @__PURE__ */ jsx20(
|
|
3912
3984
|
Header,
|
|
3913
3985
|
{
|
|
@@ -3939,7 +4011,7 @@ function PaceAppLayout({
|
|
|
3939
4011
|
}
|
|
3940
4012
|
|
|
3941
4013
|
// src/components/PaceLoginPage/PaceLoginPage.tsx
|
|
3942
|
-
import { useEffect as useEffect9, useState as
|
|
4014
|
+
import { useEffect as useEffect9, useState as useState14, useContext as useContext2 } from "react";
|
|
3943
4015
|
import { useNavigate as useNavigate2, useLocation as useLocation2 } from "react-router-dom";
|
|
3944
4016
|
import { jsx as jsx21, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
3945
4017
|
var PaceLoginPage = ({
|
|
@@ -3950,9 +4022,9 @@ var PaceLoginPage = ({
|
|
|
3950
4022
|
const { signIn, isAuthenticated, isLoading, authError, user, supabase } = useUnifiedAuth();
|
|
3951
4023
|
const navigate = useNavigate2();
|
|
3952
4024
|
const location = useLocation2();
|
|
3953
|
-
const [isSigningIn, setIsSigningIn] =
|
|
3954
|
-
const [accessError, setAccessError] =
|
|
3955
|
-
const [isCheckingAccess, setIsCheckingAccess] =
|
|
4025
|
+
const [isSigningIn, setIsSigningIn] = useState14(false);
|
|
4026
|
+
const [accessError, setAccessError] = useState14(null);
|
|
4027
|
+
const [isCheckingAccess, setIsCheckingAccess] = useState14(false);
|
|
3956
4028
|
const eventServiceContext = useContext2(EventServiceContext);
|
|
3957
4029
|
const eventService = eventServiceContext?.eventService || null;
|
|
3958
4030
|
useEffect9(() => {
|
|
@@ -4104,7 +4176,7 @@ var SessionRestorationLoader = ({
|
|
|
4104
4176
|
className
|
|
4105
4177
|
}) => {
|
|
4106
4178
|
return /* @__PURE__ */ jsxs17(
|
|
4107
|
-
|
|
4179
|
+
Alert,
|
|
4108
4180
|
{
|
|
4109
4181
|
className: cn(
|
|
4110
4182
|
"flex flex-col items-center justify-center h-screen w-full gap-4 text-center p-4 bg-background",
|
|
@@ -4115,19 +4187,18 @@ var SessionRestorationLoader = ({
|
|
|
4115
4187
|
"aria-label": message,
|
|
4116
4188
|
children: [
|
|
4117
4189
|
/* @__PURE__ */ jsx22(LoadingSpinner, { size: "lg" }),
|
|
4118
|
-
/* @__PURE__ */ jsx22("
|
|
4190
|
+
/* @__PURE__ */ jsx22("span", { className: "text-sm text-sec-600", children: message })
|
|
4119
4191
|
]
|
|
4120
4192
|
}
|
|
4121
4193
|
);
|
|
4122
4194
|
};
|
|
4123
4195
|
|
|
4124
4196
|
// src/components/ProtectedRoute/ProtectedRoute.tsx
|
|
4125
|
-
import { useMemo as useMemo10, useEffect as useEffect10, useRef as
|
|
4197
|
+
import { useMemo as useMemo10, useEffect as useEffect10, useRef as useRef9, useState as useState15 } from "react";
|
|
4126
4198
|
import { Navigate, Outlet as Outlet2 } from "react-router-dom";
|
|
4127
4199
|
import { jsx as jsx23, jsxs as jsxs18 } from "react/jsx-runtime";
|
|
4128
4200
|
function ProtectedRoute({
|
|
4129
4201
|
requireEvent = false,
|
|
4130
|
-
allowSuperAdminBypass = false,
|
|
4131
4202
|
noEventsFallback,
|
|
4132
4203
|
loadingFallback,
|
|
4133
4204
|
loginPath = "/login"
|
|
@@ -4139,9 +4210,9 @@ function ProtectedRoute({
|
|
|
4139
4210
|
const eventLoading = requireEvent ? eventsContext.isLoading || false : false;
|
|
4140
4211
|
const sessionRestoration = useSessionRestoration();
|
|
4141
4212
|
usePreventTabReload({ enabled: true, gracePeriodMs: 2e3 });
|
|
4142
|
-
const wasAuthenticatedRef =
|
|
4143
|
-
const [shouldRedirect, setShouldRedirect] =
|
|
4144
|
-
const tabJustBecameVisibleRef =
|
|
4213
|
+
const wasAuthenticatedRef = useRef9(false);
|
|
4214
|
+
const [shouldRedirect, setShouldRedirect] = useState15(false);
|
|
4215
|
+
const tabJustBecameVisibleRef = useRef9(false);
|
|
4145
4216
|
useEffect10(() => {
|
|
4146
4217
|
if (isAuthenticated) {
|
|
4147
4218
|
wasAuthenticatedRef.current = true;
|
|
@@ -4255,8 +4326,8 @@ function ProtectedRoute({
|
|
|
4255
4326
|
}
|
|
4256
4327
|
|
|
4257
4328
|
// src/components/FileUpload/FileUpload.tsx
|
|
4258
|
-
import { useState as
|
|
4259
|
-
import { Fragment as
|
|
4329
|
+
import { useState as useState16, useCallback as useCallback11, useRef as useRef10, useEffect as useEffect11, useMemo as useMemo11 } from "react";
|
|
4330
|
+
import { Fragment as Fragment9, jsx as jsx24, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
4260
4331
|
function FileUpload({
|
|
4261
4332
|
supabase,
|
|
4262
4333
|
table_name,
|
|
@@ -4282,12 +4353,19 @@ function FileUpload({
|
|
|
4282
4353
|
onProgress,
|
|
4283
4354
|
children
|
|
4284
4355
|
}) {
|
|
4285
|
-
|
|
4286
|
-
|
|
4287
|
-
|
|
4288
|
-
|
|
4289
|
-
|
|
4290
|
-
|
|
4356
|
+
if (!pageContext) {
|
|
4357
|
+
const errorMsg = "pageContext is required for FileUpload component. This is used for permission checks.";
|
|
4358
|
+
if (import.meta.env.MODE === "development") {
|
|
4359
|
+
console.error("[FileUpload]", errorMsg);
|
|
4360
|
+
}
|
|
4361
|
+
throw new Error(errorMsg);
|
|
4362
|
+
}
|
|
4363
|
+
const [isDragging, setIsDragging] = useState16(false);
|
|
4364
|
+
const [uploadStates, setUploadStates] = useState16(/* @__PURE__ */ new Map());
|
|
4365
|
+
const [resolvedAppId, setResolvedAppId] = useState16(app_id || null);
|
|
4366
|
+
const [isResolvingAppId, setIsResolvingAppId] = useState16(!app_id);
|
|
4367
|
+
const [appIdError, setAppIdError] = useState16(null);
|
|
4368
|
+
const fileInputRef = useRef10(null);
|
|
4291
4369
|
const { uploadFile, isLoading, error } = useFileReference(supabase);
|
|
4292
4370
|
useEffect11(() => {
|
|
4293
4371
|
if (app_id) {
|
|
@@ -4449,6 +4527,10 @@ function FileUpload({
|
|
|
4449
4527
|
const errorMsg = appIdError || "App ID not available. Please provide app_id prop or set app name.";
|
|
4450
4528
|
throw new Error(errorMsg);
|
|
4451
4529
|
}
|
|
4530
|
+
if (!pageContext) {
|
|
4531
|
+
const errorMsg = "pageContext is required for file upload. This is used for permission checks.";
|
|
4532
|
+
throw new Error(errorMsg);
|
|
4533
|
+
}
|
|
4452
4534
|
const result = await uploadFile({
|
|
4453
4535
|
table_name,
|
|
4454
4536
|
record_id,
|
|
@@ -4546,7 +4628,7 @@ function FileUpload({
|
|
|
4546
4628
|
onUploadError?.(errorMessage, file);
|
|
4547
4629
|
}
|
|
4548
4630
|
}
|
|
4549
|
-
}, [uploadFile, table_name, record_id, organisation_id, resolvedAppId, category, folder, isPublic, maxSize, onUploadSuccess, onUploadError, onProgress, validateFile, generatePreview, showPreview, appIdError]);
|
|
4631
|
+
}, [uploadFile, table_name, record_id, organisation_id, resolvedAppId, category, folder, isPublic, maxSize, onUploadSuccess, onUploadError, onProgress, validateFile, generatePreview, showPreview, appIdError, pageContext]);
|
|
4550
4632
|
const handleDragOver = useCallback11((e) => {
|
|
4551
4633
|
e.preventDefault();
|
|
4552
4634
|
e.stopPropagation();
|
|
@@ -4618,10 +4700,11 @@ function FileUpload({
|
|
|
4618
4700
|
onChange: handleFileInputChange,
|
|
4619
4701
|
className: "hidden",
|
|
4620
4702
|
disabled: isDisabled,
|
|
4621
|
-
"data-testid": "file-input"
|
|
4703
|
+
"data-testid": "file-input",
|
|
4704
|
+
"aria-label": accept ? `Upload file${multiple ? "s" : ""} (${accept})` : `Upload file${multiple ? "s" : ""}`
|
|
4622
4705
|
}
|
|
4623
4706
|
),
|
|
4624
|
-
/* @__PURE__ */ jsx24("div", { className: "text-sec-600", children: isResolvingAppId ? "Resolving app configuration..." : isDragging ? "Drop files here..." : /* @__PURE__ */ jsxs19(
|
|
4707
|
+
/* @__PURE__ */ jsx24("div", { className: "text-sec-600", children: isResolvingAppId ? "Resolving app configuration..." : isDragging ? "Drop files here..." : /* @__PURE__ */ jsxs19(Fragment9, { children: [
|
|
4625
4708
|
/* @__PURE__ */ jsx24("span", { className: "font-medium", children: "Click to upload" }),
|
|
4626
4709
|
" ",
|
|
4627
4710
|
"or drag and drop"
|
|
@@ -4727,9 +4810,9 @@ function FileUpload({
|
|
|
4727
4810
|
}
|
|
4728
4811
|
|
|
4729
4812
|
// src/components/Table/Table.tsx
|
|
4730
|
-
import * as
|
|
4813
|
+
import * as React20 from "react";
|
|
4731
4814
|
import { jsx as jsx25 } from "react/jsx-runtime";
|
|
4732
|
-
var Table =
|
|
4815
|
+
var Table = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
4733
4816
|
"table",
|
|
4734
4817
|
{
|
|
4735
4818
|
ref,
|
|
@@ -4738,9 +4821,9 @@ var Table = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */
|
|
|
4738
4821
|
}
|
|
4739
4822
|
));
|
|
4740
4823
|
Table.displayName = "Table";
|
|
4741
|
-
var TableHeader =
|
|
4824
|
+
var TableHeader = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25("thead", { ref, className: cn("[&_tr]:border-b", className), ...props }));
|
|
4742
4825
|
TableHeader.displayName = "TableHeader";
|
|
4743
|
-
var TableBody =
|
|
4826
|
+
var TableBody = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
4744
4827
|
"tbody",
|
|
4745
4828
|
{
|
|
4746
4829
|
ref,
|
|
@@ -4749,7 +4832,7 @@ var TableBody = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
4749
4832
|
}
|
|
4750
4833
|
));
|
|
4751
4834
|
TableBody.displayName = "TableBody";
|
|
4752
|
-
var TableFooter =
|
|
4835
|
+
var TableFooter = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
4753
4836
|
"tfoot",
|
|
4754
4837
|
{
|
|
4755
4838
|
ref,
|
|
@@ -4761,7 +4844,7 @@ var TableFooter = React21.forwardRef(({ className, ...props }, ref) => /* @__PUR
|
|
|
4761
4844
|
}
|
|
4762
4845
|
));
|
|
4763
4846
|
TableFooter.displayName = "TableFooter";
|
|
4764
|
-
var TableRow =
|
|
4847
|
+
var TableRow = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
4765
4848
|
"tr",
|
|
4766
4849
|
{
|
|
4767
4850
|
ref,
|
|
@@ -4773,7 +4856,7 @@ var TableRow = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE__
|
|
|
4773
4856
|
}
|
|
4774
4857
|
));
|
|
4775
4858
|
TableRow.displayName = "TableRow";
|
|
4776
|
-
var TableHead =
|
|
4859
|
+
var TableHead = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
4777
4860
|
"th",
|
|
4778
4861
|
{
|
|
4779
4862
|
ref,
|
|
@@ -4785,7 +4868,7 @@ var TableHead = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
4785
4868
|
}
|
|
4786
4869
|
));
|
|
4787
4870
|
TableHead.displayName = "TableHead";
|
|
4788
|
-
var TableCell =
|
|
4871
|
+
var TableCell = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
4789
4872
|
"td",
|
|
4790
4873
|
{
|
|
4791
4874
|
ref,
|
|
@@ -4794,7 +4877,7 @@ var TableCell = React21.forwardRef(({ className, ...props }, ref) => /* @__PURE_
|
|
|
4794
4877
|
}
|
|
4795
4878
|
));
|
|
4796
4879
|
TableCell.displayName = "TableCell";
|
|
4797
|
-
var TableCaption =
|
|
4880
|
+
var TableCaption = React20.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx25(
|
|
4798
4881
|
"caption",
|
|
4799
4882
|
{
|
|
4800
4883
|
ref,
|
|
@@ -4805,7 +4888,7 @@ var TableCaption = React21.forwardRef(({ className, ...props }, ref) => /* @__PU
|
|
|
4805
4888
|
TableCaption.displayName = "TableCaption";
|
|
4806
4889
|
|
|
4807
4890
|
// src/components/PublicLayout/PublicPageLayout.tsx
|
|
4808
|
-
import { Fragment as
|
|
4891
|
+
import { Fragment as Fragment10, jsx as jsx26, jsxs as jsxs20 } from "react/jsx-runtime";
|
|
4809
4892
|
function PublicPageHeader({
|
|
4810
4893
|
event,
|
|
4811
4894
|
eventCode,
|
|
@@ -4830,9 +4913,9 @@ function PublicPageHeader({
|
|
|
4830
4913
|
alt: appName
|
|
4831
4914
|
}
|
|
4832
4915
|
),
|
|
4833
|
-
event && /* @__PURE__ */ jsxs20(
|
|
4916
|
+
event && /* @__PURE__ */ jsxs20(Fragment10, { children: [
|
|
4834
4917
|
/* @__PURE__ */ jsx26("h1", { children: event.event_name }),
|
|
4835
|
-
showEventLogo && event && /* @__PURE__ */ jsx26(
|
|
4918
|
+
showEventLogo && event && /* @__PURE__ */ jsx26(Fragment10, { children: customEventLogo || /* @__PURE__ */ jsx26(
|
|
4836
4919
|
FileDisplay,
|
|
4837
4920
|
{
|
|
4838
4921
|
table_name: "event",
|
|
@@ -4851,11 +4934,11 @@ function PublicPageHeader({
|
|
|
4851
4934
|
) }),
|
|
4852
4935
|
event.event_venue && /* @__PURE__ */ jsx26("h4", { children: event.event_venue })
|
|
4853
4936
|
] }),
|
|
4854
|
-
title && /* @__PURE__ */ jsxs20(
|
|
4937
|
+
title && /* @__PURE__ */ jsxs20(Fragment10, { children: [
|
|
4855
4938
|
/* @__PURE__ */ jsx26("h1", { children: title }),
|
|
4856
4939
|
description && /* @__PURE__ */ jsx26("p", { className: "text-lg text-sec-600 max-w-3xl mx-auto", children: description })
|
|
4857
4940
|
] }),
|
|
4858
|
-
children && /* @__PURE__ */ jsx26(
|
|
4941
|
+
children && /* @__PURE__ */ jsx26(Fragment10, { children })
|
|
4859
4942
|
] });
|
|
4860
4943
|
}
|
|
4861
4944
|
function PublicPageFooter({
|
|
@@ -4871,7 +4954,7 @@ function PublicPageFooter({
|
|
|
4871
4954
|
const copyrightText = copyright || `\xA9 Copyright 2022\u2013${year} all rights reserved, ${companyName}.`;
|
|
4872
4955
|
return /* @__PURE__ */ jsx26("footer", { className: cn("mt-8 py-6 flex justify-center", className), children: /* @__PURE__ */ jsxs20("section", { className: "px-4 w-[min(var(--app-width),100%)] mx-auto text-center", children: [
|
|
4873
4956
|
logo && /* @__PURE__ */ jsx26("img", { src: logo, alt: "Logo", className: "h-8 w-auto" }),
|
|
4874
|
-
children && /* @__PURE__ */ jsx26(
|
|
4957
|
+
children && /* @__PURE__ */ jsx26(Fragment10, { children }),
|
|
4875
4958
|
/* @__PURE__ */ jsx26("span", { className: "text-muted-foreground", children: copyrightText }),
|
|
4876
4959
|
links && links.length > 0 && /* @__PURE__ */ jsx26("ul", { className: "flex gap-4 mt-2 md:mt-0", children: links.map((link, index) => /* @__PURE__ */ jsx26("li", { children: /* @__PURE__ */ jsx26("a", { href: link.href, className: "text-muted-foreground hover:text-foreground", children: link.label }) }, index)) })
|
|
4877
4960
|
] }) });
|
|
@@ -4884,7 +4967,6 @@ function PublicPageLayout({
|
|
|
4884
4967
|
error = null,
|
|
4885
4968
|
refetch,
|
|
4886
4969
|
showFooter = true,
|
|
4887
|
-
className = "",
|
|
4888
4970
|
errorFallback: ErrorFallback,
|
|
4889
4971
|
loadingFallback: LoadingFallback,
|
|
4890
4972
|
customHeader,
|
|
@@ -4925,7 +5007,7 @@ function PublicPageLayout({
|
|
|
4925
5007
|
handleRefetch && /* @__PURE__ */ jsx26(Button, { onClick: handleRefetch, children: "Try Again" })
|
|
4926
5008
|
] });
|
|
4927
5009
|
}
|
|
4928
|
-
return /* @__PURE__ */ jsx26(ErrorBoundary, { componentName: "PublicPageLayout", children: /* @__PURE__ */ jsxs20(
|
|
5010
|
+
return /* @__PURE__ */ jsx26(ErrorBoundary, { componentName: "PublicPageLayout", children: /* @__PURE__ */ jsxs20(Fragment10, { children: [
|
|
4929
5011
|
customHeader || /* @__PURE__ */ jsx26(
|
|
4930
5012
|
PublicPageHeader,
|
|
4931
5013
|
{
|
|
@@ -4990,4 +5072,4 @@ export {
|
|
|
4990
5072
|
PublicPageFooter,
|
|
4991
5073
|
PublicPageLayout
|
|
4992
5074
|
};
|
|
4993
|
-
//# sourceMappingURL=chunk-
|
|
5075
|
+
//# sourceMappingURL=chunk-NECFR5MM.js.map
|