@revealui/core 0.2.1 → 0.5.0
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/dist/api/compression.d.ts.map +1 -1
- package/dist/api/payload-optimization.d.ts.map +1 -1
- package/dist/api/rate-limit.d.ts +29 -28
- package/dist/api/rate-limit.d.ts.map +1 -1
- package/dist/api/rate-limit.js +63 -3
- package/dist/api/response-cache.d.ts.map +1 -1
- package/dist/api/response-cache.js +1 -1
- package/dist/api/rest.d.ts.map +1 -1
- package/dist/api/rest.js +3 -2
- package/dist/auth/access.d.ts.map +1 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/cache/query-cache.d.ts +12 -10
- package/dist/cache/query-cache.d.ts.map +1 -1
- package/dist/cache/query-cache.js +38 -42
- package/dist/caching/index.d.ts +6 -0
- package/dist/caching/index.d.ts.map +1 -0
- package/dist/caching/index.js +5 -0
- package/dist/client/admin/RichText.d.ts +1 -1
- package/dist/client/admin/RichText.d.ts.map +1 -1
- package/dist/client/admin/components/AdminDashboard.d.ts.map +1 -1
- package/dist/client/admin/components/AdminDashboard.js +195 -205
- package/dist/client/admin/components/CollectionList.d.ts.map +1 -1
- package/dist/client/admin/components/DocumentForm.d.ts.map +1 -1
- package/dist/client/admin/components/DocumentForm.js +130 -6
- package/dist/client/admin/components/GlobalForm.d.ts.map +1 -1
- package/dist/client/admin/context/ServerFunctionContext.d.ts +8 -0
- package/dist/client/admin/context/ServerFunctionContext.d.ts.map +1 -0
- package/dist/client/admin/context/ServerFunctionContext.js +15 -0
- package/dist/client/admin/i18n/en.d.ts.map +1 -1
- package/dist/client/admin/index.d.ts +1 -0
- package/dist/client/admin/index.d.ts.map +1 -1
- package/dist/client/admin/index.js +1 -0
- package/dist/client/admin/layout.d.ts +1 -1
- package/dist/client/admin/layout.d.ts.map +1 -1
- package/dist/client/admin/layout.js +3 -2
- package/dist/client/admin/page.d.ts.map +1 -1
- package/dist/client/admin/utils/apiClient.d.ts.map +1 -1
- package/dist/client/admin/utils/apiClient.js +0 -4
- package/dist/client/admin/utils/index.d.ts +0 -1
- package/dist/client/admin/utils/index.d.ts.map +1 -1
- package/dist/client/admin/utils/index.js +0 -1
- package/dist/client/admin/utils/serializeConfig.d.ts.map +1 -1
- package/dist/client/hooks.d.ts.map +1 -1
- package/dist/client/index.d.ts.map +1 -1
- package/dist/client/richtext/RichTextEditor.d.ts.map +1 -1
- package/dist/client/richtext/components/ImageNodeComponent.d.ts.map +1 -1
- package/dist/client/richtext/components/ImageNodeComponent.js +0 -1
- package/dist/client/richtext/components/ImageUploadButton.d.ts +2 -0
- package/dist/client/richtext/components/ImageUploadButton.d.ts.map +1 -1
- package/dist/client/richtext/components/ImageUploadButton.js +30 -15
- package/dist/client/richtext/index.d.ts.map +1 -1
- package/dist/client/richtext/nodes/DecoratorBlockNode.d.ts.map +1 -1
- package/dist/client/richtext/nodes/ImageNode.d.ts.map +1 -1
- package/dist/client/richtext/plugins/CollaborationPlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/CursorsOverlayPlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/FloatingToolbarPlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/FloatingToolbarPlugin.js +1 -3
- package/dist/client/richtext/plugins/ImagePlugin.d.ts.map +1 -1
- package/dist/client/richtext/plugins/ToolbarPlugin.d.ts.map +1 -1
- package/dist/client/ui/index.d.ts.map +1 -1
- package/dist/client/ui/index.js +1 -1
- package/dist/collections/CollectionOperations.d.ts +7 -7
- package/dist/collections/CollectionOperations.d.ts.map +1 -1
- package/dist/collections/CollectionOperations.js +15 -1
- package/dist/collections/hooks.d.ts.map +1 -1
- package/dist/collections/index.d.ts.map +1 -1
- package/dist/collections/operations/create.d.ts +4 -5
- package/dist/collections/operations/create.d.ts.map +1 -1
- package/dist/collections/operations/create.js +35 -6
- package/dist/collections/operations/createMany.d.ts +12 -0
- package/dist/collections/operations/createMany.d.ts.map +1 -0
- package/dist/collections/operations/createMany.js +43 -0
- package/dist/collections/operations/delete.d.ts +1 -1
- package/dist/collections/operations/delete.d.ts.map +1 -1
- package/dist/collections/operations/delete.js +31 -2
- package/dist/collections/operations/deleteMany.d.ts +11 -0
- package/dist/collections/operations/deleteMany.d.ts.map +1 -0
- package/dist/collections/operations/deleteMany.js +50 -0
- package/dist/collections/operations/fieldHooks.d.ts +2 -2
- package/dist/collections/operations/fieldHooks.d.ts.map +1 -1
- package/dist/collections/operations/fieldHooks.js +4 -4
- package/dist/collections/operations/find.d.ts +2 -4
- package/dist/collections/operations/find.d.ts.map +1 -1
- package/dist/collections/operations/find.js +115 -8
- package/dist/collections/operations/findById.d.ts +3 -4
- package/dist/collections/operations/findById.d.ts.map +1 -1
- package/dist/collections/operations/findById.js +53 -1
- package/dist/collections/operations/sqlAdapter.d.ts +23 -0
- package/dist/collections/operations/sqlAdapter.d.ts.map +1 -0
- package/dist/collections/operations/sqlAdapter.js +76 -0
- package/dist/collections/operations/update.d.ts +3 -5
- package/dist/collections/operations/update.d.ts.map +1 -1
- package/dist/collections/operations/update.js +103 -11
- package/dist/collections/operations/updateMany.d.ts +11 -0
- package/dist/collections/operations/updateMany.d.ts.map +1 -0
- package/dist/collections/operations/updateMany.js +52 -0
- package/dist/collections/registry.d.ts +12 -0
- package/dist/collections/registry.d.ts.map +1 -0
- package/dist/collections/registry.js +38 -0
- package/dist/config/index.d.ts.map +1 -1
- package/dist/config/runtime.d.ts.map +1 -1
- package/dist/config/utils.d.ts +0 -10
- package/dist/config/utils.d.ts.map +1 -1
- package/dist/config/utils.js +0 -13
- package/dist/database/index.d.ts +3 -0
- package/dist/database/index.d.ts.map +1 -1
- package/dist/database/index.js +1 -5
- package/dist/database/safe-parse.d.ts.map +1 -1
- package/dist/database/ssl-config.d.ts.map +1 -1
- package/dist/database/type-adapter.d.ts.map +1 -1
- package/dist/database/universal-postgres.d.ts.map +1 -1
- package/dist/database/universal-postgres.js +6 -1
- package/dist/dataloader.d.ts.map +1 -1
- package/dist/error-handling/error-boundary.d.ts.map +1 -1
- package/dist/error-handling/error-reporter.d.ts +1 -1
- package/dist/error-handling/error-reporter.d.ts.map +1 -1
- package/dist/error-handling/error-reporter.js +19 -5
- package/dist/error-handling/fallback-components.d.ts.map +1 -1
- package/dist/error-handling/fallback-components.js +1 -1
- package/dist/error-handling/index.d.ts +2 -4
- package/dist/error-handling/index.d.ts.map +1 -1
- package/dist/error-handling/index.js +1 -4
- package/dist/factories/builders.d.ts.map +1 -1
- package/dist/factories/index.d.ts.map +1 -1
- package/dist/features.d.ts +7 -7
- package/dist/features.d.ts.map +1 -1
- package/dist/features.js +2 -2
- package/dist/fieldTraversal.d.ts.map +1 -1
- package/dist/fields/config/types.d.ts.map +1 -1
- package/dist/fields/getDefaultValue.d.ts.map +1 -1
- package/dist/fields/getFieldPaths.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/index.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/promise.d.ts.map +1 -1
- package/dist/fields/hooks/afterRead/traverseFields.d.ts.map +1 -1
- package/dist/generated/types/cms.d.ts.map +1 -1
- package/dist/generated/types/cms.js +0 -1
- package/dist/generated/types/neon.d.ts.map +1 -1
- package/dist/generated/types/neon.js +4 -2
- package/dist/globals/GlobalOperations.d.ts.map +1 -1
- package/dist/globals/GlobalOperations.js +16 -4
- package/dist/globals/index.d.ts.map +1 -1
- package/dist/index.d.ts +15 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/instance/RevealUIInstance.d.ts.map +1 -1
- package/dist/instance/RevealUIInstance.js +6 -19
- package/dist/instance/index.d.ts.map +1 -1
- package/dist/instance/logger.d.ts.map +1 -1
- package/dist/instance/methods/create.d.ts.map +1 -1
- package/dist/instance/methods/create.js +0 -3
- package/dist/instance/methods/delete.d.ts.map +1 -1
- package/dist/instance/methods/delete.js +1 -4
- package/dist/instance/methods/find.d.ts.map +1 -1
- package/dist/instance/methods/find.js +0 -3
- package/dist/instance/methods/findById.d.ts.map +1 -1
- package/dist/instance/methods/findById.js +0 -3
- package/dist/instance/methods/hooks.d.ts.map +1 -1
- package/dist/instance/methods/update.d.ts.map +1 -1
- package/dist/instance/methods/update.js +0 -3
- package/dist/jobs/index.d.ts +16 -0
- package/dist/jobs/index.d.ts.map +1 -0
- package/dist/jobs/index.js +14 -0
- package/dist/jobs/queue.d.ts +57 -0
- package/dist/jobs/queue.d.ts.map +1 -0
- package/dist/jobs/queue.js +134 -0
- package/dist/license-encryption.d.ts +21 -0
- package/dist/license-encryption.d.ts.map +1 -0
- package/dist/license-encryption.js +74 -0
- package/dist/license.d.ts +26 -3
- package/dist/license.d.ts.map +1 -1
- package/dist/license.js +87 -7
- package/dist/monitoring/alerts.d.ts +4 -4
- package/dist/monitoring/alerts.d.ts.map +1 -1
- package/dist/monitoring/cleanup-manager.d.ts.map +1 -1
- package/dist/monitoring/health-monitor.d.ts.map +1 -1
- package/dist/monitoring/index.d.ts.map +1 -1
- package/dist/monitoring/process-registry.d.ts.map +1 -1
- package/dist/monitoring/query-monitor.d.ts.map +1 -1
- package/dist/monitoring/types.d.ts.map +1 -1
- package/dist/monitoring/zombie-detector.d.ts.map +1 -1
- package/dist/monitoring/zombie-detector.js +5 -0
- package/dist/nextjs/index.d.ts.map +1 -1
- package/dist/nextjs/utilities.d.ts.map +1 -1
- package/dist/nextjs/withRevealUI.d.ts.map +1 -1
- package/dist/observability/alerts.d.ts.map +1 -1
- package/dist/observability/alerts.js +1 -2
- package/dist/observability/health-check.d.ts +0 -4
- package/dist/observability/health-check.d.ts.map +1 -1
- package/dist/observability/health-check.js +0 -36
- package/dist/observability/index.d.ts.map +1 -1
- package/dist/observability/logger.d.ts.map +1 -1
- package/dist/observability/logger.js +1 -1
- package/dist/observability/metrics.d.ts.map +1 -1
- package/dist/observability/tracing.d.ts.map +1 -1
- package/dist/observability/tracing.js +0 -1
- package/dist/plugins/form-builder.d.ts.map +1 -1
- package/dist/plugins/index.d.ts.map +1 -1
- package/dist/plugins/nested-docs.d.ts +4 -0
- package/dist/plugins/nested-docs.d.ts.map +1 -1
- package/dist/plugins/nested-docs.js +50 -6
- package/dist/plugins/redirects.d.ts.map +1 -1
- package/dist/queries/index.d.ts.map +1 -1
- package/dist/queries/queryBuilder.d.ts.map +1 -1
- package/dist/queries/queryBuilder.js +13 -5
- package/dist/relationships/analyzer.d.ts.map +1 -1
- package/dist/relationships/analyzer.js +8 -0
- package/dist/relationships/index.d.ts.map +1 -1
- package/dist/relationships/populate-core.d.ts +57 -0
- package/dist/relationships/populate-core.d.ts.map +1 -0
- package/dist/relationships/populate-core.js +116 -0
- package/dist/relationships/populate-helpers.d.ts +5 -51
- package/dist/relationships/populate-helpers.d.ts.map +1 -1
- package/dist/relationships/populate-helpers.js +4 -109
- package/dist/relationships/population.d.ts +1 -9
- package/dist/relationships/population.d.ts.map +1 -1
- package/dist/relationships/population.js +8 -3
- package/dist/revealui.d.ts.map +1 -1
- package/dist/richtext/exports/client/rcc.d.ts.map +1 -1
- package/dist/richtext/exports/client/rcc.js +1 -1
- package/dist/richtext/exports/server/rsc.d.ts +17 -0
- package/dist/richtext/exports/server/rsc.d.ts.map +1 -1
- package/dist/richtext/exports/server/rsc.js +61 -5
- package/dist/richtext/index.d.ts.map +1 -1
- package/dist/richtext/lexical.d.ts.map +1 -1
- package/dist/security/index.d.ts +3 -16
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/index.js +3 -16
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/renderPage.d.ts.map +1 -1
- package/dist/storage/index.d.ts +1 -0
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +2 -4
- package/dist/storage/vercel-blob.d.ts.map +1 -1
- package/dist/storage/vercel-blob.js +3 -0
- package/dist/translations/index.d.ts.map +1 -1
- package/dist/types/access.d.ts.map +1 -1
- package/dist/types/api.d.ts.map +1 -1
- package/dist/types/cms.d.ts.map +1 -1
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/core.d.ts +1 -1
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/extensions.d.ts.map +1 -1
- package/dist/types/frontend.d.ts.map +1 -1
- package/dist/types/generated.d.ts.map +1 -1
- package/dist/types/hooks.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/interfaces/app.d.ts.map +1 -1
- package/dist/types/jobs.d.ts.map +1 -1
- package/dist/types/legacy.d.ts.map +1 -1
- package/dist/types/plugins.d.ts.map +1 -1
- package/dist/types/query.d.ts.map +1 -1
- package/dist/types/request.d.ts.map +1 -1
- package/dist/types/richtext.d.ts.map +1 -1
- package/dist/types/runtime.d.ts +60 -1
- package/dist/types/runtime.d.ts.map +1 -1
- package/dist/types/schema.d.ts.map +1 -1
- package/dist/types/user.d.ts.map +1 -1
- package/dist/utils/access-conversion.d.ts.map +1 -1
- package/dist/utils/api-wrapper.d.ts.map +1 -1
- package/dist/utils/api-wrapper.js +1 -1
- package/dist/utils/block-conversion.d.ts.map +1 -1
- package/dist/utils/cache.d.ts.map +1 -1
- package/dist/utils/deep-clone.js +0 -1
- package/dist/utils/error-responses.d.ts.map +1 -1
- package/dist/utils/error-responses.js +2 -3
- package/dist/utils/errors.d.ts +36 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +103 -0
- package/dist/utils/field-conversion.d.ts +1 -1
- package/dist/utils/field-conversion.d.ts.map +1 -1
- package/dist/utils/flattenResult.d.ts.map +1 -1
- package/dist/utils/flattenResult.js +0 -1
- package/dist/utils/getBlockSelect.d.ts.map +1 -1
- package/dist/utils/getSelectMode.d.ts.map +1 -1
- package/dist/utils/isValidID.d.ts.map +1 -1
- package/dist/utils/json-parsing.d.ts.map +1 -1
- package/dist/utils/logger-client.d.ts.map +1 -1
- package/dist/utils/logger-server.d.ts.map +1 -1
- package/dist/utils/logger.d.ts.map +1 -1
- package/dist/utils/request-context.d.ts.map +1 -1
- package/dist/utils/stripUnselectedFields.d.ts.map +1 -1
- package/dist/utils/type-guards.d.ts.map +1 -1
- package/package.json +58 -26
- package/dist/caching/app-cache.d.ts +0 -237
- package/dist/caching/app-cache.d.ts.map +0 -1
- package/dist/caching/app-cache.js +0 -430
- package/dist/caching/cdn-config.d.ts +0 -155
- package/dist/caching/cdn-config.d.ts.map +0 -1
- package/dist/caching/cdn-config.js +0 -411
- package/dist/caching/edge-cache.d.ts +0 -177
- package/dist/caching/edge-cache.d.ts.map +0 -1
- package/dist/caching/edge-cache.js +0 -385
- package/dist/caching/service-worker.d.ts +0 -154
- package/dist/caching/service-worker.d.ts.map +0 -1
- package/dist/caching/service-worker.js +0 -437
- package/dist/client/admin/utils/auth.d.ts +0 -23
- package/dist/client/admin/utils/auth.d.ts.map +0 -1
- package/dist/client/admin/utils/auth.js +0 -52
- package/dist/client/http/client.d.ts +0 -15
- package/dist/client/http/client.d.ts.map +0 -1
- package/dist/client/http/client.js +0 -49
- package/dist/client/http/fetchBanner.d.ts +0 -18
- package/dist/client/http/fetchBanner.d.ts.map +0 -1
- package/dist/client/http/fetchBanner.js +0 -44
- package/dist/client/http/fetchCard.d.ts +0 -18
- package/dist/client/http/fetchCard.d.ts.map +0 -1
- package/dist/client/http/fetchCard.js +0 -46
- package/dist/client/http/fetchEvents.d.ts +0 -18
- package/dist/client/http/fetchEvents.d.ts.map +0 -1
- package/dist/client/http/fetchEvents.js +0 -44
- package/dist/client/http/fetchHero.d.ts +0 -17
- package/dist/client/http/fetchHero.d.ts.map +0 -1
- package/dist/client/http/fetchHero.js +0 -55
- package/dist/client/http/fetchMainInfos.d.ts +0 -17
- package/dist/client/http/fetchMainInfos.d.ts.map +0 -1
- package/dist/client/http/fetchMainInfos.js +0 -44
- package/dist/client/http/fetchVideos.d.ts +0 -13
- package/dist/client/http/fetchVideos.d.ts.map +0 -1
- package/dist/client/http/fetchVideos.js +0 -36
- package/dist/client/http/index.d.ts +0 -19
- package/dist/client/http/index.d.ts.map +0 -1
- package/dist/client/http/index.js +0 -11
- package/dist/error-handling/circuit-breaker.d.ts +0 -262
- package/dist/error-handling/circuit-breaker.d.ts.map +0 -1
- package/dist/error-handling/circuit-breaker.js +0 -542
- package/dist/error-handling/retry.d.ts +0 -194
- package/dist/error-handling/retry.d.ts.map +0 -1
- package/dist/error-handling/retry.js +0 -450
- package/dist/errors/index.d.ts +0 -23
- package/dist/errors/index.d.ts.map +0 -1
- package/dist/errors/index.js +0 -40
- package/dist/generated/agents/index.d.ts +0 -8
- package/dist/generated/agents/index.d.ts.map +0 -1
- package/dist/generated/agents/index.js +0 -7
- package/dist/generated/components/index.d.ts +0 -8
- package/dist/generated/components/index.d.ts.map +0 -1
- package/dist/generated/components/index.js +0 -7
- package/dist/generated/functions/index.d.ts +0 -8
- package/dist/generated/functions/index.d.ts.map +0 -1
- package/dist/generated/functions/index.js +0 -7
- package/dist/generated/hooks/index.d.ts +0 -8
- package/dist/generated/hooks/index.d.ts.map +0 -1
- package/dist/generated/hooks/index.js +0 -7
- package/dist/generated/plans/index.d.ts +0 -8
- package/dist/generated/plans/index.d.ts.map +0 -1
- package/dist/generated/plans/index.js +0 -7
- package/dist/generated/prompts/index.d.ts +0 -8
- package/dist/generated/prompts/index.d.ts.map +0 -1
- package/dist/generated/prompts/index.js +0 -7
- package/dist/generated/tools/index.d.ts +0 -8
- package/dist/generated/tools/index.d.ts.map +0 -1
- package/dist/generated/tools/index.js +0 -7
- package/dist/generated/types/supabase.d.ts +0 -193
- package/dist/generated/types/supabase.d.ts.map +0 -1
- package/dist/generated/types/supabase.js +0 -5
- package/dist/optimization/asset-optimizer.d.ts +0 -202
- package/dist/optimization/asset-optimizer.d.ts.map +0 -1
- package/dist/optimization/asset-optimizer.js +0 -312
- package/dist/optimization/build-optimizer.d.ts +0 -202
- package/dist/optimization/build-optimizer.d.ts.map +0 -1
- package/dist/optimization/build-optimizer.js +0 -271
- package/dist/optimization/bundle-analyzer.d.ts +0 -98
- package/dist/optimization/bundle-analyzer.d.ts.map +0 -1
- package/dist/optimization/bundle-analyzer.js +0 -322
- package/dist/optimization/code-splitting.d.ts +0 -131
- package/dist/optimization/code-splitting.d.ts.map +0 -1
- package/dist/optimization/code-splitting.js +0 -277
- package/dist/plugin/index.d.ts +0 -12
- package/dist/plugin/index.d.ts.map +0 -1
- package/dist/plugin/index.js +0 -4
- package/dist/security/audit.d.ts +0 -188
- package/dist/security/audit.d.ts.map +0 -1
- package/dist/security/audit.js +0 -431
- package/dist/security/auth.d.ts +0 -241
- package/dist/security/auth.d.ts.map +0 -1
- package/dist/security/auth.js +0 -476
- package/dist/security/authorization.d.ts +0 -235
- package/dist/security/authorization.d.ts.map +0 -1
- package/dist/security/authorization.js +0 -434
- package/dist/security/encryption.d.ts +0 -214
- package/dist/security/encryption.d.ts.map +0 -1
- package/dist/security/encryption.js +0 -517
- package/dist/security/gdpr.d.ts +0 -300
- package/dist/security/gdpr.d.ts.map +0 -1
- package/dist/security/gdpr.js +0 -465
- package/dist/security/headers.d.ts +0 -182
- package/dist/security/headers.d.ts.map +0 -1
- package/dist/security/headers.js +0 -402
- package/dist/utils/jwt-validation.d.ts +0 -14
- package/dist/utils/jwt-validation.d.ts.map +0 -1
- package/dist/utils/jwt-validation.js +0 -36
- package/dist/utils/request-headers.d.ts +0 -15
- package/dist/utils/request-headers.d.ts.map +0 -1
- package/dist/utils/request-headers.js +0 -31
|
@@ -1,193 +1,234 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import { logger } from '@revealui/core/utils/logger';
|
|
4
|
-
import { useEffect, useState } from 'react';
|
|
4
|
+
import { useCallback, useEffect, useReducer, useState } from 'react';
|
|
5
5
|
import { APIError, APIErrorType, apiClient } from '../utils/index.js';
|
|
6
6
|
import { CollectionList } from './CollectionList.js';
|
|
7
7
|
import { DocumentForm } from './DocumentForm.js';
|
|
8
8
|
import { GlobalForm } from './GlobalForm.js';
|
|
9
|
+
const initialState = {
|
|
10
|
+
view: { type: 'dashboard' },
|
|
11
|
+
documents: [],
|
|
12
|
+
totalDocs: 0,
|
|
13
|
+
page: 1,
|
|
14
|
+
totalPages: 1,
|
|
15
|
+
collectionLoading: false,
|
|
16
|
+
globalDocument: null,
|
|
17
|
+
globalLoading: false,
|
|
18
|
+
saving: false,
|
|
19
|
+
deleting: null,
|
|
20
|
+
error: null,
|
|
21
|
+
successMessage: null,
|
|
22
|
+
};
|
|
23
|
+
function reducer(state, action) {
|
|
24
|
+
switch (action.type) {
|
|
25
|
+
case 'NAVIGATE':
|
|
26
|
+
return { ...state, view: action.view, error: null, successMessage: null };
|
|
27
|
+
case 'COLLECTION_LOADING':
|
|
28
|
+
return { ...state, collectionLoading: true };
|
|
29
|
+
case 'COLLECTION_LOADED':
|
|
30
|
+
return {
|
|
31
|
+
...state,
|
|
32
|
+
documents: action.documents,
|
|
33
|
+
totalDocs: action.totalDocs,
|
|
34
|
+
page: action.page,
|
|
35
|
+
totalPages: action.totalPages,
|
|
36
|
+
collectionLoading: false,
|
|
37
|
+
};
|
|
38
|
+
case 'GLOBAL_LOADING':
|
|
39
|
+
return { ...state, globalDocument: null, globalLoading: true };
|
|
40
|
+
case 'GLOBAL_LOADED':
|
|
41
|
+
return { ...state, globalDocument: action.document, globalLoading: false };
|
|
42
|
+
case 'SET_SAVING':
|
|
43
|
+
return { ...state, saving: action.saving };
|
|
44
|
+
case 'SET_DELETING':
|
|
45
|
+
return { ...state, deleting: action.id };
|
|
46
|
+
case 'SET_ERROR':
|
|
47
|
+
return { ...state, error: action.error };
|
|
48
|
+
case 'SET_SUCCESS':
|
|
49
|
+
return { ...state, successMessage: action.message };
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// =============================================================================
|
|
53
|
+
// Shared sub-components
|
|
54
|
+
// =============================================================================
|
|
55
|
+
function AdminHeader({ title, onBack }) {
|
|
56
|
+
return (_jsx("header", { className: "bg-white shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("button", { type: "button", onClick: onBack, className: "text-gray-400 hover:text-gray-600", children: "\u2190 Back to Dashboard" }), _jsx("h1", { className: "text-2xl font-bold text-gray-900 capitalize", children: title })] }), _jsx(SignOutButton, {})] }) }) }));
|
|
57
|
+
}
|
|
58
|
+
function StatusBanners({ error, successMessage, }) {
|
|
59
|
+
return (_jsxs(_Fragment, { children: [error && (_jsxs("div", { className: "mb-4 bg-red-50 border border-red-200 text-red-800 px-4 py-3 rounded", children: [_jsx("p", { className: "font-medium", children: "Error" }), _jsx("p", { className: "text-sm", children: error })] })), successMessage && (_jsxs("div", { className: "mb-4 bg-green-50 border border-green-200 text-green-800 px-4 py-3 rounded", children: [_jsx("p", { className: "font-medium", children: "Success" }), _jsx("p", { className: "text-sm", children: successMessage })] }))] }));
|
|
60
|
+
}
|
|
61
|
+
function LoadingSpinner() {
|
|
62
|
+
return (_jsxs("div", { className: "mb-4 text-center py-8", children: [_jsx("div", { className: "inline-block animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900" }), _jsx("p", { className: "mt-2 text-sm text-gray-600", children: "Loading..." })] }));
|
|
63
|
+
}
|
|
64
|
+
function SignOutButton() {
|
|
65
|
+
const [loading, setLoading] = useState(false);
|
|
66
|
+
const handleSignOut = useCallback(async () => {
|
|
67
|
+
setLoading(true);
|
|
68
|
+
try {
|
|
69
|
+
await fetch('/api/auth/sign-out', {
|
|
70
|
+
method: 'POST',
|
|
71
|
+
credentials: 'include',
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
// Sign out even if the API call fails — clear client state regardless
|
|
76
|
+
}
|
|
77
|
+
window.location.href = '/login';
|
|
78
|
+
}, []);
|
|
79
|
+
return (_jsx("button", { type: "button", onClick: () => void handleSignOut(), disabled: loading, className: "text-sm text-gray-500 hover:text-gray-700 px-3 py-1.5 rounded-md hover:bg-gray-100 transition-colors", children: loading ? 'Signing out...' : 'Sign Out' }));
|
|
80
|
+
}
|
|
81
|
+
// =============================================================================
|
|
82
|
+
// Dashboard home view
|
|
83
|
+
// =============================================================================
|
|
84
|
+
function DashboardHome({ collections, globals, onCollectionClick, onGlobalClick, }) {
|
|
85
|
+
return (_jsxs("div", { className: "min-h-screen bg-gray-50", children: [_jsx("header", { className: "bg-white shadow-sm border-b", children: _jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: _jsxs("div", { className: "flex justify-between items-center py-4", children: [_jsx("div", { className: "flex items-center", children: _jsx("h1", { className: "text-2xl font-bold text-gray-900", children: "RevealUI Admin" }) }), _jsxs("div", { className: "flex items-center space-x-4", children: [_jsx("span", { className: "text-sm text-gray-500", children: "v0.1.0" }), _jsx(SignOutButton, {})] })] }) }) }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsx("div", { className: "px-4 py-6 sm:px-0", children: _jsxs("div", { className: "grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3", children: [_jsxs("div", { className: "bg-white overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-gray-400", "aria-label": "Collections", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", role: "img", children: [_jsx("title", { children: "Collections" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-gray-500 truncate", children: "Collections" }), _jsx("dd", { className: "text-lg font-medium text-gray-900", children: collections.length })] }) })] }) }), _jsx("div", { className: "bg-gray-50 px-5 py-3", children: _jsx("div", { className: "text-sm", children: collections.length > 0 ? (_jsx("ul", { className: "space-y-1 max-h-48 overflow-y-auto", children: collections.map((collection) => (_jsx("li", { className: "text-gray-600 hover:text-gray-900", children: _jsx("button", { type: "button", onClick: () => onCollectionClick(collection), className: "hover:underline cursor-pointer", children: String(collection.slug) }) }, String(collection.slug)))) })) : (_jsx("p", { className: "text-gray-500", children: "No collections configured" })) }) })] }), _jsxs("div", { className: "bg-white overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsxs("svg", { className: "h-8 w-8 text-gray-400", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-labelledby": "globals-icon-title", role: "img", children: [_jsx("title", { id: "globals-icon-title", children: "Globals" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 6V4m0 2a2 2 0 100 4m0-4a2 2 0 110 4m-6 8a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4m6 6v10m6-2a2 2 0 100-4m0 4a2 2 0 100 4m0-4v2m0-6V4" })] }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-gray-500 truncate", children: "Globals" }), _jsx("dd", { className: "text-lg font-medium text-gray-900", children: globals.length })] }) })] }) }), _jsx("div", { className: "bg-gray-50 px-5 py-3", children: _jsx("div", { className: "text-sm", children: globals.length > 0 ? (_jsx("ul", { className: "space-y-1 max-h-32 overflow-y-auto", children: globals.map((global) => (_jsx("li", { className: "text-gray-600 hover:text-gray-900", children: _jsx("button", { type: "button", onClick: () => onGlobalClick(global), className: "hover:underline cursor-pointer", children: global.label || String(global.slug) }) }, String(global.slug)))) })) : (_jsx("p", { className: "text-gray-500", children: "No globals configured" })) }) })] }), _jsxs("div", { className: "bg-white overflow-hidden shadow rounded-lg", children: [_jsx("div", { className: "p-5", children: _jsxs("div", { className: "flex items-center", children: [_jsx("div", { className: "flex-shrink-0", children: _jsx("div", { className: "h-8 w-8 bg-green-100 rounded-full flex items-center justify-center", children: _jsxs("svg", { className: "h-5 w-5 text-green-600", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", "aria-labelledby": "system-status-icon-title", role: "img", children: [_jsx("title", { id: "system-status-icon-title", children: "System Status: Healthy" }), _jsx("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M5 13l4 4L19 7" })] }) }) }), _jsx("div", { className: "ml-5 w-0 flex-1", children: _jsxs("dl", { children: [_jsx("dt", { className: "text-sm font-medium text-gray-500 truncate", children: "System Status" }), _jsx("dd", { className: "text-lg font-medium text-gray-900", children: "Healthy" })] }) })] }) }), _jsx("div", { className: "bg-gray-50 px-5 py-3", children: _jsx("div", { className: "text-sm text-gray-600", children: "RevealUI CMS is running successfully" }) })] })] }) }) })] }));
|
|
86
|
+
}
|
|
87
|
+
// =============================================================================
|
|
88
|
+
// Error handling helpers
|
|
89
|
+
// =============================================================================
|
|
90
|
+
function extractErrorMessage(err, fallback) {
|
|
91
|
+
return err instanceof APIError ? err.message : fallback;
|
|
92
|
+
}
|
|
93
|
+
function logApiError(err, context) {
|
|
94
|
+
logger.error(context, { error: err });
|
|
95
|
+
if (err instanceof APIError && err.type === APIErrorType.Authentication) {
|
|
96
|
+
logger.warn('Authentication required');
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// =============================================================================
|
|
100
|
+
// Main component
|
|
101
|
+
// =============================================================================
|
|
9
102
|
export function AdminDashboard({ config }) {
|
|
10
|
-
const [
|
|
11
|
-
type: 'dashboard',
|
|
12
|
-
});
|
|
13
|
-
const [collectionData, setCollectionData] = useState({
|
|
14
|
-
documents: [],
|
|
15
|
-
totalDocs: 0,
|
|
16
|
-
page: 1,
|
|
17
|
-
totalPages: 1,
|
|
18
|
-
loading: false,
|
|
19
|
-
error: null,
|
|
20
|
-
});
|
|
21
|
-
const [saving, setSaving] = useState(false);
|
|
22
|
-
const [deleting, setDeleting] = useState(null);
|
|
23
|
-
const [error, setError] = useState(null);
|
|
24
|
-
const [successMessage, setSuccessMessage] = useState(null);
|
|
25
|
-
const [globalData, setGlobalData] = useState({
|
|
26
|
-
document: null,
|
|
27
|
-
loading: false,
|
|
28
|
-
error: null,
|
|
29
|
-
});
|
|
103
|
+
const [state, dispatch] = useReducer(reducer, initialState);
|
|
30
104
|
const collections = config.collections || [];
|
|
31
105
|
const globals = config.globals || [];
|
|
32
106
|
// Auto-dismiss success messages
|
|
33
107
|
useEffect(() => {
|
|
34
|
-
if (successMessage) {
|
|
35
|
-
const timer = setTimeout(() =>
|
|
108
|
+
if (state.successMessage) {
|
|
109
|
+
const timer = setTimeout(() => dispatch({ type: 'SET_SUCCESS', message: null }), 3000);
|
|
36
110
|
return () => clearTimeout(timer);
|
|
37
111
|
}
|
|
38
112
|
return;
|
|
39
|
-
}, [successMessage]);
|
|
113
|
+
}, [state.successMessage]);
|
|
40
114
|
// Auto-dismiss error messages
|
|
41
115
|
useEffect(() => {
|
|
42
|
-
if (error) {
|
|
43
|
-
const timer = setTimeout(() =>
|
|
116
|
+
if (state.error) {
|
|
117
|
+
const timer = setTimeout(() => dispatch({ type: 'SET_ERROR', error: null }), 5000);
|
|
44
118
|
return () => clearTimeout(timer);
|
|
45
119
|
}
|
|
46
120
|
return;
|
|
47
|
-
}, [error]);
|
|
48
|
-
const
|
|
49
|
-
|
|
50
|
-
setError(null);
|
|
51
|
-
setSuccessMessage(null);
|
|
121
|
+
}, [state.error]);
|
|
122
|
+
const goToDashboard = () => dispatch({ type: 'NAVIGATE', view: { type: 'dashboard' } });
|
|
123
|
+
const fetchCollection = async (collection, page = 1) => {
|
|
52
124
|
try {
|
|
53
|
-
|
|
54
|
-
setCollectionData((prev) => ({ ...prev, loading: true, error: null }));
|
|
55
|
-
// Fetch first page of documents
|
|
125
|
+
dispatch({ type: 'COLLECTION_LOADING' });
|
|
56
126
|
const response = await apiClient.find({
|
|
57
127
|
collection: String(collection.slug),
|
|
58
|
-
page
|
|
128
|
+
page,
|
|
59
129
|
limit: 10,
|
|
60
130
|
});
|
|
61
|
-
|
|
131
|
+
dispatch({
|
|
132
|
+
type: 'COLLECTION_LOADED',
|
|
62
133
|
documents: response.docs || [],
|
|
63
134
|
totalDocs: response.totalDocs || 0,
|
|
64
135
|
page: response.page || 1,
|
|
65
136
|
totalPages: response.totalPages || 1,
|
|
66
|
-
loading: false,
|
|
67
|
-
error: null,
|
|
68
137
|
});
|
|
69
138
|
}
|
|
70
139
|
catch (err) {
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (err instanceof APIError && err.type === APIErrorType.Authentication) {
|
|
82
|
-
// Redirect to login would be handled by the auth system
|
|
83
|
-
logger.warn('Authentication required');
|
|
84
|
-
}
|
|
140
|
+
const msg = extractErrorMessage(err, 'Failed to fetch collection data. Please try again.');
|
|
141
|
+
logApiError(err, 'Failed to fetch collection data');
|
|
142
|
+
dispatch({
|
|
143
|
+
type: 'COLLECTION_LOADED',
|
|
144
|
+
documents: state.documents,
|
|
145
|
+
totalDocs: state.totalDocs,
|
|
146
|
+
page: state.page,
|
|
147
|
+
totalPages: state.totalPages,
|
|
148
|
+
});
|
|
149
|
+
dispatch({ type: 'SET_ERROR', error: msg });
|
|
85
150
|
}
|
|
86
151
|
};
|
|
152
|
+
const handleCollectionClick = async (collection) => {
|
|
153
|
+
dispatch({ type: 'NAVIGATE', view: { type: 'collection', collection } });
|
|
154
|
+
await fetchCollection(collection);
|
|
155
|
+
};
|
|
87
156
|
const handleGlobalClick = async (global) => {
|
|
88
|
-
|
|
89
|
-
setError(null);
|
|
90
|
-
setSuccessMessage(null);
|
|
157
|
+
dispatch({ type: 'NAVIGATE', view: { type: 'global', global } });
|
|
91
158
|
try {
|
|
92
|
-
|
|
93
|
-
setGlobalData({ document: null, loading: true, error: null });
|
|
94
|
-
// Fetch global data
|
|
159
|
+
dispatch({ type: 'GLOBAL_LOADING' });
|
|
95
160
|
const document = await apiClient.findGlobal({
|
|
96
161
|
slug: String(global.slug),
|
|
97
162
|
depth: 0,
|
|
98
163
|
});
|
|
99
|
-
|
|
100
|
-
document,
|
|
101
|
-
loading: false,
|
|
102
|
-
error: null,
|
|
103
|
-
});
|
|
164
|
+
dispatch({ type: 'GLOBAL_LOADED', document });
|
|
104
165
|
}
|
|
105
166
|
catch (err) {
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
setGlobalData({
|
|
110
|
-
document: null,
|
|
111
|
-
loading: false,
|
|
112
|
-
error: errorMessage,
|
|
113
|
-
});
|
|
114
|
-
setError(errorMessage);
|
|
115
|
-
// Handle authentication errors
|
|
116
|
-
if (err instanceof APIError && err.type === APIErrorType.Authentication) {
|
|
117
|
-
logger.warn('Authentication required');
|
|
118
|
-
}
|
|
167
|
+
const msg = extractErrorMessage(err, 'Failed to fetch global data. Please try again.');
|
|
168
|
+
logApiError(err, 'Failed to fetch global data');
|
|
169
|
+
dispatch({ type: 'SET_ERROR', error: msg });
|
|
119
170
|
}
|
|
120
171
|
};
|
|
121
172
|
const handleCreate = () => {
|
|
122
|
-
if (
|
|
123
|
-
|
|
173
|
+
if (state.view.collection) {
|
|
174
|
+
dispatch({
|
|
175
|
+
type: 'NAVIGATE',
|
|
176
|
+
view: { type: 'edit', collection: state.view.collection },
|
|
177
|
+
});
|
|
124
178
|
}
|
|
125
179
|
};
|
|
126
180
|
const handleEdit = (document) => {
|
|
127
|
-
if (
|
|
128
|
-
|
|
129
|
-
type: '
|
|
130
|
-
collection:
|
|
131
|
-
document,
|
|
181
|
+
if (state.view.collection) {
|
|
182
|
+
dispatch({
|
|
183
|
+
type: 'NAVIGATE',
|
|
184
|
+
view: { type: 'edit', collection: state.view.collection, document },
|
|
132
185
|
});
|
|
133
186
|
}
|
|
134
187
|
};
|
|
135
188
|
const handleDelete = async (document) => {
|
|
136
|
-
if (!(
|
|
189
|
+
if (!(state.view.collection && document.id))
|
|
137
190
|
return;
|
|
138
|
-
|
|
139
|
-
const confirmed = window.confirm(`Are you sure you want to delete this ${String(currentView.collection.slug)}? This action cannot be undone.`);
|
|
191
|
+
const confirmed = window.confirm(`Are you sure you want to delete this ${String(state.view.collection.slug)}? This action cannot be undone.`);
|
|
140
192
|
if (!confirmed)
|
|
141
193
|
return;
|
|
142
194
|
try {
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
setSuccessMessage(null);
|
|
195
|
+
dispatch({ type: 'SET_DELETING', id: String(document.id) });
|
|
196
|
+
dispatch({ type: 'SET_ERROR', error: null });
|
|
146
197
|
await apiClient.delete({
|
|
147
|
-
collection: String(
|
|
198
|
+
collection: String(state.view.collection.slug),
|
|
148
199
|
id: String(document.id),
|
|
149
200
|
});
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
await handleCollectionClick(currentView.collection);
|
|
201
|
+
if (state.view.collection) {
|
|
202
|
+
await fetchCollection(state.view.collection);
|
|
153
203
|
}
|
|
154
|
-
|
|
155
|
-
setSuccessMessage('Document deleted successfully');
|
|
204
|
+
dispatch({ type: 'SET_SUCCESS', message: 'Document deleted successfully' });
|
|
156
205
|
}
|
|
157
206
|
catch (err) {
|
|
158
|
-
const
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
// Handle authentication errors
|
|
162
|
-
if (err instanceof APIError && err.type === APIErrorType.Authentication) {
|
|
163
|
-
logger.warn('Authentication required');
|
|
164
|
-
}
|
|
207
|
+
const msg = extractErrorMessage(err, 'Failed to delete document. Please try again.');
|
|
208
|
+
logApiError(err, 'Failed to delete document');
|
|
209
|
+
dispatch({ type: 'SET_ERROR', error: msg });
|
|
165
210
|
}
|
|
166
211
|
finally {
|
|
167
|
-
|
|
212
|
+
dispatch({ type: 'SET_DELETING', id: null });
|
|
168
213
|
}
|
|
169
214
|
};
|
|
170
215
|
const handleSave = async (data) => {
|
|
171
|
-
if (!
|
|
216
|
+
if (!state.view.collection)
|
|
172
217
|
return;
|
|
173
218
|
try {
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
if (currentView.document?.id) {
|
|
178
|
-
// Update existing document
|
|
219
|
+
dispatch({ type: 'SET_SAVING', saving: true });
|
|
220
|
+
dispatch({ type: 'SET_ERROR', error: null });
|
|
221
|
+
if (state.view.document?.id) {
|
|
179
222
|
await apiClient.update({
|
|
180
|
-
collection: String(
|
|
181
|
-
id: String(
|
|
223
|
+
collection: String(state.view.collection.slug),
|
|
224
|
+
id: String(state.view.document.id),
|
|
182
225
|
data,
|
|
183
226
|
});
|
|
184
|
-
|
|
227
|
+
dispatch({ type: 'SET_SUCCESS', message: 'Document updated successfully' });
|
|
185
228
|
}
|
|
186
229
|
else {
|
|
187
|
-
// Auto-generate slug from title if
|
|
188
|
-
|
|
189
|
-
// so we replicate the slug-generation logic here as a reliable client-side fallback.
|
|
190
|
-
const hasSlugField = currentView.collection.fields.some((f) => 'name' in f && f.name === 'slug');
|
|
230
|
+
// Auto-generate slug from title if needed
|
|
231
|
+
const hasSlugField = state.view.collection.fields.some((f) => 'name' in f && f.name === 'slug');
|
|
191
232
|
const submitData = hasSlugField && !data.slug && typeof data.title === 'string'
|
|
192
233
|
? {
|
|
193
234
|
...data,
|
|
@@ -197,122 +238,71 @@ export function AdminDashboard({ config }) {
|
|
|
197
238
|
.toLowerCase(),
|
|
198
239
|
}
|
|
199
240
|
: data;
|
|
200
|
-
// Create new document
|
|
201
241
|
await apiClient.create({
|
|
202
|
-
collection: String(
|
|
242
|
+
collection: String(state.view.collection.slug),
|
|
203
243
|
data: submitData,
|
|
204
244
|
});
|
|
205
|
-
|
|
206
|
-
}
|
|
207
|
-
// Refresh collection list
|
|
208
|
-
if (currentView.collection) {
|
|
209
|
-
await handleCollectionClick(currentView.collection);
|
|
245
|
+
dispatch({ type: 'SET_SUCCESS', message: 'Document created successfully' });
|
|
210
246
|
}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
type: '
|
|
214
|
-
collection:
|
|
247
|
+
await fetchCollection(state.view.collection);
|
|
248
|
+
dispatch({
|
|
249
|
+
type: 'NAVIGATE',
|
|
250
|
+
view: { type: 'collection', collection: state.view.collection },
|
|
215
251
|
});
|
|
216
252
|
}
|
|
217
253
|
catch (err) {
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
// Handle validation errors
|
|
254
|
+
const msg = extractErrorMessage(err, 'Failed to save document. Please try again.');
|
|
255
|
+
logApiError(err, 'Failed to save document');
|
|
256
|
+
dispatch({ type: 'SET_ERROR', error: msg });
|
|
222
257
|
if (err instanceof APIError && err.type === APIErrorType.Validation) {
|
|
223
|
-
|
|
224
|
-
logger.warn('Validation error', {
|
|
225
|
-
field: err.field,
|
|
226
|
-
message: err.message,
|
|
227
|
-
});
|
|
228
|
-
}
|
|
229
|
-
// Handle authentication errors
|
|
230
|
-
if (err instanceof APIError && err.type === APIErrorType.Authentication) {
|
|
231
|
-
logger.warn('Authentication required');
|
|
258
|
+
logger.warn('Validation error', { field: err.field, message: err.message });
|
|
232
259
|
}
|
|
233
260
|
}
|
|
234
261
|
finally {
|
|
235
|
-
|
|
262
|
+
dispatch({ type: 'SET_SAVING', saving: false });
|
|
236
263
|
}
|
|
237
264
|
};
|
|
238
265
|
const handleSaveGlobal = async (data) => {
|
|
239
|
-
if (!
|
|
266
|
+
if (!state.view.global)
|
|
240
267
|
return;
|
|
241
268
|
try {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
setSuccessMessage(null);
|
|
245
|
-
// Update global
|
|
269
|
+
dispatch({ type: 'SET_SAVING', saving: true });
|
|
270
|
+
dispatch({ type: 'SET_ERROR', error: null });
|
|
246
271
|
await apiClient.updateGlobal({
|
|
247
|
-
slug: String(
|
|
272
|
+
slug: String(state.view.global.slug),
|
|
248
273
|
data,
|
|
249
274
|
});
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
setCurrentView({ type: 'dashboard' });
|
|
275
|
+
dispatch({ type: 'SET_SUCCESS', message: 'Global updated successfully' });
|
|
276
|
+
goToDashboard();
|
|
253
277
|
}
|
|
254
278
|
catch (err) {
|
|
255
|
-
const
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
// Handle validation errors
|
|
279
|
+
const msg = extractErrorMessage(err, 'Failed to save global. Please try again.');
|
|
280
|
+
logApiError(err, 'Failed to save global');
|
|
281
|
+
dispatch({ type: 'SET_ERROR', error: msg });
|
|
259
282
|
if (err instanceof APIError && err.type === APIErrorType.Validation) {
|
|
260
|
-
logger.warn('Validation error', {
|
|
261
|
-
field: err.field,
|
|
262
|
-
message: err.message,
|
|
263
|
-
});
|
|
264
|
-
}
|
|
265
|
-
// Handle authentication errors
|
|
266
|
-
if (err instanceof APIError && err.type === APIErrorType.Authentication) {
|
|
267
|
-
logger.warn('Authentication required');
|
|
283
|
+
logger.warn('Validation error', { field: err.field, message: err.message });
|
|
268
284
|
}
|
|
269
285
|
}
|
|
270
286
|
finally {
|
|
271
|
-
|
|
272
|
-
}
|
|
273
|
-
};
|
|
274
|
-
const handleCancel = () => {
|
|
275
|
-
setCurrentView({ type: 'dashboard' });
|
|
276
|
-
};
|
|
277
|
-
const handlePageChange = async (page) => {
|
|
278
|
-
if (!currentView.collection)
|
|
279
|
-
return;
|
|
280
|
-
try {
|
|
281
|
-
setCollectionData((prev) => ({ ...prev, loading: true, error: null }));
|
|
282
|
-
const response = await apiClient.find({
|
|
283
|
-
collection: String(currentView.collection.slug),
|
|
284
|
-
page,
|
|
285
|
-
limit: 10,
|
|
286
|
-
});
|
|
287
|
-
setCollectionData({
|
|
288
|
-
documents: response.docs || [],
|
|
289
|
-
totalDocs: response.totalDocs || 0,
|
|
290
|
-
page: response.page || 1,
|
|
291
|
-
totalPages: response.totalPages || 1,
|
|
292
|
-
loading: false,
|
|
293
|
-
error: null,
|
|
294
|
-
});
|
|
295
|
-
}
|
|
296
|
-
catch (err) {
|
|
297
|
-
const errorMessage = err instanceof APIError ? err.message : 'Failed to fetch page. Please try again.';
|
|
298
|
-
logger.error('Failed to fetch page', { error: err });
|
|
299
|
-
setCollectionData((prev) => ({
|
|
300
|
-
...prev,
|
|
301
|
-
loading: false,
|
|
302
|
-
error: errorMessage,
|
|
303
|
-
}));
|
|
304
|
-
setError(errorMessage);
|
|
287
|
+
dispatch({ type: 'SET_SAVING', saving: false });
|
|
305
288
|
}
|
|
306
289
|
};
|
|
307
|
-
|
|
308
|
-
|
|
290
|
+
// ── Collection list view ──────────────────────────────────────────────
|
|
291
|
+
if (state.view.type === 'collection' && state.view.collection) {
|
|
292
|
+
return (_jsxs("div", { className: "min-h-screen bg-gray-50", children: [_jsx(AdminHeader, { title: String(state.view.collection.slug), onBack: goToDashboard }), _jsxs("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: [_jsx(StatusBanners, { error: state.error, successMessage: state.successMessage }), state.collectionLoading && _jsx(LoadingSpinner, {}), _jsx(CollectionList, { collection: state.view.collection, documents: state.documents, totalDocs: state.totalDocs, page: state.page, totalPages: state.totalPages, onCreate: handleCreate, onEdit: handleEdit, onDelete: (document) => void handleDelete(document), onPageChange: (nextPage) => {
|
|
293
|
+
const collection = state.view.collection;
|
|
294
|
+
if (collection)
|
|
295
|
+
void fetchCollection(collection, nextPage);
|
|
296
|
+
}, deleting: state.deleting })] })] }));
|
|
309
297
|
}
|
|
310
|
-
|
|
311
|
-
|
|
298
|
+
// ── Document edit/create view ─────────────────────────────────────────
|
|
299
|
+
if (state.view.type === 'edit' && state.view.collection) {
|
|
300
|
+
return (_jsxs("div", { className: "min-h-screen bg-gray-50", children: [_jsx(AdminHeader, { title: `${state.view.document ? 'Edit' : 'Create'} ${String(state.view.collection.slug).slice(0, -1)}`, onBack: goToDashboard }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsxs("div", { className: "max-w-3xl", children: [_jsx(StatusBanners, { error: state.error, successMessage: state.successMessage }), _jsx(DocumentForm, { collection: state.view.collection, document: state.view.document, onSave: (data) => void handleSave(data), onCancel: goToDashboard, isLoading: state.saving })] }) })] }));
|
|
312
301
|
}
|
|
313
|
-
|
|
314
|
-
|
|
302
|
+
// ── Global edit view ──────────────────────────────────────────────────
|
|
303
|
+
if (state.view.type === 'global' && state.view.global) {
|
|
304
|
+
return (_jsxs("div", { className: "min-h-screen bg-gray-50", children: [_jsx(AdminHeader, { title: state.view.global.label || String(state.view.global.slug), onBack: goToDashboard }), _jsx("main", { className: "max-w-7xl mx-auto py-6 sm:px-6 lg:px-8", children: _jsxs("div", { className: "max-w-3xl", children: [_jsx(StatusBanners, { error: state.error, successMessage: state.successMessage }), state.globalLoading && _jsx(LoadingSpinner, {}), !state.globalLoading && state.globalDocument && (_jsx(GlobalForm, { global: state.view.global, document: state.globalDocument, onSave: (data) => void handleSaveGlobal(data), onCancel: goToDashboard, isLoading: state.saving }))] }) })] }));
|
|
315
305
|
}
|
|
316
|
-
// Dashboard
|
|
317
|
-
return (
|
|
306
|
+
// ── Dashboard home ────────────────────────────────────────────────────
|
|
307
|
+
return (_jsx(DashboardHome, { collections: collections, globals: globals, onCollectionClick: (c) => void handleCollectionClick(c), onGlobalClick: (g) => void handleGlobalClick(g) }));
|
|
318
308
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CollectionList.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/CollectionList.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"CollectionList.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/CollectionList.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAoCjC,UAAU,mBAAmB;IAC3B,UAAU,EAAE,sBAAsB,CAAC;IACnC,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,MAAM,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IACtC,QAAQ,EAAE,CAAC,GAAG,EAAE,cAAc,KAAK,IAAI,CAAC;IACxC,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAgB,cAAc,CAAC,EAC7B,UAAU,EACV,SAAS,EACT,SAAS,EACT,IAAI,EACJ,UAAU,EACV,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,YAAY,EACZ,QAAQ,GACT,EAAE,mBAAmB,2CAqKrB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DocumentForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/DocumentForm.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"DocumentForm.d.ts","sourceRoot":"","sources":["../../../../src/client/admin/components/DocumentForm.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,sBAAsB,EACtB,cAAc,EAEf,MAAM,yBAAyB,CAAC;AAiEjC,UAAU,iBAAiB;IACzB,UAAU,EAAE,sBAAsB,CAAC;IACnC,QAAQ,CAAC,EAAE,cAAc,CAAC;IAC1B,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;IAChD,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,wBAAgB,YAAY,CAAC,EAC3B,UAAU,EACV,QAAQ,EACR,MAAM,EACN,QAAQ,EACR,SAAiB,GAClB,EAAE,iBAAiB,2CA0DnB"}
|