@nextsparkjs/core 0.1.0-beta.188 → 0.1.0-beta.189
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/components/api/keys/ApiKeyDisplay.js +19 -19
- package/dist/components/api/keys/CreateApiKeyDialog.js +21 -21
- package/dist/components/app/layouts/PublicNavbar.d.ts.map +1 -1
- package/dist/components/app/layouts/PublicNavbar.js +34 -16
- package/dist/components/app/misc/ThemeToggle.d.ts.map +1 -1
- package/dist/components/app/misc/ThemeToggle.js +3 -4
- package/dist/components/auth/SessionCookieRefresher.d.ts +5 -0
- package/dist/components/auth/SessionCookieRefresher.d.ts.map +1 -1
- package/dist/components/auth/SessionCookieRefresher.js +7 -1
- package/dist/components/auth/forms/LoginForm.d.ts.map +1 -1
- package/dist/components/auth/forms/LoginForm.js +49 -12
- package/dist/components/auth/forms/SignupForm.d.ts.map +1 -1
- package/dist/components/auth/forms/SignupForm.js +4 -3
- package/dist/components/dashboard/block-editor/block-settings-panel.js +1 -1
- package/dist/components/dashboard/block-editor/floating-block-toolbar.js +1 -1
- package/dist/components/dashboard/block-editor/sortable-block.js +1 -1
- package/dist/components/dashboard/layouts/Sidebar.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/Sidebar.js +8 -6
- package/dist/components/dashboard/layouts/TopNavbar.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/TopNavbar.js +51 -54
- package/dist/components/dashboard/misc/NotificationsDropdown.d.ts.map +1 -1
- package/dist/components/dashboard/misc/NotificationsDropdown.js +17 -15
- package/dist/components/dashboard/misc/SearchDropdown.d.ts.map +1 -1
- package/dist/components/dashboard/misc/SearchDropdown.js +19 -22
- package/dist/components/dashboard/mobile/MobileBottomNav.js +1 -1
- package/dist/components/dashboard/mobile/MobileTopBar.js +2 -2
- package/dist/components/dashboard/navigation/DynamicNavigation.js +5 -5
- package/dist/components/devtools/BlockDetailViewer.js +1 -1
- package/dist/components/devtools/BlocksViewer.js +1 -1
- package/dist/components/entities/EntityChildManager.js +5 -5
- package/dist/components/entities/EntityDetailPage.d.ts.map +1 -1
- package/dist/components/entities/EntityDetailPage.js +16 -15
- package/dist/components/entities/EntityFieldRenderer.d.ts.map +1 -1
- package/dist/components/entities/EntityFieldRenderer.js +12 -7
- package/dist/components/entities/EntityPageHeader.js +5 -5
- package/dist/components/entities/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/entities/ErrorBoundary.js +20 -21
- package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -5
- package/dist/components/entities/wrappers/EntityFormWrapper.js +2 -2
- package/dist/components/entities/wrappers/EntityListWrapper.js +3 -3
- package/dist/components/permissions/NoPermission.js +10 -10
- package/dist/components/public/pageBuilder/PageRenderer.d.ts.map +1 -1
- package/dist/components/public/pageBuilder/PageRenderer.js +2 -1
- package/dist/components/settings/SettingsPageSkeleton.js +4 -4
- package/dist/components/settings/layouts/SettingsSidebar.js +6 -6
- package/dist/components/shared/MultiSelectFilter.d.ts +3 -1
- package/dist/components/shared/MultiSelectFilter.d.ts.map +1 -1
- package/dist/components/shared/MultiSelectFilter.js +7 -3
- package/dist/components/shared/SearchInput.d.ts +2 -0
- package/dist/components/shared/SearchInput.d.ts.map +1 -1
- package/dist/components/shared/SearchInput.js +64 -6
- package/dist/components/ui/address-input.js +18 -18
- package/dist/components/ui/audio-upload.js +9 -9
- package/dist/components/ui/combobox.d.ts.map +1 -1
- package/dist/components/ui/combobox.js +4 -4
- package/dist/components/ui/country-select.d.ts.map +1 -1
- package/dist/components/ui/country-select.js +3 -3
- package/dist/components/ui/currency-select.d.ts.map +1 -1
- package/dist/components/ui/currency-select.js +3 -3
- package/dist/components/ui/dynamic-icon.d.ts.map +1 -1
- package/dist/components/ui/dynamic-icon.js +3 -2
- package/dist/components/ui/file-upload.js +7 -7
- package/dist/components/ui/image-upload.js +8 -8
- package/dist/components/ui/multi-select.d.ts +2 -1
- package/dist/components/ui/multi-select.d.ts.map +1 -1
- package/dist/components/ui/multi-select.js +4 -3
- package/dist/components/ui/phone-input.d.ts.map +1 -1
- package/dist/components/ui/phone-input.js +3 -3
- package/dist/components/ui/relation-display.js +1 -1
- package/dist/components/ui/simple-relation-select.d.ts +2 -1
- package/dist/components/ui/simple-relation-select.d.ts.map +1 -1
- package/dist/components/ui/simple-relation-select.js +7 -6
- package/dist/components/ui/tags-input.d.ts.map +1 -1
- package/dist/components/ui/tags-input.js +1 -1
- package/dist/components/ui/timezone-select.d.ts.map +1 -1
- package/dist/components/ui/timezone-select.js +3 -3
- package/dist/components/ui/user-display.js +4 -4
- package/dist/components/ui/user-select.d.ts.map +1 -1
- package/dist/components/ui/user-select.js +9 -9
- package/dist/components/ui/video-upload.js +9 -9
- package/dist/contexts/SubscriptionContext.d.ts.map +1 -1
- package/dist/contexts/SubscriptionContext.js +5 -1
- package/dist/contexts/TeamContext.d.ts.map +1 -1
- package/dist/contexts/TeamContext.js +83 -26
- package/dist/emails/otp-verification.d.ts.map +1 -1
- package/dist/emails/otp-verification.js +3 -2
- package/dist/hooks/useAccountPreferencesSync.d.ts +13 -0
- package/dist/hooks/useAccountPreferencesSync.d.ts.map +1 -0
- package/dist/hooks/useAccountPreferencesSync.js +95 -0
- package/dist/hooks/useAuth.d.ts +202 -15
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +49 -13
- package/dist/hooks/useEntityConfig.js +2 -2
- package/dist/hooks/useEntitySearch.js +10 -10
- package/dist/hooks/useNotifications.js +12 -12
- package/dist/hooks/usePrefetch.d.ts.map +1 -1
- package/dist/hooks/usePrefetch.js +6 -2
- package/dist/hooks/useSearch.js +15 -15
- package/dist/hooks/useSessionCookieRefresh.d.ts +18 -1
- package/dist/hooks/useSessionCookieRefresh.d.ts.map +1 -1
- package/dist/hooks/useSessionCookieRefresh.js +17 -4
- package/dist/hooks/useSessionHint.d.ts +12 -0
- package/dist/hooks/useSessionHint.d.ts.map +1 -0
- package/dist/hooks/useSessionHint.js +15 -0
- package/dist/hooks/useTranslationPreload.js +6 -6
- package/dist/i18n.d.ts +13 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +2 -27
- package/dist/lib/actions/entity.actions.d.ts.map +1 -1
- package/dist/lib/actions/entity.actions.js +3 -2
- package/dist/lib/api/auth/dual-auth.d.ts +4 -1
- package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
- package/dist/lib/api/auth/dual-auth.js +5 -16
- package/dist/lib/api/entities.js +33 -33
- package/dist/lib/api/keys.d.ts +27 -27
- package/dist/lib/api/keys.js +27 -27
- package/dist/lib/auth/callback-url.d.ts +11 -0
- package/dist/lib/auth/callback-url.d.ts.map +1 -0
- package/dist/lib/auth/callback-url.js +14 -0
- package/dist/lib/auth/otp-config.d.ts +55 -0
- package/dist/lib/auth/otp-config.d.ts.map +1 -0
- package/dist/lib/auth/otp-config.js +48 -0
- package/dist/lib/auth/registration-helpers.d.ts.map +1 -1
- package/dist/lib/auth/registration-helpers.js +3 -1
- package/dist/lib/auth/session-hint.d.ts +31 -0
- package/dist/lib/auth/session-hint.d.ts.map +1 -0
- package/dist/lib/auth/session-hint.js +37 -0
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +6 -4
- package/dist/lib/blocks/loader.d.ts +3 -11
- package/dist/lib/blocks/loader.d.ts.map +1 -1
- package/dist/lib/blocks/loader.js +1 -9
- package/dist/lib/blocks/loader.server.d.ts +18 -0
- package/dist/lib/blocks/loader.server.d.ts.map +1 -0
- package/dist/lib/blocks/loader.server.js +11 -0
- package/dist/lib/blocks/sanitize-html.d.ts +31 -0
- package/dist/lib/blocks/sanitize-html.d.ts.map +1 -0
- package/dist/lib/blocks/sanitize-html.js +60 -0
- package/dist/lib/config/config-sync.d.ts +1 -0
- package/dist/lib/config/config-sync.d.ts.map +1 -1
- package/dist/lib/config/config-sync.js +4 -1
- package/dist/lib/config/types.d.ts +48 -0
- package/dist/lib/config/types.d.ts.map +1 -1
- package/dist/lib/email/types.d.ts +6 -0
- package/dist/lib/email/types.d.ts.map +1 -1
- package/dist/lib/entities/serialization.d.ts.map +1 -1
- package/dist/lib/entities/serialization.js +3 -6
- package/dist/lib/icons.d.ts +12 -0
- package/dist/lib/icons.d.ts.map +1 -0
- package/dist/lib/icons.js +30 -0
- package/dist/lib/locale.d.ts +25 -1
- package/dist/lib/locale.d.ts.map +1 -1
- package/dist/lib/locale.js +49 -35
- package/dist/lib/mcp/engine.js +1 -1
- package/dist/lib/mcp/errors.js +17 -17
- package/dist/lib/mcp/schema-builder.js +16 -16
- package/dist/lib/mcp/tool-generator.js +18 -18
- package/dist/lib/search-highlighting.d.ts +7 -0
- package/dist/lib/search-highlighting.d.ts.map +1 -1
- package/dist/lib/search-highlighting.js +6 -2
- package/dist/lib/selectors/core-selectors.d.ts +2 -0
- package/dist/lib/selectors/core-selectors.d.ts.map +1 -1
- package/dist/lib/selectors/domains/auth.selectors.d.ts +1 -0
- package/dist/lib/selectors/domains/auth.selectors.d.ts.map +1 -1
- package/dist/lib/selectors/domains/auth.selectors.js +1 -0
- package/dist/lib/selectors/domains/entities.selectors.d.ts +2 -0
- package/dist/lib/selectors/domains/entities.selectors.d.ts.map +1 -1
- package/dist/lib/selectors/domains/entities.selectors.js +2 -0
- package/dist/lib/selectors/selectors.d.ts +4 -0
- package/dist/lib/selectors/selectors.d.ts.map +1 -1
- package/dist/lib/services/block.service.js +1 -1
- package/dist/lib/teams/active-team-cookie.d.ts +24 -0
- package/dist/lib/teams/active-team-cookie.d.ts.map +1 -0
- package/dist/lib/teams/active-team-cookie.js +17 -0
- package/dist/lib/teams/dashboard-team.d.ts +20 -0
- package/dist/lib/teams/dashboard-team.d.ts.map +1 -0
- package/dist/lib/teams/dashboard-team.js +38 -0
- package/dist/lib/teams/schema.d.ts.map +1 -1
- package/dist/lib/teams/schema.js +1 -1
- package/dist/lib/template-resolver.d.ts.map +1 -1
- package/dist/lib/template-resolver.js +0 -1
- package/dist/lib/theme/get-default-theme-mode.d.ts +7 -4
- package/dist/lib/theme/get-default-theme-mode.d.ts.map +1 -1
- package/dist/lib/theme/get-default-theme-mode.js +2 -44
- package/dist/messages/de/auth.json +4 -2
- package/dist/messages/de/common.json +83 -3
- package/dist/messages/de/email.json +1 -1
- package/dist/messages/de/index.d.ts +87 -0
- package/dist/messages/de/index.d.ts.map +1 -1
- package/dist/messages/de/settings.json +5 -0
- package/dist/messages/en/auth.json +4 -2
- package/dist/messages/en/common.json +83 -3
- package/dist/messages/en/email.json +1 -1
- package/dist/messages/en/index.d.ts +86 -0
- package/dist/messages/en/index.d.ts.map +1 -1
- package/dist/messages/en/settings.json +4 -0
- package/dist/messages/es/auth.json +4 -2
- package/dist/messages/es/common.json +83 -3
- package/dist/messages/es/email.json +1 -1
- package/dist/messages/es/index.d.ts +86 -0
- package/dist/messages/es/index.d.ts.map +1 -1
- package/dist/messages/es/settings.json +4 -0
- package/dist/messages/fr/auth.json +4 -2
- package/dist/messages/fr/common.json +83 -3
- package/dist/messages/fr/email.json +1 -1
- package/dist/messages/fr/index.d.ts +87 -0
- package/dist/messages/fr/index.d.ts.map +1 -1
- package/dist/messages/fr/settings.json +5 -0
- package/dist/messages/it/auth.json +4 -2
- package/dist/messages/it/common.json +83 -3
- package/dist/messages/it/email.json +1 -1
- package/dist/messages/it/index.d.ts +87 -0
- package/dist/messages/it/index.d.ts.map +1 -1
- package/dist/messages/it/settings.json +5 -0
- package/dist/messages/pt/auth.json +4 -2
- package/dist/messages/pt/common.json +83 -3
- package/dist/messages/pt/email.json +1 -1
- package/dist/messages/pt/index.d.ts +87 -0
- package/dist/messages/pt/index.d.ts.map +1 -1
- package/dist/messages/pt/settings.json +5 -0
- package/dist/nextspark-registries.d.ts +54 -0
- package/dist/providers/DashboardProviders.d.ts +13 -10
- package/dist/providers/DashboardProviders.d.ts.map +1 -1
- package/dist/providers/DashboardProviders.js +7 -1
- package/dist/templates/app/(auth)/forgot-password/page.tsx +2 -2
- package/dist/templates/app/(auth)/reset-password/page.tsx +6 -6
- package/dist/templates/app/403/page.tsx +6 -6
- package/dist/templates/app/api/v1/teams/switch/route.ts +24 -5
- package/dist/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
- package/dist/templates/app/dashboard/(main)/layout.tsx +4 -3
- package/dist/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
- package/dist/templates/app/dashboard/settings/profile/page.tsx +7 -6
- package/dist/templates/app/dashboard/settings/security/page.tsx +5 -4
- package/dist/templates/app/layout.ppr.tsx +8 -8
- package/dist/templates/app/layout.tsx +12 -17
- package/dist/templates/blocks/cta-section/component.tsx +5 -2
- package/dist/templates/blocks/cta-section/config.ts +3 -2
- package/dist/templates/blocks/cta-section/fields.ts +2 -2
- package/dist/templates/blocks/cta-section/schema.ts +2 -2
- package/dist/templates/blocks/features-grid/component.tsx +10 -2
- package/dist/templates/blocks/features-grid/config.ts +3 -2
- package/dist/templates/blocks/features-grid/fields.ts +2 -2
- package/dist/templates/blocks/features-grid/schema.ts +2 -2
- package/dist/templates/blocks/hero/component.tsx +6 -3
- package/dist/templates/blocks/hero/config.ts +3 -2
- package/dist/templates/blocks/hero/fields.ts +2 -2
- package/dist/templates/blocks/hero/schema.ts +2 -2
- package/dist/templates/blocks/testimonials/component.tsx +6 -3
- package/dist/templates/blocks/testimonials/config.ts +3 -2
- package/dist/templates/blocks/testimonials/fields.ts +2 -2
- package/dist/templates/blocks/testimonials/schema.ts +2 -2
- package/dist/templates/blocks/text-content/component.tsx +7 -3
- package/dist/templates/blocks/text-content/config.ts +3 -2
- package/dist/templates/blocks/text-content/fields.ts +2 -2
- package/dist/templates/blocks/text-content/schema.ts +2 -2
- package/dist/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
- package/dist/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
- package/dist/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
- package/dist/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/config/app.config.ts +8 -0
- package/dist/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
- package/dist/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
- package/dist/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
- package/dist/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
- package/dist/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
- package/dist/templates/features/blog/blocks/post-content/component.tsx +5 -1
- package/dist/templates/features/blog/blocks/post-content/schema.ts +1 -1
- package/dist/templates/features/pages/blocks/hero/component.tsx +3 -0
- package/dist/templates/features/pages/blocks/hero/schema.ts +1 -1
- package/dist/templates/proxy.ts +138 -53
- package/dist/types/blocks.d.ts.map +1 -1
- package/dist/types/blocks.js +1 -1
- package/dist/types/task.types.d.ts +1 -1
- package/dist/types/task.types.js +7 -7
- package/dist/utils/dev/TranslationDebugger.js +2 -2
- package/package.json +14 -5
- package/scripts/build/registry/__tests__/block-registry.test.mjs +73 -0
- package/scripts/build/registry/__tests__/icons-discovery.test.mjs +130 -0
- package/scripts/build/registry/__tests__/identifier.test.mjs +65 -0
- package/scripts/build/registry/__tests__/page-generator.test.mjs +430 -0
- package/scripts/build/registry/__tests__/scheduled-actions-registry.test.mjs +41 -0
- package/scripts/build/registry/__tests__/template-registry.test.mjs +89 -0
- package/scripts/build/registry/discovery/icons.mjs +275 -0
- package/scripts/build/registry/discovery/index.mjs +1 -0
- package/scripts/build/registry/generators/block-registry.mjs +203 -55
- package/scripts/build/registry/generators/feature-registry.mjs +9 -2
- package/scripts/build/registry/generators/icon-registry.mjs +56 -0
- package/scripts/build/registry/generators/identifier.mjs +28 -0
- package/scripts/build/registry/generators/index.mjs +1 -0
- package/scripts/build/registry/generators/plugin-registry.mjs +4 -3
- package/scripts/build/registry/generators/scheduled-actions-registry.mjs +4 -2
- package/scripts/build/registry/generators/template-registry.mjs +49 -41
- package/scripts/build/registry/generators/theme-registry.mjs +6 -7
- package/scripts/build/registry/post-build/page-generator.mjs +380 -59
- package/scripts/build/registry.mjs +9 -1
- package/templates/app/(auth)/forgot-password/page.tsx +2 -2
- package/templates/app/(auth)/reset-password/page.tsx +6 -6
- package/templates/app/403/page.tsx +6 -6
- package/templates/app/api/v1/teams/switch/route.ts +24 -5
- package/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
- package/templates/app/dashboard/(main)/layout.tsx +4 -3
- package/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
- package/templates/app/dashboard/settings/profile/page.tsx +7 -6
- package/templates/app/dashboard/settings/security/page.tsx +5 -4
- package/templates/app/layout.ppr.tsx +8 -8
- package/templates/app/layout.tsx +12 -17
- package/templates/blocks/cta-section/component.tsx +5 -2
- package/templates/blocks/cta-section/config.ts +3 -2
- package/templates/blocks/cta-section/fields.ts +2 -2
- package/templates/blocks/cta-section/schema.ts +2 -2
- package/templates/blocks/features-grid/component.tsx +10 -2
- package/templates/blocks/features-grid/config.ts +3 -2
- package/templates/blocks/features-grid/fields.ts +2 -2
- package/templates/blocks/features-grid/schema.ts +2 -2
- package/templates/blocks/hero/component.tsx +6 -3
- package/templates/blocks/hero/config.ts +3 -2
- package/templates/blocks/hero/fields.ts +2 -2
- package/templates/blocks/hero/schema.ts +2 -2
- package/templates/blocks/testimonials/component.tsx +6 -3
- package/templates/blocks/testimonials/config.ts +3 -2
- package/templates/blocks/testimonials/fields.ts +2 -2
- package/templates/blocks/testimonials/schema.ts +2 -2
- package/templates/blocks/text-content/component.tsx +7 -3
- package/templates/blocks/text-content/config.ts +3 -2
- package/templates/blocks/text-content/fields.ts +2 -2
- package/templates/blocks/text-content/schema.ts +2 -2
- package/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
- package/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
- package/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
- package/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
- package/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
- package/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
- package/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
- package/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
- package/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
- package/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
- package/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
- package/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
- package/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
- package/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
- package/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
- package/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
- package/templates/contents/themes/starter/config/app.config.ts +8 -0
- package/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
- package/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
- package/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
- package/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
- package/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
- package/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
- package/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
- package/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
- package/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
- package/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
- package/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
- package/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
- package/templates/features/blog/blocks/post-content/component.tsx +5 -1
- package/templates/features/blog/blocks/post-content/schema.ts +1 -1
- package/templates/features/pages/blocks/hero/component.tsx +3 -0
- package/templates/features/pages/blocks/hero/schema.ts +1 -1
- package/templates/proxy.ts +138 -53
- package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.client.ts +9 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.lazy.ts +5 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/icon-registry.ts +42 -0
- package/tests/jest/__mocks__/next-intl-server.js +85 -5
- package/tests/jest/__mocks__/next-server.js +32 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Button } from '@nextsparkjs/core/components/ui/button'
|
|
3
|
+
import { cn } from '@nextsparkjs/core/lib/utils'
|
|
4
|
+
import { buildSectionClasses, resolveMediaUrl } from '@nextsparkjs/core/types/blocks'
|
|
5
|
+
import type { HeroBlockProps } from './schema'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Hero Block Component
|
|
9
|
+
*
|
|
10
|
+
* Props from 3-tab structure:
|
|
11
|
+
* - Content: title, content, cta
|
|
12
|
+
* - Design: backgroundColor, backgroundImage, textColor
|
|
13
|
+
* - Advanced: className, id
|
|
14
|
+
*/
|
|
15
|
+
export function HeroBlock({
|
|
16
|
+
// Base content props
|
|
17
|
+
title,
|
|
18
|
+
content,
|
|
19
|
+
cta,
|
|
20
|
+
// Base design props
|
|
21
|
+
backgroundColor,
|
|
22
|
+
// Hero-specific design
|
|
23
|
+
backgroundImage,
|
|
24
|
+
textColor = 'light',
|
|
25
|
+
// Base advanced props
|
|
26
|
+
className,
|
|
27
|
+
id,
|
|
28
|
+
// Legacy props for backward compatibility
|
|
29
|
+
...legacyProps
|
|
30
|
+
}: HeroBlockProps & {
|
|
31
|
+
ctaText?: string
|
|
32
|
+
ctaLink?: string
|
|
33
|
+
subtitle?: string
|
|
34
|
+
description?: string
|
|
35
|
+
}) {
|
|
36
|
+
// Handle legacy CTA format (ctaText, ctaLink) for backward compatibility
|
|
37
|
+
const ctaConfig = cta || (legacyProps.ctaText ? {
|
|
38
|
+
text: legacyProps.ctaText,
|
|
39
|
+
link: legacyProps.ctaLink || '#',
|
|
40
|
+
target: '_self' as const,
|
|
41
|
+
} : undefined)
|
|
42
|
+
|
|
43
|
+
// Handle legacy subtitle/description props for backward compatibility
|
|
44
|
+
const displayContent = content || legacyProps.subtitle || legacyProps.description
|
|
45
|
+
|
|
46
|
+
// Resolve media ref to URL (handles both legacy string and new object format)
|
|
47
|
+
const backgroundImageUrl = resolveMediaUrl(backgroundImage)
|
|
48
|
+
|
|
49
|
+
// Build section classes with background and custom className
|
|
50
|
+
const sectionClasses = buildSectionClasses(
|
|
51
|
+
cn(
|
|
52
|
+
'relative flex min-h-[600px] items-center justify-center overflow-hidden px-4 py-20',
|
|
53
|
+
textColor === 'light' ? 'text-white' : 'text-gray-900'
|
|
54
|
+
),
|
|
55
|
+
{ backgroundColor, className }
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
return (
|
|
59
|
+
<section id={id} className={sectionClasses} data-cy="block-hero">
|
|
60
|
+
{/* Background Image */}
|
|
61
|
+
{backgroundImageUrl && (
|
|
62
|
+
<div
|
|
63
|
+
className="absolute inset-0 z-0"
|
|
64
|
+
style={{
|
|
65
|
+
backgroundImage: `url(${backgroundImageUrl})`,
|
|
66
|
+
backgroundSize: 'cover',
|
|
67
|
+
backgroundPosition: 'center',
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
<div className="absolute inset-0 bg-black/40" />
|
|
71
|
+
</div>
|
|
72
|
+
)}
|
|
73
|
+
|
|
74
|
+
{/* Content */}
|
|
75
|
+
<div className="container relative z-10 mx-auto max-w-4xl text-center">
|
|
76
|
+
{title && (
|
|
77
|
+
<h1 className="mb-6 text-5xl font-bold leading-tight @md:text-6xl @lg:text-7xl">
|
|
78
|
+
{title}
|
|
79
|
+
</h1>
|
|
80
|
+
)}
|
|
81
|
+
|
|
82
|
+
{displayContent && (
|
|
83
|
+
<p className="mb-8 text-xl @md:text-2xl opacity-90">
|
|
84
|
+
{displayContent}
|
|
85
|
+
</p>
|
|
86
|
+
)}
|
|
87
|
+
|
|
88
|
+
{ctaConfig && (
|
|
89
|
+
<Button asChild size="lg" className="text-lg px-8 py-6">
|
|
90
|
+
<a
|
|
91
|
+
href={ctaConfig.link}
|
|
92
|
+
target={ctaConfig.target}
|
|
93
|
+
rel={ctaConfig.target === '_blank' ? 'noopener noreferrer' : undefined}
|
|
94
|
+
>
|
|
95
|
+
{ctaConfig.text}
|
|
96
|
+
</a>
|
|
97
|
+
</Button>
|
|
98
|
+
)}
|
|
99
|
+
</div>
|
|
100
|
+
</section>
|
|
101
|
+
)
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// The generated block registry imports this as the module's default.
|
|
105
|
+
export default HeroBlock
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
|
|
3
|
+
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
|
+
slug: 'hero',
|
|
5
|
+
name: 'Hero Section',
|
|
6
|
+
description: 'Full-width hero section with title, subtitle, CTA button, and background image',
|
|
7
|
+
category: 'hero',
|
|
8
|
+
icon: 'Rocket',
|
|
9
|
+
thumbnail: '/theme/blocks/hero/thumbnail.png',
|
|
10
|
+
scope: ['pages', 'posts']
|
|
11
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
import {
|
|
3
|
+
baseContentFields,
|
|
4
|
+
baseDesignFields,
|
|
5
|
+
baseAdvancedFields,
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Hero Block Field Definitions
|
|
10
|
+
*
|
|
11
|
+
* Organized into 3 tabs:
|
|
12
|
+
* - Content: title, content, cta (from base)
|
|
13
|
+
* - Design: backgroundColor (from base) + backgroundImage, textColor
|
|
14
|
+
* - Advanced: className, id (from base)
|
|
15
|
+
*
|
|
16
|
+
* Note: The `content` field from base serves as the hero subtitle/description
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Hero-specific design fields
|
|
20
|
+
const heroDesignFields: FieldDefinition[] = [
|
|
21
|
+
{
|
|
22
|
+
name: 'backgroundImage',
|
|
23
|
+
label: 'Background Image',
|
|
24
|
+
type: 'image',
|
|
25
|
+
tab: 'design',
|
|
26
|
+
required: false,
|
|
27
|
+
helpText: 'Optional background image (recommended: 1920x1080px minimum)',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'textColor',
|
|
31
|
+
label: 'Text Color',
|
|
32
|
+
type: 'select',
|
|
33
|
+
tab: 'design',
|
|
34
|
+
required: false,
|
|
35
|
+
default: 'light',
|
|
36
|
+
helpText: 'Choose text color based on background',
|
|
37
|
+
options: [
|
|
38
|
+
{ label: 'Light (for dark backgrounds)', value: 'light' },
|
|
39
|
+
{ label: 'Dark (for light backgrounds)', value: 'dark' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Complete field definitions organized by tab
|
|
46
|
+
*/
|
|
47
|
+
export const fieldDefinitions: FieldDefinition[] = [
|
|
48
|
+
// Content tab: base fields only (title, content, cta)
|
|
49
|
+
...baseContentFields,
|
|
50
|
+
|
|
51
|
+
// Design tab: base fields + hero-specific
|
|
52
|
+
...baseDesignFields,
|
|
53
|
+
...heroDesignFields,
|
|
54
|
+
|
|
55
|
+
// Advanced tab: base fields only
|
|
56
|
+
...baseAdvancedFields,
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
// Alias for compatibility
|
|
60
|
+
export const fields = fieldDefinitions
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import {
|
|
3
|
+
baseBlockSchema,
|
|
4
|
+
mediaRefSchema,
|
|
5
|
+
type BaseBlockProps,
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Hero Block Schema
|
|
10
|
+
*
|
|
11
|
+
* Extends base schema with hero-specific fields:
|
|
12
|
+
* - backgroundImage: Optional hero background
|
|
13
|
+
* - textColor: Light/dark for contrast
|
|
14
|
+
*
|
|
15
|
+
* Note: Uses base schema title, content, cta, backgroundColor, className, id
|
|
16
|
+
* The `content` field serves as the hero subtitle/description
|
|
17
|
+
*/
|
|
18
|
+
export const heroSpecificSchema = z.object({
|
|
19
|
+
// Hero-specific design fields
|
|
20
|
+
backgroundImage: mediaRefSchema.optional(),
|
|
21
|
+
textColor: z.enum(['light', 'dark']).default('light'),
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Complete Hero Block Schema
|
|
26
|
+
* Combines base fields + hero-specific fields
|
|
27
|
+
*/
|
|
28
|
+
export const schema = baseBlockSchema.extend(heroSpecificSchema.shape)
|
|
29
|
+
|
|
30
|
+
export type HeroBlockProps = z.infer<typeof schema>
|
|
31
|
+
|
|
32
|
+
// Also export for type-only imports
|
|
33
|
+
export type { BaseBlockProps }
|
|
Binary file
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Quote } from 'lucide-react'
|
|
3
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@nextsparkjs/core/components/ui/avatar'
|
|
4
|
+
import { cn } from '@nextsparkjs/core/lib/utils'
|
|
5
|
+
import { buildSectionClasses, resolveMediaUrl } from '@nextsparkjs/core/types/blocks'
|
|
6
|
+
import type { TestimonialsBlockProps, TestimonialItem } from './schema'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Testimonials Block Component
|
|
10
|
+
*
|
|
11
|
+
* Props from 3-tab structure:
|
|
12
|
+
* - Content: title, content, cta, items
|
|
13
|
+
* - Design: backgroundColor, columns
|
|
14
|
+
* - Advanced: className, id
|
|
15
|
+
*/
|
|
16
|
+
export function TestimonialsBlock({
|
|
17
|
+
// Base content props
|
|
18
|
+
title,
|
|
19
|
+
content,
|
|
20
|
+
cta,
|
|
21
|
+
// Testimonials-specific content
|
|
22
|
+
items,
|
|
23
|
+
// Base design props
|
|
24
|
+
backgroundColor = 'gray-50',
|
|
25
|
+
// Testimonials-specific design
|
|
26
|
+
columns = '3',
|
|
27
|
+
// Base advanced props
|
|
28
|
+
className,
|
|
29
|
+
id,
|
|
30
|
+
}: TestimonialsBlockProps) {
|
|
31
|
+
// Build column classes based on columns prop
|
|
32
|
+
const columnClasses: Record<string, string> = {
|
|
33
|
+
'2': '@md:grid-cols-2',
|
|
34
|
+
'3': '@md:grid-cols-2 @lg:grid-cols-3',
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Build section classes with background and custom className
|
|
38
|
+
const sectionClasses = buildSectionClasses(
|
|
39
|
+
'py-16 px-4 @md:py-24',
|
|
40
|
+
{ backgroundColor, className }
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
// Ensure items is always an array
|
|
44
|
+
const safeItems = Array.isArray(items) ? items : []
|
|
45
|
+
|
|
46
|
+
return (
|
|
47
|
+
<section id={id} className={sectionClasses} data-cy="block-testimonials">
|
|
48
|
+
<div className="container mx-auto max-w-6xl">
|
|
49
|
+
{/* Section Header */}
|
|
50
|
+
{(title || content) && (
|
|
51
|
+
<div className="mb-12 text-center">
|
|
52
|
+
{title && (
|
|
53
|
+
<h2 className="mb-4 text-4xl font-bold @md:text-5xl">
|
|
54
|
+
{title}
|
|
55
|
+
</h2>
|
|
56
|
+
)}
|
|
57
|
+
{content && (
|
|
58
|
+
<p className="mx-auto max-w-2xl text-lg text-muted-foreground">
|
|
59
|
+
{content}
|
|
60
|
+
</p>
|
|
61
|
+
)}
|
|
62
|
+
</div>
|
|
63
|
+
)}
|
|
64
|
+
|
|
65
|
+
{/* Testimonials Grid */}
|
|
66
|
+
<div className={cn('grid gap-8', columnClasses[columns] || columnClasses['3'])}>
|
|
67
|
+
{safeItems.map((item: TestimonialItem, index: number) => (
|
|
68
|
+
<div
|
|
69
|
+
key={index}
|
|
70
|
+
className="flex flex-col p-6 rounded-lg border bg-card"
|
|
71
|
+
>
|
|
72
|
+
<Quote className="h-8 w-8 text-primary mb-4" />
|
|
73
|
+
|
|
74
|
+
<blockquote className="mb-6 text-lg flex-grow">
|
|
75
|
+
"{item.quote}"
|
|
76
|
+
</blockquote>
|
|
77
|
+
|
|
78
|
+
<div className="flex items-center gap-3">
|
|
79
|
+
<Avatar>
|
|
80
|
+
<AvatarImage src={resolveMediaUrl(item.avatar)} alt={item.author} />
|
|
81
|
+
<AvatarFallback>
|
|
82
|
+
{item.author.split(' ').map((n: string) => n[0]).join('')}
|
|
83
|
+
</AvatarFallback>
|
|
84
|
+
</Avatar>
|
|
85
|
+
|
|
86
|
+
<div>
|
|
87
|
+
<div className="font-semibold">{item.author}</div>
|
|
88
|
+
{item.role && (
|
|
89
|
+
<div className="text-sm text-muted-foreground">{item.role}</div>
|
|
90
|
+
)}
|
|
91
|
+
</div>
|
|
92
|
+
</div>
|
|
93
|
+
</div>
|
|
94
|
+
))}
|
|
95
|
+
</div>
|
|
96
|
+
|
|
97
|
+
{/* Optional CTA */}
|
|
98
|
+
{cta && (
|
|
99
|
+
<div className="mt-12 text-center">
|
|
100
|
+
<a
|
|
101
|
+
href={cta.link}
|
|
102
|
+
target={cta.target}
|
|
103
|
+
rel={cta.target === '_blank' ? 'noopener noreferrer' : undefined}
|
|
104
|
+
className="inline-flex items-center justify-center rounded-md bg-primary px-8 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors"
|
|
105
|
+
>
|
|
106
|
+
{cta.text}
|
|
107
|
+
</a>
|
|
108
|
+
</div>
|
|
109
|
+
)}
|
|
110
|
+
</div>
|
|
111
|
+
</section>
|
|
112
|
+
)
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
// The generated block registry imports this as the module's default.
|
|
116
|
+
export default TestimonialsBlock
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
|
|
3
|
+
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
|
+
slug: 'testimonials',
|
|
5
|
+
name: 'Testimonials',
|
|
6
|
+
description: 'Display customer testimonials with quotes, authors, and avatars',
|
|
7
|
+
category: 'testimonials',
|
|
8
|
+
icon: 'Quote',
|
|
9
|
+
thumbnail: '/theme/blocks/testimonials/thumbnail.png',
|
|
10
|
+
scope: ['pages']
|
|
11
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
import {
|
|
3
|
+
baseContentFields,
|
|
4
|
+
baseDesignFields,
|
|
5
|
+
baseAdvancedFields,
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Testimonials Block Field Definitions
|
|
10
|
+
*
|
|
11
|
+
* Organized into 3 tabs:
|
|
12
|
+
* - Content: title, description, cta (from base) + items array
|
|
13
|
+
* - Design: backgroundColor (from base) + columns
|
|
14
|
+
* - Advanced: className, id (from base)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Testimonials-specific content fields
|
|
18
|
+
const testimonialsContentFields: FieldDefinition[] = [
|
|
19
|
+
{
|
|
20
|
+
name: 'items',
|
|
21
|
+
label: 'Testimonials',
|
|
22
|
+
type: 'array',
|
|
23
|
+
tab: 'content',
|
|
24
|
+
required: true,
|
|
25
|
+
description: 'Customer testimonials to display',
|
|
26
|
+
helpText: 'Add up to 6 testimonials',
|
|
27
|
+
minItems: 1,
|
|
28
|
+
maxItems: 6,
|
|
29
|
+
itemFields: [
|
|
30
|
+
{
|
|
31
|
+
name: 'quote',
|
|
32
|
+
label: 'Quote',
|
|
33
|
+
type: 'textarea',
|
|
34
|
+
tab: 'content',
|
|
35
|
+
required: true,
|
|
36
|
+
placeholder: 'This product changed my life...',
|
|
37
|
+
maxLength: 500,
|
|
38
|
+
rows: 3,
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'author',
|
|
42
|
+
label: 'Author Name',
|
|
43
|
+
type: 'text',
|
|
44
|
+
tab: 'content',
|
|
45
|
+
required: true,
|
|
46
|
+
placeholder: 'John Doe',
|
|
47
|
+
maxLength: 100,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'role',
|
|
51
|
+
label: 'Role/Title',
|
|
52
|
+
type: 'text',
|
|
53
|
+
tab: 'content',
|
|
54
|
+
required: false,
|
|
55
|
+
placeholder: 'CEO at Company',
|
|
56
|
+
maxLength: 100,
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'avatar',
|
|
60
|
+
label: 'Avatar Image',
|
|
61
|
+
type: 'image',
|
|
62
|
+
tab: 'content',
|
|
63
|
+
required: false,
|
|
64
|
+
description: 'Profile picture of the person',
|
|
65
|
+
helpText: 'Recommended size: 100x100px',
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
},
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
// Testimonials-specific design fields
|
|
72
|
+
const testimonialsDesignFields: FieldDefinition[] = [
|
|
73
|
+
{
|
|
74
|
+
name: 'columns',
|
|
75
|
+
label: 'Grid Columns',
|
|
76
|
+
type: 'select',
|
|
77
|
+
tab: 'design',
|
|
78
|
+
required: false,
|
|
79
|
+
default: '3',
|
|
80
|
+
description: 'Number of columns in the grid layout',
|
|
81
|
+
options: [
|
|
82
|
+
{ label: '2 Columns', value: '2' },
|
|
83
|
+
{ label: '3 Columns', value: '3' },
|
|
84
|
+
],
|
|
85
|
+
},
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Complete field definitions organized by tab
|
|
90
|
+
*/
|
|
91
|
+
export const fieldDefinitions: FieldDefinition[] = [
|
|
92
|
+
// Content tab: base fields + testimonials-specific
|
|
93
|
+
...baseContentFields,
|
|
94
|
+
...testimonialsContentFields,
|
|
95
|
+
|
|
96
|
+
// Design tab: base fields + testimonials-specific
|
|
97
|
+
...baseDesignFields,
|
|
98
|
+
...testimonialsDesignFields,
|
|
99
|
+
|
|
100
|
+
// Advanced tab: base fields only
|
|
101
|
+
...baseAdvancedFields,
|
|
102
|
+
]
|
|
103
|
+
|
|
104
|
+
// Alias for compatibility
|
|
105
|
+
export const fields = fieldDefinitions
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { baseBlockSchema, mediaRefSchema } from '@nextsparkjs/core/types/blocks'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Testimonial Item Schema
|
|
6
|
+
* Individual testimonial entry
|
|
7
|
+
*/
|
|
8
|
+
const testimonialItemSchema = z.object({
|
|
9
|
+
quote: z.string().min(1, 'Quote is required').max(500),
|
|
10
|
+
author: z.string().min(1, 'Author name is required').max(100),
|
|
11
|
+
role: z.string().max(100).optional(),
|
|
12
|
+
avatar: mediaRefSchema.optional(),
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
export type TestimonialItem = z.infer<typeof testimonialItemSchema>
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Testimonials Block Schema
|
|
19
|
+
*
|
|
20
|
+
* Extends base schema with:
|
|
21
|
+
* - items: Array of testimonial items
|
|
22
|
+
* - columns: Grid layout option (2, 3 columns)
|
|
23
|
+
*
|
|
24
|
+
* Note: Uses base schema title, description, cta, backgroundColor, className, id
|
|
25
|
+
*/
|
|
26
|
+
export const testimonialsSpecificSchema = z.object({
|
|
27
|
+
// Content: array of testimonials
|
|
28
|
+
items: z.array(testimonialItemSchema)
|
|
29
|
+
.min(1, 'At least one testimonial is required')
|
|
30
|
+
.max(6, 'Maximum 6 testimonials allowed'),
|
|
31
|
+
|
|
32
|
+
// Design: column layout
|
|
33
|
+
columns: z.enum(['2', '3']).default('3'),
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Complete Testimonials Block Schema
|
|
38
|
+
*/
|
|
39
|
+
export const schema = baseBlockSchema.extend(testimonialsSpecificSchema.shape)
|
|
40
|
+
|
|
41
|
+
export type TestimonialsBlockProps = z.infer<typeof schema>
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { cn } from '@nextsparkjs/core/lib/utils'
|
|
3
|
+
import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
|
|
4
|
+
import { sanitizeBlockHtml } from '@nextsparkjs/core/lib/blocks/sanitize-html'
|
|
5
|
+
import type { TextContentBlockProps } from './schema'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Text Content Block Component
|
|
9
|
+
*
|
|
10
|
+
* Props from 3-tab structure:
|
|
11
|
+
* - Content: title, content (rich-text), cta
|
|
12
|
+
* - Design: backgroundColor, maxWidth, alignment
|
|
13
|
+
* - Advanced: className, id
|
|
14
|
+
*
|
|
15
|
+
* Note: `content` is the main rich-text body of this block
|
|
16
|
+
*/
|
|
17
|
+
export function TextContentBlock({
|
|
18
|
+
// Base content props
|
|
19
|
+
title,
|
|
20
|
+
content,
|
|
21
|
+
cta,
|
|
22
|
+
// Base design props
|
|
23
|
+
backgroundColor,
|
|
24
|
+
// Text-content-specific design
|
|
25
|
+
maxWidth = 'lg',
|
|
26
|
+
alignment = 'left',
|
|
27
|
+
// Base advanced props
|
|
28
|
+
className,
|
|
29
|
+
id,
|
|
30
|
+
}: TextContentBlockProps) {
|
|
31
|
+
const maxWidthClasses: Record<string, string> = {
|
|
32
|
+
sm: 'max-w-2xl',
|
|
33
|
+
md: 'max-w-3xl',
|
|
34
|
+
lg: 'max-w-4xl',
|
|
35
|
+
xl: 'max-w-5xl',
|
|
36
|
+
full: 'max-w-none',
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const alignmentClasses: Record<string, string> = {
|
|
40
|
+
left: 'text-left',
|
|
41
|
+
center: 'text-center mx-auto',
|
|
42
|
+
right: 'text-right ml-auto',
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Build section classes with background and custom className
|
|
46
|
+
const sectionClasses = buildSectionClasses(
|
|
47
|
+
'py-16 px-4 @md:py-24',
|
|
48
|
+
{ backgroundColor, className }
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<section id={id} className={sectionClasses} data-cy="block-text-content">
|
|
53
|
+
<div className="container mx-auto">
|
|
54
|
+
{/* Optional Section Title */}
|
|
55
|
+
{title && (
|
|
56
|
+
<div className={cn(
|
|
57
|
+
'mb-8',
|
|
58
|
+
maxWidthClasses[maxWidth],
|
|
59
|
+
alignmentClasses[alignment]
|
|
60
|
+
)}>
|
|
61
|
+
<h2 className="text-3xl font-bold @md:text-4xl">
|
|
62
|
+
{title}
|
|
63
|
+
</h2>
|
|
64
|
+
</div>
|
|
65
|
+
)}
|
|
66
|
+
|
|
67
|
+
{/* Rich Text Content */}
|
|
68
|
+
<div
|
|
69
|
+
className={cn(
|
|
70
|
+
'prose prose-lg dark:prose-invert',
|
|
71
|
+
maxWidthClasses[maxWidth],
|
|
72
|
+
alignmentClasses[alignment]
|
|
73
|
+
)}
|
|
74
|
+
dangerouslySetInnerHTML={{ __html: sanitizeBlockHtml(content) }}
|
|
75
|
+
/>
|
|
76
|
+
|
|
77
|
+
{/* Optional CTA */}
|
|
78
|
+
{cta && (
|
|
79
|
+
<div className={cn(
|
|
80
|
+
'mt-8',
|
|
81
|
+
maxWidthClasses[maxWidth],
|
|
82
|
+
alignmentClasses[alignment]
|
|
83
|
+
)}>
|
|
84
|
+
<a
|
|
85
|
+
href={cta.link}
|
|
86
|
+
target={cta.target}
|
|
87
|
+
rel={cta.target === '_blank' ? 'noopener noreferrer' : undefined}
|
|
88
|
+
className="inline-flex items-center justify-center rounded-md bg-primary px-8 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors"
|
|
89
|
+
>
|
|
90
|
+
{cta.text}
|
|
91
|
+
</a>
|
|
92
|
+
</div>
|
|
93
|
+
)}
|
|
94
|
+
</div>
|
|
95
|
+
</section>
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// The generated block registry imports this as the module's default.
|
|
100
|
+
export default TextContentBlock
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
|
|
3
|
+
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
|
+
slug: 'text-content',
|
|
5
|
+
name: 'Text Content',
|
|
6
|
+
description: 'Rich text content block for paragraphs, lists, and formatted text',
|
|
7
|
+
category: 'content',
|
|
8
|
+
icon: 'FileText',
|
|
9
|
+
thumbnail: '/theme/blocks/text-content/thumbnail.png',
|
|
10
|
+
scope: ['pages']
|
|
11
|
+
}
|