@nextsparkjs/core 0.1.0-beta.187 → 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.d.ts +10 -1
- package/dist/components/dashboard/mobile/MobileTopBar.d.ts.map +1 -1
- package/dist/components/dashboard/mobile/MobileTopBar.js +4 -3
- 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
|
@@ -27,7 +27,7 @@ function ApiKeyDisplay({ apiKey, keyName, warning, onClose }) {
|
|
|
27
27
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
28
28
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
|
|
29
29
|
/* @__PURE__ */ jsx(CheckCircle, { className: "h-5 w-5 text-green-600" }),
|
|
30
|
-
/* @__PURE__ */ jsx(CardTitle, { className: "text-green-800", children: "API Key
|
|
30
|
+
/* @__PURE__ */ jsx(CardTitle, { className: "text-green-800", children: "API Key created successfully" })
|
|
31
31
|
] }),
|
|
32
32
|
/* @__PURE__ */ jsx(Button, { variant: "ghost", size: "sm", onClick: onClose, children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" }) })
|
|
33
33
|
] }),
|
|
@@ -37,13 +37,13 @@ function ApiKeyDisplay({ apiKey, keyName, warning, onClose }) {
|
|
|
37
37
|
warning && /* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
|
|
38
38
|
/* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4" }),
|
|
39
39
|
/* @__PURE__ */ jsxs(AlertDescription, { children: [
|
|
40
|
-
/* @__PURE__ */ jsx("strong", { children: "
|
|
40
|
+
/* @__PURE__ */ jsx("strong", { children: "Important!" }),
|
|
41
41
|
" ",
|
|
42
42
|
warning
|
|
43
43
|
] })
|
|
44
44
|
] }),
|
|
45
45
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
46
|
-
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium text-green-800", children: "
|
|
46
|
+
/* @__PURE__ */ jsx("label", { className: "text-sm font-medium text-green-800", children: "Your new API Key:" }),
|
|
47
47
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
48
48
|
/* @__PURE__ */ jsxs("div", { className: "relative flex-1", children: [
|
|
49
49
|
/* @__PURE__ */ jsx(
|
|
@@ -76,29 +76,29 @@ function ApiKeyDisplay({ apiKey, keyName, warning, onClose }) {
|
|
|
76
76
|
"data-cy": sel("settings.apiKeys.newKeyDisplay.copyButton"),
|
|
77
77
|
children: [
|
|
78
78
|
/* @__PURE__ */ jsx(Copy, { className: "h-4 w-4 mr-2" }),
|
|
79
|
-
copied ? "
|
|
79
|
+
copied ? "Copied!" : "Copy"
|
|
80
80
|
]
|
|
81
81
|
}
|
|
82
82
|
)
|
|
83
83
|
] })
|
|
84
84
|
] }),
|
|
85
85
|
/* @__PURE__ */ jsxs("div", { className: "space-y-3", children: [
|
|
86
|
-
/* @__PURE__ */ jsx("h4", { className: "text-sm font-medium text-green-800", children: "
|
|
86
|
+
/* @__PURE__ */ jsx("h4", { className: "text-sm font-medium text-green-800", children: "How to use your API Key:" }),
|
|
87
87
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2 text-sm", children: [
|
|
88
88
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
89
|
-
/* @__PURE__ */ jsx("strong", { children: "1.
|
|
89
|
+
/* @__PURE__ */ jsx("strong", { children: "1. Include the API key in the Authorization header:" }),
|
|
90
90
|
/* @__PURE__ */ jsxs("div", { className: "mt-1 p-2 bg-gray-100 rounded font-mono text-xs overflow-x-auto", children: [
|
|
91
91
|
"Authorization: Bearer ",
|
|
92
92
|
isVisible ? apiKey : "sk_live_\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022"
|
|
93
93
|
] })
|
|
94
94
|
] }),
|
|
95
95
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
96
|
-
/* @__PURE__ */ jsx("strong", { children: "2.
|
|
96
|
+
/* @__PURE__ */ jsx("strong", { children: "2. Example with curl:" }),
|
|
97
97
|
/* @__PURE__ */ jsx("div", { className: "mt-1 p-2 bg-gray-100 rounded font-mono text-xs overflow-x-auto", children: `curl -H "Authorization: Bearer ${isVisible ? apiKey : "YOUR_API_KEY"}" \\
|
|
98
98
|
https://yourapp.com/api/v1/users` })
|
|
99
99
|
] }),
|
|
100
100
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
101
|
-
/* @__PURE__ */ jsx("strong", { children: "3.
|
|
101
|
+
/* @__PURE__ */ jsx("strong", { children: "3. Example with JavaScript:" }),
|
|
102
102
|
/* @__PURE__ */ jsx("div", { className: "mt-1 p-2 bg-gray-100 rounded font-mono text-xs overflow-x-auto", children: `fetch('/api/v1/users', {
|
|
103
103
|
headers: {
|
|
104
104
|
'Authorization': 'Bearer ${isVisible ? apiKey : "YOUR_API_KEY"}',
|
|
@@ -109,20 +109,20 @@ function ApiKeyDisplay({ apiKey, keyName, warning, onClose }) {
|
|
|
109
109
|
] })
|
|
110
110
|
] }),
|
|
111
111
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
112
|
-
/* @__PURE__ */ jsx("h4", { className: "text-sm font-medium text-green-800", children: "
|
|
112
|
+
/* @__PURE__ */ jsx("h4", { className: "text-sm font-medium text-green-800", children: "Security tips:" }),
|
|
113
113
|
/* @__PURE__ */ jsxs("ul", { className: "text-sm text-green-700 space-y-1 list-disc list-inside", children: [
|
|
114
|
-
/* @__PURE__ */ jsx("li", { children: "
|
|
115
|
-
/* @__PURE__ */ jsx("li", { children: "
|
|
116
|
-
/* @__PURE__ */ jsx("li", { children: "
|
|
117
|
-
/* @__PURE__ */ jsx("li", { children: "
|
|
114
|
+
/* @__PURE__ */ jsx("li", { children: "Never share your API key publicly" }),
|
|
115
|
+
/* @__PURE__ */ jsx("li", { children: "Store it as an environment variable in your application" }),
|
|
116
|
+
/* @__PURE__ */ jsx("li", { children: "Revoke the key immediately if you think it's compromised" }),
|
|
117
|
+
/* @__PURE__ */ jsx("li", { children: "Always use HTTPS when making requests to the API" })
|
|
118
118
|
] })
|
|
119
119
|
] }),
|
|
120
120
|
/* @__PURE__ */ jsxs("div", { className: "p-3 bg-blue-50 rounded-lg border border-blue-200", children: [
|
|
121
|
-
/* @__PURE__ */ jsx("h4", { className: "text-sm font-medium text-blue-800 mb-1", children: "
|
|
121
|
+
/* @__PURE__ */ jsx("h4", { className: "text-sm font-medium text-blue-800 mb-1", children: "API limits:" }),
|
|
122
122
|
/* @__PURE__ */ jsxs("div", { className: "text-sm text-blue-700 space-y-1", children: [
|
|
123
|
-
/* @__PURE__ */ jsx("div", { children: "\u2022 1,000 requests
|
|
124
|
-
/* @__PURE__ */ jsx("div", { children: "\u2022
|
|
125
|
-
/* @__PURE__ */ jsx("div", { children: "\u2022
|
|
123
|
+
/* @__PURE__ */ jsx("div", { children: "\u2022 1,000 requests per minute" }),
|
|
124
|
+
/* @__PURE__ */ jsx("div", { children: "\u2022 Rate limiting headers included in responses" }),
|
|
125
|
+
/* @__PURE__ */ jsx("div", { children: "\u2022 Full documentation available at /docs" })
|
|
126
126
|
] })
|
|
127
127
|
] }),
|
|
128
128
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-2 pt-2", children: [
|
|
@@ -134,11 +134,11 @@ function ApiKeyDisplay({ apiKey, keyName, warning, onClose }) {
|
|
|
134
134
|
className: "flex-1",
|
|
135
135
|
children: [
|
|
136
136
|
/* @__PURE__ */ jsx(Copy, { className: "h-4 w-4 mr-2" }),
|
|
137
|
-
copied ? "API Key
|
|
137
|
+
copied ? "API Key Copied!" : "Copy API Key"
|
|
138
138
|
]
|
|
139
139
|
}
|
|
140
140
|
),
|
|
141
|
-
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "outline", children: "
|
|
141
|
+
/* @__PURE__ */ jsx(Button, { onClick: onClose, variant: "outline", children: "Got it" })
|
|
142
142
|
] })
|
|
143
143
|
] })
|
|
144
144
|
] });
|
|
@@ -35,8 +35,8 @@ function useScopeCatalogue() {
|
|
|
35
35
|
return {
|
|
36
36
|
...SCOPE_CATEGORIES,
|
|
37
37
|
app: {
|
|
38
|
-
name: "
|
|
39
|
-
description: "Scopes
|
|
38
|
+
name: "Application",
|
|
39
|
+
description: "Scopes this application defines for its own routes",
|
|
40
40
|
scopes: appScopes
|
|
41
41
|
}
|
|
42
42
|
};
|
|
@@ -134,35 +134,35 @@ function CreateApiKeyDialog({ open, onClose, onSuccess }) {
|
|
|
134
134
|
};
|
|
135
135
|
return /* @__PURE__ */ jsx(Dialog, { open, onOpenChange: handleClose, children: /* @__PURE__ */ jsxs(DialogContent, { className: "max-w-2xl max-h-[90vh] overflow-y-auto", "data-cy": sel("settings.apiKeys.createDialog.container"), children: [
|
|
136
136
|
/* @__PURE__ */ jsxs(DialogHeader, { children: [
|
|
137
|
-
/* @__PURE__ */ jsx(DialogTitle, { children: "
|
|
138
|
-
/* @__PURE__ */ jsx(DialogDescription, { children: "
|
|
137
|
+
/* @__PURE__ */ jsx(DialogTitle, { children: "Create new API Key" }),
|
|
138
|
+
/* @__PURE__ */ jsx(DialogDescription, { children: "Create an API key to securely access the external endpoints." })
|
|
139
139
|
] }),
|
|
140
140
|
/* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-6", children: [
|
|
141
141
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
142
|
-
/* @__PURE__ */ jsx(Label, { htmlFor: "name", children: "
|
|
142
|
+
/* @__PURE__ */ jsx(Label, { htmlFor: "name", children: "API Key Name" }),
|
|
143
143
|
/* @__PURE__ */ jsx(
|
|
144
144
|
Input,
|
|
145
145
|
{
|
|
146
146
|
id: "name",
|
|
147
147
|
value: name,
|
|
148
148
|
onChange: (e) => setName(e.target.value),
|
|
149
|
-
placeholder: "
|
|
149
|
+
placeholder: "e.g. My mobile app",
|
|
150
150
|
maxLength: 100,
|
|
151
151
|
"data-cy": sel("settings.apiKeys.createDialog.nameInput")
|
|
152
152
|
}
|
|
153
153
|
),
|
|
154
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "
|
|
154
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "A descriptive name to identify this API key" })
|
|
155
155
|
] }),
|
|
156
156
|
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
157
|
-
/* @__PURE__ */ jsx(Label, { children: "
|
|
157
|
+
/* @__PURE__ */ jsx(Label, { children: "Expiration" }),
|
|
158
158
|
/* @__PURE__ */ jsxs(Select, { value: expiryOption, onValueChange: (value) => setExpiryOption(value), children: [
|
|
159
159
|
/* @__PURE__ */ jsx(SelectTrigger, { children: /* @__PURE__ */ jsx(SelectValue, {}) }),
|
|
160
160
|
/* @__PURE__ */ jsxs(SelectContent, { children: [
|
|
161
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "never", children: "
|
|
162
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "30d", children: "30
|
|
163
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "90d", children: "90
|
|
164
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "1y", children: "1
|
|
165
|
-
/* @__PURE__ */ jsx(SelectItem, { value: "custom", children: "
|
|
161
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "never", children: "Never expires" }),
|
|
162
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "30d", children: "30 days" }),
|
|
163
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "90d", children: "90 days" }),
|
|
164
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "1y", children: "1 year" }),
|
|
165
|
+
/* @__PURE__ */ jsx(SelectItem, { value: "custom", children: "Custom date" })
|
|
166
166
|
] })
|
|
167
167
|
] }),
|
|
168
168
|
expiryOption === "custom" && /* @__PURE__ */ jsx(
|
|
@@ -177,12 +177,12 @@ function CreateApiKeyDialog({ open, onClose, onSuccess }) {
|
|
|
177
177
|
] }),
|
|
178
178
|
/* @__PURE__ */ jsxs("div", { className: "space-y-4", "data-cy": sel("settings.apiKeys.createDialog.scopesContainer"), children: [
|
|
179
179
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
180
|
-
/* @__PURE__ */ jsx(Label, { children: "
|
|
181
|
-
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "
|
|
180
|
+
/* @__PURE__ */ jsx(Label, { children: "Permissions (Scopes)" }),
|
|
181
|
+
/* @__PURE__ */ jsx("p", { className: "text-xs text-muted-foreground", children: "Choose the permissions this API key will have" })
|
|
182
182
|
] }),
|
|
183
183
|
/* @__PURE__ */ jsxs(Alert, { children: [
|
|
184
184
|
/* @__PURE__ */ jsx(Info, { className: "h-4 w-4" }),
|
|
185
|
-
/* @__PURE__ */ jsx(AlertDescription, { children: "
|
|
185
|
+
/* @__PURE__ */ jsx(AlertDescription, { children: "You can only assign permissions that your current role allows. Permissions cannot be changed after creating the API key." })
|
|
186
186
|
] }),
|
|
187
187
|
/* @__PURE__ */ jsx("div", { className: "space-y-4", children: Object.entries(scopeCatalogue).map(([categoryKey, category]) => {
|
|
188
188
|
const isFullySelected = isCategoryFullySelected(category.scopes);
|
|
@@ -232,7 +232,7 @@ function CreateApiKeyDialog({ open, onClose, onSuccess }) {
|
|
|
232
232
|
}) }),
|
|
233
233
|
selectedScopes.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
234
234
|
/* @__PURE__ */ jsxs(Label, { children: [
|
|
235
|
-
"
|
|
235
|
+
"Selected permissions (",
|
|
236
236
|
selectedScopes.length,
|
|
237
237
|
")"
|
|
238
238
|
] }),
|
|
@@ -242,20 +242,20 @@ function CreateApiKeyDialog({ open, onClose, onSuccess }) {
|
|
|
242
242
|
/* @__PURE__ */ jsxs(Alert, { variant: "destructive", children: [
|
|
243
243
|
/* @__PURE__ */ jsx(AlertTriangle, { className: "h-4 w-4" }),
|
|
244
244
|
/* @__PURE__ */ jsxs(AlertDescription, { children: [
|
|
245
|
-
/* @__PURE__ */ jsx("strong", { children: "
|
|
246
|
-
"
|
|
245
|
+
/* @__PURE__ */ jsx("strong", { children: "Important:" }),
|
|
246
|
+
" The API key will only be shown once after creation. Store it somewhere safe, as you won't be able to see it again."
|
|
247
247
|
] })
|
|
248
248
|
] })
|
|
249
249
|
] }),
|
|
250
250
|
/* @__PURE__ */ jsxs(DialogFooter, { "data-cy": sel("settings.apiKeys.createDialog.footer"), children: [
|
|
251
|
-
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleClose, disabled: createApiKey.isPending, children: "
|
|
251
|
+
/* @__PURE__ */ jsx(Button, { variant: "outline", onClick: handleClose, disabled: createApiKey.isPending, children: "Cancel" }),
|
|
252
252
|
/* @__PURE__ */ jsx(
|
|
253
253
|
Button,
|
|
254
254
|
{
|
|
255
255
|
onClick: handleSubmit,
|
|
256
256
|
disabled: createApiKey.isPending || selectedScopes.length === 0 || !name.trim(),
|
|
257
257
|
"data-cy": sel("settings.apiKeys.createDialog.submitButton"),
|
|
258
|
-
children: createApiKey.isPending ? "
|
|
258
|
+
children: createApiKey.isPending ? "Creating..." : "Create API Key"
|
|
259
259
|
}
|
|
260
260
|
)
|
|
261
261
|
] })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PublicNavbar.d.ts","sourceRoot":"","sources":["../../../../src/components/app/layouts/PublicNavbar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"PublicNavbar.d.ts","sourceRoot":"","sources":["../../../../src/components/app/layouts/PublicNavbar.tsx"],"names":[],"mappings":"AAqGA,wBAAgB,YAAY,4CAsG3B"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
3
|
import Link from "next/link";
|
|
4
4
|
import { useAuth } from "../../../hooks/useAuth.js";
|
|
5
|
+
import { useSessionHint } from "../../../hooks/useSessionHint.js";
|
|
5
6
|
import { Button } from "../../ui/button.js";
|
|
6
7
|
import { ThemeToggle } from "../misc/ThemeToggle.js";
|
|
7
8
|
import { Menu, X } from "lucide-react";
|
|
@@ -9,11 +10,40 @@ import { useState } from "react";
|
|
|
9
10
|
import { sel } from "../../../lib/test/index.js";
|
|
10
11
|
import { useTranslations } from "next-intl";
|
|
11
12
|
import { APP_NAME } from "../../../lib/config/index.js";
|
|
12
|
-
function
|
|
13
|
+
function AuthActionsSkeleton({ layout }) {
|
|
14
|
+
return layout === "desktop" ? /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
|
|
15
|
+
/* @__PURE__ */ jsx("div", { className: "h-9 w-16 bg-muted animate-pulse rounded-md" }),
|
|
16
|
+
/* @__PURE__ */ jsx("div", { className: "h-9 w-20 bg-muted animate-pulse rounded-md" })
|
|
17
|
+
] }) : /* @__PURE__ */ jsxs("div", { className: "flex flex-col space-y-2", children: [
|
|
18
|
+
/* @__PURE__ */ jsx("div", { className: "h-9 bg-muted animate-pulse rounded-md" }),
|
|
19
|
+
/* @__PURE__ */ jsx("div", { className: "h-9 bg-muted animate-pulse rounded-md" })
|
|
20
|
+
] });
|
|
21
|
+
}
|
|
22
|
+
function SignedOutActions({ layout, onNavigate }) {
|
|
23
|
+
const tHome = useTranslations("home");
|
|
24
|
+
return layout === "desktop" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
25
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", asChild: true, "data-cy": sel("public.navbar.loginButton"), children: /* @__PURE__ */ jsx(Link, { href: "/login", children: tHome("auth.signIn") }) }),
|
|
26
|
+
/* @__PURE__ */ jsx(Button, { asChild: true, "data-cy": sel("public.navbar.signupButton"), children: /* @__PURE__ */ jsx(Link, { href: "/signup", children: tHome("auth.createAccount") }) })
|
|
27
|
+
] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
28
|
+
/* @__PURE__ */ jsx(Button, { variant: "ghost", asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(Link, { href: "/login", onClick: onNavigate, children: tHome("auth.signIn") }) }),
|
|
29
|
+
/* @__PURE__ */ jsx(Button, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(Link, { href: "/signup", onClick: onNavigate, children: tHome("auth.createAccount") }) })
|
|
30
|
+
] });
|
|
31
|
+
}
|
|
32
|
+
function SessionActions({ layout, onNavigate }) {
|
|
13
33
|
const { user, isLoading } = useAuth();
|
|
34
|
+
const tHome = useTranslations("home");
|
|
35
|
+
if (isLoading) return /* @__PURE__ */ jsx(AuthActionsSkeleton, { layout });
|
|
36
|
+
if (!user) return /* @__PURE__ */ jsx(SignedOutActions, { layout, onNavigate });
|
|
37
|
+
return layout === "desktop" ? /* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsx(Link, { href: "/dashboard", children: tHome("auth.goToDashboard") }) }) : /* @__PURE__ */ jsx(Button, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(Link, { href: "/dashboard", onClick: onNavigate, children: tHome("auth.goToDashboard") }) });
|
|
38
|
+
}
|
|
39
|
+
function AuthActions(props) {
|
|
40
|
+
const { ready, signedIn } = useSessionHint();
|
|
41
|
+
if (!ready) return /* @__PURE__ */ jsx(AuthActionsSkeleton, { layout: props.layout });
|
|
42
|
+
return signedIn ? /* @__PURE__ */ jsx(SessionActions, { ...props }) : /* @__PURE__ */ jsx(SignedOutActions, { ...props });
|
|
43
|
+
}
|
|
44
|
+
function PublicNavbar() {
|
|
14
45
|
const [isMenuOpen, setIsMenuOpen] = useState(false);
|
|
15
46
|
const tNav = useTranslations("navigation");
|
|
16
|
-
const tHome = useTranslations("home");
|
|
17
47
|
const appName = APP_NAME;
|
|
18
48
|
const navigationItems = [
|
|
19
49
|
{ name: "features", href: "/features" },
|
|
@@ -53,13 +83,7 @@ function PublicNavbar() {
|
|
|
53
83
|
/* @__PURE__ */ jsx("div", { className: "w-full flex-1 md:w-auto md:flex-none" }),
|
|
54
84
|
/* @__PURE__ */ jsxs("div", { className: "hidden md:flex items-center gap-2", children: [
|
|
55
85
|
/* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
56
|
-
|
|
57
|
-
/* @__PURE__ */ jsx("div", { className: "h-9 w-16 bg-muted animate-pulse rounded-md" }),
|
|
58
|
-
/* @__PURE__ */ jsx("div", { className: "h-9 w-20 bg-muted animate-pulse rounded-md" })
|
|
59
|
-
] }) : user ? /* @__PURE__ */ jsx(Button, { asChild: true, children: /* @__PURE__ */ jsx(Link, { href: "/dashboard", children: tHome("auth.goToDashboard") }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
60
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", asChild: true, "data-cy": sel("public.navbar.loginButton"), children: /* @__PURE__ */ jsx(Link, { href: "/login", children: tHome("auth.signIn") }) }),
|
|
61
|
-
/* @__PURE__ */ jsx(Button, { asChild: true, "data-cy": sel("public.navbar.signupButton"), children: /* @__PURE__ */ jsx(Link, { href: "/signup", children: tHome("auth.createAccount") }) })
|
|
62
|
-
] })
|
|
86
|
+
/* @__PURE__ */ jsx(AuthActions, { layout: "desktop" })
|
|
63
87
|
] }),
|
|
64
88
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 md:hidden", children: [
|
|
65
89
|
/* @__PURE__ */ jsx(ThemeToggle, {}),
|
|
@@ -86,13 +110,7 @@ function PublicNavbar() {
|
|
|
86
110
|
},
|
|
87
111
|
item.name
|
|
88
112
|
)) }),
|
|
89
|
-
/* @__PURE__ */ jsx("div", { className: "flex flex-col space-y-2 pt-4 border-t border-border", children:
|
|
90
|
-
/* @__PURE__ */ jsx("div", { className: "h-9 bg-muted animate-pulse rounded-md" }),
|
|
91
|
-
/* @__PURE__ */ jsx("div", { className: "h-9 bg-muted animate-pulse rounded-md" })
|
|
92
|
-
] }) : user ? /* @__PURE__ */ jsx(Button, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(Link, { href: "/dashboard", onClick: () => setIsMenuOpen(false), children: tHome("auth.goToDashboard") }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
93
|
-
/* @__PURE__ */ jsx(Button, { variant: "ghost", asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(Link, { href: "/login", onClick: () => setIsMenuOpen(false), children: tHome("auth.signIn") }) }),
|
|
94
|
-
/* @__PURE__ */ jsx(Button, { asChild: true, className: "w-full", children: /* @__PURE__ */ jsx(Link, { href: "/signup", onClick: () => setIsMenuOpen(false), children: tHome("auth.createAccount") }) })
|
|
95
|
-
] }) })
|
|
113
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-col space-y-2 pt-4 border-t border-border", children: /* @__PURE__ */ jsx(AuthActions, { layout: "mobile", onNavigate: () => setIsMenuOpen(false) }) })
|
|
96
114
|
] }) })
|
|
97
115
|
]
|
|
98
116
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../../../../src/components/app/misc/ThemeToggle.tsx"],"names":[],"mappings":"AAiBA,wBAAgB,WAAW,
|
|
1
|
+
{"version":3,"file":"ThemeToggle.d.ts","sourceRoot":"","sources":["../../../../src/components/app/misc/ThemeToggle.tsx"],"names":[],"mappings":"AAiBA,wBAAgB,WAAW,4CA6H1B"}
|
|
@@ -12,10 +12,9 @@ import {
|
|
|
12
12
|
import { useEffect, useState, useCallback } from "react";
|
|
13
13
|
import { createAriaLabel, sel } from "../../../lib/test/index.js";
|
|
14
14
|
import { useTranslations } from "next-intl";
|
|
15
|
-
import {
|
|
15
|
+
import { hasSessionHint } from "../../../lib/auth/session-hint.js";
|
|
16
16
|
function ThemeToggle() {
|
|
17
17
|
const { setTheme, theme, forcedTheme } = useTheme();
|
|
18
|
-
const { user } = useAuth();
|
|
19
18
|
const [mounted, setMounted] = useState(false);
|
|
20
19
|
const [statusMessage, setStatusMessage] = useState("");
|
|
21
20
|
const t = useTranslations("common");
|
|
@@ -30,7 +29,7 @@ function ThemeToggle() {
|
|
|
30
29
|
system: t("theme.system")
|
|
31
30
|
};
|
|
32
31
|
setStatusMessage(`${t("theme.changed")} ${themeNames[newTheme]}`);
|
|
33
|
-
if (
|
|
32
|
+
if (hasSessionHint()) {
|
|
34
33
|
try {
|
|
35
34
|
await fetch("/api/user/profile", {
|
|
36
35
|
method: "PATCH",
|
|
@@ -49,7 +48,7 @@ function ThemeToggle() {
|
|
|
49
48
|
console.error("[ThemeToggle] Failed to save theme preference:", error);
|
|
50
49
|
}
|
|
51
50
|
}
|
|
52
|
-
}, [setTheme, t
|
|
51
|
+
}, [setTheme, t]);
|
|
53
52
|
if (forcedTheme) {
|
|
54
53
|
return null;
|
|
55
54
|
}
|
|
@@ -9,6 +9,11 @@ import { type UseSessionCookieRefreshOptions } from '../../hooks/useSessionCooki
|
|
|
9
9
|
* `useSessionCookieRefresh` for the options and `lib/auth/session-refresh.ts`
|
|
10
10
|
* for why render-time session reads cannot do this themselves.
|
|
11
11
|
*
|
|
12
|
+
* It only asks while the browser is signed in (see `lib/auth/session-hint`),
|
|
13
|
+
* following the hint as a sign-in or sign-out on the page changes it, so an
|
|
14
|
+
* anonymous visitor makes no request; and each answer brings the locale cookie
|
|
15
|
+
* and the theme in line with the account (`useAccountPreferencesSync`).
|
|
16
|
+
*
|
|
12
17
|
* @example
|
|
13
18
|
* ```tsx
|
|
14
19
|
* // app/layout.tsx
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SessionCookieRefresher.d.ts","sourceRoot":"","sources":["../../../src/components/auth/SessionCookieRefresher.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SessionCookieRefresher.d.ts","sourceRoot":"","sources":["../../../src/components/auth/SessionCookieRefresher.tsx"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,8BAA8B,EACpC,MAAM,qCAAqC,CAAA;AAM5C;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,GAAE,8BAAmC,OAOhF"}
|
|
@@ -1,9 +1,15 @@
|
|
|
1
1
|
"use client";
|
|
2
|
+
import { useSyncExternalStore } from "react";
|
|
2
3
|
import {
|
|
3
4
|
useSessionCookieRefresh
|
|
4
5
|
} from "../../hooks/useSessionCookieRefresh.js";
|
|
6
|
+
import { useAccountPreferencesSync } from "../../hooks/useAccountPreferencesSync.js";
|
|
7
|
+
import { hasSessionHint, subscribeSessionHint } from "../../lib/auth/session-hint.js";
|
|
8
|
+
const signedOutOnServer = () => false;
|
|
5
9
|
function SessionCookieRefresher(props = {}) {
|
|
6
|
-
|
|
10
|
+
const signedIn = useSyncExternalStore(subscribeSessionHint, hasSessionHint, signedOutOnServer);
|
|
11
|
+
const onRefresh = useAccountPreferencesSync();
|
|
12
|
+
useSessionCookieRefresh({ ...props, enabled: (props.enabled ?? true) && signedIn, onRefresh });
|
|
7
13
|
return null;
|
|
8
14
|
}
|
|
9
15
|
export {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/forms/LoginForm.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"LoginForm.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/forms/LoginForm.tsx"],"names":[],"mappings":"AAsIA,wBAAgB,SAAS,4CAmvBxB"}
|
|
@@ -6,7 +6,8 @@ import { useSearchParams } from "next/navigation";
|
|
|
6
6
|
import { useForm } from "react-hook-form";
|
|
7
7
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
8
8
|
import { z } from "zod";
|
|
9
|
-
import {
|
|
9
|
+
import { useAuthActions } from "../../../hooks/useAuth.js";
|
|
10
|
+
import { safeCallbackPath } from "../../../lib/auth/callback-url.js";
|
|
10
11
|
import { useLastAuthMethod } from "../../../hooks/useLastAuthMethod.js";
|
|
11
12
|
import { Button } from "../../ui/button.js";
|
|
12
13
|
import { Input } from "../../ui/input.js";
|
|
@@ -24,6 +25,7 @@ import { AuthTranslationPreloader } from "../../../lib/i18n/AuthTranslationPrelo
|
|
|
24
25
|
import { DevKeyring } from "../DevKeyring.js";
|
|
25
26
|
import { DEV_CONFIG, PUBLIC_AUTH_CONFIG } from "../../../lib/config/config-sync.js";
|
|
26
27
|
import { getPrimaryEmailMethod } from "../../../lib/auth/auth-methods.js";
|
|
28
|
+
import { DEFAULT_OTP_CONFIG, formatOtpCountdown, getOtpSecondsRemaining } from "../../../lib/auth/otp-config.js";
|
|
27
29
|
function getErrorMessageFromCode(error, t, context) {
|
|
28
30
|
const authError = error;
|
|
29
31
|
const errorCode = authError.code || getErrorCodeFromMessage(error.message);
|
|
@@ -94,13 +96,15 @@ function buildLoginSchema(t) {
|
|
|
94
96
|
password: z.string().min(6, t("login.errors.passwordTooShort", { defaultValue: "Password must be at least 6 characters" }))
|
|
95
97
|
});
|
|
96
98
|
}
|
|
97
|
-
const OTP_CODE_LENGTH = 6;
|
|
98
99
|
function buildOtpEmailSchema(t) {
|
|
99
100
|
return z.string().trim().email({ message: t("login.errors.invalidEmail", { defaultValue: "Invalid email" }) });
|
|
100
101
|
}
|
|
101
|
-
function buildOtpCodeSchema(t) {
|
|
102
|
-
return z.string().trim().regex(new RegExp(`^\\d{${
|
|
103
|
-
message: t("login.errors.otpInvalidCode", {
|
|
102
|
+
function buildOtpCodeSchema(t, length) {
|
|
103
|
+
return z.string().trim().regex(new RegExp(`^\\d{${length}}$`), {
|
|
104
|
+
message: t("login.errors.otpInvalidCode", {
|
|
105
|
+
length,
|
|
106
|
+
defaultValue: `Enter the ${length}-digit code`
|
|
107
|
+
})
|
|
104
108
|
});
|
|
105
109
|
}
|
|
106
110
|
function LoginForm() {
|
|
@@ -109,6 +113,9 @@ function LoginForm() {
|
|
|
109
113
|
const googleEnabled = PUBLIC_AUTH_CONFIG.providers.google.enabled;
|
|
110
114
|
const methods = PUBLIC_AUTH_CONFIG.methods;
|
|
111
115
|
const otpEnabled = methods.includes("email-otp");
|
|
116
|
+
const otpConfig = PUBLIC_AUTH_CONFIG.otp ?? DEFAULT_OTP_CONFIG;
|
|
117
|
+
const otpLength = otpConfig.otpLength;
|
|
118
|
+
const otpExpiresIn = otpConfig.expiresIn;
|
|
112
119
|
const devKeyringActive = process.env.NODE_ENV !== "production" && !!((_b = (_a = DEV_CONFIG) == null ? void 0 : _a.devKeyring) == null ? void 0 : _b.enabled);
|
|
113
120
|
const passwordEnabled = methods.includes("email-password") || devKeyringActive;
|
|
114
121
|
const signupVisible = (registrationMode === "open" || registrationMode === "domain-open") && methods.includes("email-password");
|
|
@@ -129,23 +136,36 @@ function LoginForm() {
|
|
|
129
136
|
const [otpCode, setOtpCode] = useState("");
|
|
130
137
|
const [otpEmailError, setOtpEmailError] = useState(null);
|
|
131
138
|
const [otpCodeError, setOtpCodeError] = useState(null);
|
|
139
|
+
const [otpSentAt, setOtpSentAt] = useState(null);
|
|
140
|
+
const [otpSecondsLeft, setOtpSecondsLeft] = useState(otpExpiresIn);
|
|
132
141
|
const isProcessingRef = useRef(false);
|
|
133
|
-
const { signIn, googleSignIn, sendOtp, signInWithOtp } =
|
|
142
|
+
const { signIn, googleSignIn, sendOtp, signInWithOtp } = useAuthActions();
|
|
134
143
|
const { lastMethod, isReady } = useLastAuthMethod();
|
|
135
144
|
const t = useTranslations("auth");
|
|
136
145
|
const loginSchema = useMemo(() => buildLoginSchema(t), [t]);
|
|
137
146
|
const otpEmailSchema = useMemo(() => buildOtpEmailSchema(t), [t]);
|
|
138
|
-
const otpCodeSchema = useMemo(() => buildOtpCodeSchema(t), [t]);
|
|
147
|
+
const otpCodeSchema = useMemo(() => buildOtpCodeSchema(t, otpLength), [t, otpLength]);
|
|
139
148
|
const searchParams = useSearchParams();
|
|
140
149
|
const inviteEmail = searchParams.get("email");
|
|
141
150
|
const fromInvite = searchParams.get("fromInvite") === "true";
|
|
142
|
-
const callbackUrl = searchParams.get("callbackUrl");
|
|
151
|
+
const callbackUrl = safeCallbackPath(searchParams.get("callbackUrl"));
|
|
143
152
|
useEffect(() => {
|
|
144
153
|
if (fromInvite && inviteEmail) {
|
|
145
154
|
setShowEmailForm(true);
|
|
146
155
|
setOtpEmail(inviteEmail);
|
|
147
156
|
}
|
|
148
157
|
}, [fromInvite, inviteEmail]);
|
|
158
|
+
useEffect(() => {
|
|
159
|
+
if (otpSentAt === null) return;
|
|
160
|
+
const tick = () => {
|
|
161
|
+
const remaining = getOtpSecondsRemaining(otpSentAt, otpExpiresIn);
|
|
162
|
+
setOtpSecondsLeft(remaining);
|
|
163
|
+
if (remaining <= 0) clearInterval(intervalId);
|
|
164
|
+
};
|
|
165
|
+
const intervalId = setInterval(tick, 1e3);
|
|
166
|
+
tick();
|
|
167
|
+
return () => clearInterval(intervalId);
|
|
168
|
+
}, [otpSentAt, otpExpiresIn]);
|
|
149
169
|
const switchEmailMode = useCallback((mode) => {
|
|
150
170
|
setEmailMode(mode);
|
|
151
171
|
setError(null);
|
|
@@ -153,6 +173,7 @@ function LoginForm() {
|
|
|
153
173
|
setOtpCodeError(null);
|
|
154
174
|
setOtpStep("email");
|
|
155
175
|
setOtpCode("");
|
|
176
|
+
setOtpSentAt(null);
|
|
156
177
|
}, []);
|
|
157
178
|
const handleSendOtp = useCallback(async (event) => {
|
|
158
179
|
var _a2;
|
|
@@ -168,11 +189,14 @@ function LoginForm() {
|
|
|
168
189
|
setError(null);
|
|
169
190
|
setLoadingProvider("email");
|
|
170
191
|
setStatusMessage(t("login.messages.otpSending"));
|
|
192
|
+
const sentAt = Date.now();
|
|
171
193
|
try {
|
|
172
194
|
await sendOtp(parsed.data);
|
|
173
195
|
setOtpEmail(parsed.data);
|
|
174
196
|
setOtpCode("");
|
|
175
197
|
setOtpStep("code");
|
|
198
|
+
setOtpSentAt(sentAt);
|
|
199
|
+
setOtpSecondsLeft(getOtpSecondsRemaining(sentAt, otpExpiresIn));
|
|
176
200
|
setStatusMessage(t("login.messages.otpSent"));
|
|
177
201
|
} catch (err) {
|
|
178
202
|
const error2 = err instanceof Error ? err : new Error(t("login.messages.otpSendFailed"));
|
|
@@ -182,7 +206,7 @@ function LoginForm() {
|
|
|
182
206
|
} finally {
|
|
183
207
|
setLoadingProvider(null);
|
|
184
208
|
}
|
|
185
|
-
}, [loadingProvider, otpEmail, otpEmailSchema, sendOtp, t]);
|
|
209
|
+
}, [loadingProvider, otpEmail, otpEmailSchema, otpExpiresIn, sendOtp, t]);
|
|
186
210
|
const handleVerifyOtp = useCallback(async (event) => {
|
|
187
211
|
var _a2;
|
|
188
212
|
event == null ? void 0 : event.preventDefault();
|
|
@@ -414,7 +438,20 @@ function LoginForm() {
|
|
|
414
438
|
] }) : /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
415
439
|
/* @__PURE__ */ jsxs(Alert, { "data-cy": sel("auth.login.otpSentNotice"), children: [
|
|
416
440
|
/* @__PURE__ */ jsx(Mail, { className: "h-4 w-4", "aria-hidden": "true" }),
|
|
417
|
-
/* @__PURE__ */
|
|
441
|
+
/* @__PURE__ */ jsxs(AlertDescription, { children: [
|
|
442
|
+
t("login.form.otp.codeSent", { email: otpEmail, length: otpLength }),
|
|
443
|
+
" ",
|
|
444
|
+
/* @__PURE__ */ jsx(
|
|
445
|
+
"span",
|
|
446
|
+
{
|
|
447
|
+
"data-cy": sel("auth.login.otpCountdown"),
|
|
448
|
+
"aria-live": otpSecondsLeft > 0 ? "off" : "polite",
|
|
449
|
+
children: otpSecondsLeft > 0 ? t("login.form.otp.expiresIn", {
|
|
450
|
+
time: formatOtpCountdown(otpSecondsLeft)
|
|
451
|
+
}) : t("login.form.otp.expired")
|
|
452
|
+
}
|
|
453
|
+
)
|
|
454
|
+
] })
|
|
418
455
|
] }),
|
|
419
456
|
/* @__PURE__ */ jsx(Label, { htmlFor: "otp-code", children: t("login.form.otp.codeLabel") }),
|
|
420
457
|
/* @__PURE__ */ jsxs("div", { className: "relative", children: [
|
|
@@ -427,9 +464,9 @@ function LoginForm() {
|
|
|
427
464
|
inputMode: "numeric",
|
|
428
465
|
autoComplete: "one-time-code",
|
|
429
466
|
pattern: "[0-9]*",
|
|
430
|
-
maxLength:
|
|
467
|
+
maxLength: otpLength,
|
|
431
468
|
value: otpCode,
|
|
432
|
-
onChange: (e) => setOtpCode(e.target.value.replace(/\D/g, "").slice(0,
|
|
469
|
+
onChange: (e) => setOtpCode(e.target.value.replace(/\D/g, "").slice(0, otpLength)),
|
|
433
470
|
placeholder: t("login.form.otp.codePlaceholder"),
|
|
434
471
|
className: "pl-9 tracking-widest",
|
|
435
472
|
autoFocus: true,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"SignupForm.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/forms/SignupForm.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"SignupForm.d.ts","sourceRoot":"","sources":["../../../../src/components/auth/forms/SignupForm.tsx"],"names":[],"mappings":"AA8BA,wBAAgB,UAAU,4CAmgBzB"}
|
|
@@ -5,7 +5,8 @@ import Link from "next/link";
|
|
|
5
5
|
import { useSearchParams, useRouter } from "next/navigation";
|
|
6
6
|
import { useForm } from "react-hook-form";
|
|
7
7
|
import { zodResolver } from "@hookform/resolvers/zod";
|
|
8
|
-
import {
|
|
8
|
+
import { useAuthActions } from "../../../hooks/useAuth.js";
|
|
9
|
+
import { safeCallbackPath } from "../../../lib/auth/callback-url.js";
|
|
9
10
|
import { Button } from "../../ui/button.js";
|
|
10
11
|
import { Input } from "../../ui/input.js";
|
|
11
12
|
import { Label } from "../../ui/label.js";
|
|
@@ -30,12 +31,12 @@ function SignupForm() {
|
|
|
30
31
|
const [registeredEmail, setRegisteredEmail] = useState("");
|
|
31
32
|
const [resendingEmail, setResendingEmail] = useState(false);
|
|
32
33
|
const [statusMessage, setStatusMessage] = useState("");
|
|
33
|
-
const { signUp, googleSignIn, resendVerificationEmail } =
|
|
34
|
+
const { signUp, googleSignIn, resendVerificationEmail } = useAuthActions();
|
|
34
35
|
const t = useTranslations("auth");
|
|
35
36
|
const searchParams = useSearchParams();
|
|
36
37
|
const inviteEmail = searchParams.get("email");
|
|
37
38
|
const fromInvite = searchParams.get("fromInvite") === "true";
|
|
38
|
-
const callbackUrl = searchParams.get("callbackUrl");
|
|
39
|
+
const callbackUrl = safeCallbackPath(searchParams.get("callbackUrl"));
|
|
39
40
|
const inviteToken = searchParams.get("inviteToken");
|
|
40
41
|
const {
|
|
41
42
|
register,
|
|
@@ -10,7 +10,7 @@ import { cn } from "../../../lib/utils/index.js";
|
|
|
10
10
|
import { sel } from "../../../lib/test/index.js";
|
|
11
11
|
import { DynamicForm } from "./dynamic-form.js";
|
|
12
12
|
import { isPatternReference } from "../../../types/pattern-reference.js";
|
|
13
|
-
import { BLOCK_REGISTRY } from "@nextsparkjs/registries/block-registry";
|
|
13
|
+
import { BLOCK_REGISTRY } from "@nextsparkjs/registries/block-registry.client";
|
|
14
14
|
function groupFieldsByTab(fields) {
|
|
15
15
|
const grouped = {
|
|
16
16
|
content: [],
|
|
@@ -5,7 +5,7 @@ import { useTranslations } from "next-intl";
|
|
|
5
5
|
import { Button } from "../../ui/button.js";
|
|
6
6
|
import { cn } from "../../../lib/utils/index.js";
|
|
7
7
|
import { sel } from "../../../lib/test/index.js";
|
|
8
|
-
import { BLOCK_REGISTRY } from "@nextsparkjs/registries/block-registry";
|
|
8
|
+
import { BLOCK_REGISTRY } from "@nextsparkjs/registries/block-registry.client";
|
|
9
9
|
function FloatingBlockToolbar({
|
|
10
10
|
blockId,
|
|
11
11
|
blockSlug,
|
|
@@ -7,7 +7,7 @@ import { Button } from "../../ui/button.js";
|
|
|
7
7
|
import { Card, CardContent } from "../../ui/card.js";
|
|
8
8
|
import { Badge } from "../../ui/badge.js";
|
|
9
9
|
import { GripVertical, Copy, Trash2 } from "lucide-react";
|
|
10
|
-
import { BLOCK_REGISTRY } from "@nextsparkjs/registries/block-registry";
|
|
10
|
+
import { BLOCK_REGISTRY } from "@nextsparkjs/registries/block-registry.client";
|
|
11
11
|
import { cn } from "../../../lib/utils/index.js";
|
|
12
12
|
import { sel } from "../../../lib/test/index.js";
|
|
13
13
|
function SortableBlock({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/layouts/Sidebar.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Sidebar.d.ts","sourceRoot":"","sources":["../../../../src/components/dashboard/layouts/Sidebar.tsx"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,qCAAqC,CAAA;AAGnF,UAAU,YAAY;IACpB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,QAAQ,EAAE,wBAAwB,EAAE,CAAA;CACrC;AAED,wBAAgB,OAAO,CAAC,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,YAAY,2CAuG5D"}
|