@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.
Files changed (414) hide show
  1. package/dist/components/api/keys/ApiKeyDisplay.js +19 -19
  2. package/dist/components/api/keys/CreateApiKeyDialog.js +21 -21
  3. package/dist/components/app/layouts/PublicNavbar.d.ts.map +1 -1
  4. package/dist/components/app/layouts/PublicNavbar.js +34 -16
  5. package/dist/components/app/misc/ThemeToggle.d.ts.map +1 -1
  6. package/dist/components/app/misc/ThemeToggle.js +3 -4
  7. package/dist/components/auth/SessionCookieRefresher.d.ts +5 -0
  8. package/dist/components/auth/SessionCookieRefresher.d.ts.map +1 -1
  9. package/dist/components/auth/SessionCookieRefresher.js +7 -1
  10. package/dist/components/auth/forms/LoginForm.d.ts.map +1 -1
  11. package/dist/components/auth/forms/LoginForm.js +49 -12
  12. package/dist/components/auth/forms/SignupForm.d.ts.map +1 -1
  13. package/dist/components/auth/forms/SignupForm.js +4 -3
  14. package/dist/components/dashboard/block-editor/block-settings-panel.js +1 -1
  15. package/dist/components/dashboard/block-editor/floating-block-toolbar.js +1 -1
  16. package/dist/components/dashboard/block-editor/sortable-block.js +1 -1
  17. package/dist/components/dashboard/layouts/Sidebar.d.ts.map +1 -1
  18. package/dist/components/dashboard/layouts/Sidebar.js +8 -6
  19. package/dist/components/dashboard/layouts/TopNavbar.d.ts.map +1 -1
  20. package/dist/components/dashboard/layouts/TopNavbar.js +51 -54
  21. package/dist/components/dashboard/misc/NotificationsDropdown.d.ts.map +1 -1
  22. package/dist/components/dashboard/misc/NotificationsDropdown.js +17 -15
  23. package/dist/components/dashboard/misc/SearchDropdown.d.ts.map +1 -1
  24. package/dist/components/dashboard/misc/SearchDropdown.js +19 -22
  25. package/dist/components/dashboard/mobile/MobileBottomNav.js +1 -1
  26. package/dist/components/dashboard/mobile/MobileTopBar.d.ts +10 -1
  27. package/dist/components/dashboard/mobile/MobileTopBar.d.ts.map +1 -1
  28. package/dist/components/dashboard/mobile/MobileTopBar.js +4 -3
  29. package/dist/components/dashboard/navigation/DynamicNavigation.js +5 -5
  30. package/dist/components/devtools/BlockDetailViewer.js +1 -1
  31. package/dist/components/devtools/BlocksViewer.js +1 -1
  32. package/dist/components/entities/EntityChildManager.js +5 -5
  33. package/dist/components/entities/EntityDetailPage.d.ts.map +1 -1
  34. package/dist/components/entities/EntityDetailPage.js +16 -15
  35. package/dist/components/entities/EntityFieldRenderer.d.ts.map +1 -1
  36. package/dist/components/entities/EntityFieldRenderer.js +12 -7
  37. package/dist/components/entities/EntityPageHeader.js +5 -5
  38. package/dist/components/entities/ErrorBoundary.d.ts.map +1 -1
  39. package/dist/components/entities/ErrorBoundary.js +20 -21
  40. package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -5
  41. package/dist/components/entities/wrappers/EntityFormWrapper.js +2 -2
  42. package/dist/components/entities/wrappers/EntityListWrapper.js +3 -3
  43. package/dist/components/permissions/NoPermission.js +10 -10
  44. package/dist/components/public/pageBuilder/PageRenderer.d.ts.map +1 -1
  45. package/dist/components/public/pageBuilder/PageRenderer.js +2 -1
  46. package/dist/components/settings/SettingsPageSkeleton.js +4 -4
  47. package/dist/components/settings/layouts/SettingsSidebar.js +6 -6
  48. package/dist/components/shared/MultiSelectFilter.d.ts +3 -1
  49. package/dist/components/shared/MultiSelectFilter.d.ts.map +1 -1
  50. package/dist/components/shared/MultiSelectFilter.js +7 -3
  51. package/dist/components/shared/SearchInput.d.ts +2 -0
  52. package/dist/components/shared/SearchInput.d.ts.map +1 -1
  53. package/dist/components/shared/SearchInput.js +64 -6
  54. package/dist/components/ui/address-input.js +18 -18
  55. package/dist/components/ui/audio-upload.js +9 -9
  56. package/dist/components/ui/combobox.d.ts.map +1 -1
  57. package/dist/components/ui/combobox.js +4 -4
  58. package/dist/components/ui/country-select.d.ts.map +1 -1
  59. package/dist/components/ui/country-select.js +3 -3
  60. package/dist/components/ui/currency-select.d.ts.map +1 -1
  61. package/dist/components/ui/currency-select.js +3 -3
  62. package/dist/components/ui/dynamic-icon.d.ts.map +1 -1
  63. package/dist/components/ui/dynamic-icon.js +3 -2
  64. package/dist/components/ui/file-upload.js +7 -7
  65. package/dist/components/ui/image-upload.js +8 -8
  66. package/dist/components/ui/multi-select.d.ts +2 -1
  67. package/dist/components/ui/multi-select.d.ts.map +1 -1
  68. package/dist/components/ui/multi-select.js +4 -3
  69. package/dist/components/ui/phone-input.d.ts.map +1 -1
  70. package/dist/components/ui/phone-input.js +3 -3
  71. package/dist/components/ui/relation-display.js +1 -1
  72. package/dist/components/ui/simple-relation-select.d.ts +2 -1
  73. package/dist/components/ui/simple-relation-select.d.ts.map +1 -1
  74. package/dist/components/ui/simple-relation-select.js +7 -6
  75. package/dist/components/ui/tags-input.d.ts.map +1 -1
  76. package/dist/components/ui/tags-input.js +1 -1
  77. package/dist/components/ui/timezone-select.d.ts.map +1 -1
  78. package/dist/components/ui/timezone-select.js +3 -3
  79. package/dist/components/ui/user-display.js +4 -4
  80. package/dist/components/ui/user-select.d.ts.map +1 -1
  81. package/dist/components/ui/user-select.js +9 -9
  82. package/dist/components/ui/video-upload.js +9 -9
  83. package/dist/contexts/SubscriptionContext.d.ts.map +1 -1
  84. package/dist/contexts/SubscriptionContext.js +5 -1
  85. package/dist/contexts/TeamContext.d.ts.map +1 -1
  86. package/dist/contexts/TeamContext.js +83 -26
  87. package/dist/emails/otp-verification.d.ts.map +1 -1
  88. package/dist/emails/otp-verification.js +3 -2
  89. package/dist/hooks/useAccountPreferencesSync.d.ts +13 -0
  90. package/dist/hooks/useAccountPreferencesSync.d.ts.map +1 -0
  91. package/dist/hooks/useAccountPreferencesSync.js +95 -0
  92. package/dist/hooks/useAuth.d.ts +202 -15
  93. package/dist/hooks/useAuth.d.ts.map +1 -1
  94. package/dist/hooks/useAuth.js +49 -13
  95. package/dist/hooks/useEntityConfig.js +2 -2
  96. package/dist/hooks/useEntitySearch.js +10 -10
  97. package/dist/hooks/useNotifications.js +12 -12
  98. package/dist/hooks/usePrefetch.d.ts.map +1 -1
  99. package/dist/hooks/usePrefetch.js +6 -2
  100. package/dist/hooks/useSearch.js +15 -15
  101. package/dist/hooks/useSessionCookieRefresh.d.ts +18 -1
  102. package/dist/hooks/useSessionCookieRefresh.d.ts.map +1 -1
  103. package/dist/hooks/useSessionCookieRefresh.js +17 -4
  104. package/dist/hooks/useSessionHint.d.ts +12 -0
  105. package/dist/hooks/useSessionHint.d.ts.map +1 -0
  106. package/dist/hooks/useSessionHint.js +15 -0
  107. package/dist/hooks/useTranslationPreload.js +6 -6
  108. package/dist/i18n.d.ts +13 -0
  109. package/dist/i18n.d.ts.map +1 -1
  110. package/dist/i18n.js +2 -27
  111. package/dist/lib/actions/entity.actions.d.ts.map +1 -1
  112. package/dist/lib/actions/entity.actions.js +3 -2
  113. package/dist/lib/api/auth/dual-auth.d.ts +4 -1
  114. package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
  115. package/dist/lib/api/auth/dual-auth.js +5 -16
  116. package/dist/lib/api/entities.js +33 -33
  117. package/dist/lib/api/keys.d.ts +27 -27
  118. package/dist/lib/api/keys.js +27 -27
  119. package/dist/lib/auth/callback-url.d.ts +11 -0
  120. package/dist/lib/auth/callback-url.d.ts.map +1 -0
  121. package/dist/lib/auth/callback-url.js +14 -0
  122. package/dist/lib/auth/otp-config.d.ts +55 -0
  123. package/dist/lib/auth/otp-config.d.ts.map +1 -0
  124. package/dist/lib/auth/otp-config.js +48 -0
  125. package/dist/lib/auth/registration-helpers.d.ts.map +1 -1
  126. package/dist/lib/auth/registration-helpers.js +3 -1
  127. package/dist/lib/auth/session-hint.d.ts +31 -0
  128. package/dist/lib/auth/session-hint.d.ts.map +1 -0
  129. package/dist/lib/auth/session-hint.js +37 -0
  130. package/dist/lib/auth.d.ts.map +1 -1
  131. package/dist/lib/auth.js +6 -4
  132. package/dist/lib/blocks/loader.d.ts +3 -11
  133. package/dist/lib/blocks/loader.d.ts.map +1 -1
  134. package/dist/lib/blocks/loader.js +1 -9
  135. package/dist/lib/blocks/loader.server.d.ts +18 -0
  136. package/dist/lib/blocks/loader.server.d.ts.map +1 -0
  137. package/dist/lib/blocks/loader.server.js +11 -0
  138. package/dist/lib/blocks/sanitize-html.d.ts +31 -0
  139. package/dist/lib/blocks/sanitize-html.d.ts.map +1 -0
  140. package/dist/lib/blocks/sanitize-html.js +60 -0
  141. package/dist/lib/config/config-sync.d.ts +1 -0
  142. package/dist/lib/config/config-sync.d.ts.map +1 -1
  143. package/dist/lib/config/config-sync.js +4 -1
  144. package/dist/lib/config/types.d.ts +48 -0
  145. package/dist/lib/config/types.d.ts.map +1 -1
  146. package/dist/lib/email/types.d.ts +6 -0
  147. package/dist/lib/email/types.d.ts.map +1 -1
  148. package/dist/lib/entities/serialization.d.ts.map +1 -1
  149. package/dist/lib/entities/serialization.js +3 -6
  150. package/dist/lib/icons.d.ts +12 -0
  151. package/dist/lib/icons.d.ts.map +1 -0
  152. package/dist/lib/icons.js +30 -0
  153. package/dist/lib/locale.d.ts +25 -1
  154. package/dist/lib/locale.d.ts.map +1 -1
  155. package/dist/lib/locale.js +49 -35
  156. package/dist/lib/mcp/engine.js +1 -1
  157. package/dist/lib/mcp/errors.js +17 -17
  158. package/dist/lib/mcp/schema-builder.js +16 -16
  159. package/dist/lib/mcp/tool-generator.js +18 -18
  160. package/dist/lib/search-highlighting.d.ts +7 -0
  161. package/dist/lib/search-highlighting.d.ts.map +1 -1
  162. package/dist/lib/search-highlighting.js +6 -2
  163. package/dist/lib/selectors/core-selectors.d.ts +2 -0
  164. package/dist/lib/selectors/core-selectors.d.ts.map +1 -1
  165. package/dist/lib/selectors/domains/auth.selectors.d.ts +1 -0
  166. package/dist/lib/selectors/domains/auth.selectors.d.ts.map +1 -1
  167. package/dist/lib/selectors/domains/auth.selectors.js +1 -0
  168. package/dist/lib/selectors/domains/entities.selectors.d.ts +2 -0
  169. package/dist/lib/selectors/domains/entities.selectors.d.ts.map +1 -1
  170. package/dist/lib/selectors/domains/entities.selectors.js +2 -0
  171. package/dist/lib/selectors/selectors.d.ts +4 -0
  172. package/dist/lib/selectors/selectors.d.ts.map +1 -1
  173. package/dist/lib/services/block.service.js +1 -1
  174. package/dist/lib/teams/active-team-cookie.d.ts +24 -0
  175. package/dist/lib/teams/active-team-cookie.d.ts.map +1 -0
  176. package/dist/lib/teams/active-team-cookie.js +17 -0
  177. package/dist/lib/teams/dashboard-team.d.ts +20 -0
  178. package/dist/lib/teams/dashboard-team.d.ts.map +1 -0
  179. package/dist/lib/teams/dashboard-team.js +38 -0
  180. package/dist/lib/teams/schema.d.ts.map +1 -1
  181. package/dist/lib/teams/schema.js +1 -1
  182. package/dist/lib/template-resolver.d.ts.map +1 -1
  183. package/dist/lib/template-resolver.js +0 -1
  184. package/dist/lib/theme/get-default-theme-mode.d.ts +7 -4
  185. package/dist/lib/theme/get-default-theme-mode.d.ts.map +1 -1
  186. package/dist/lib/theme/get-default-theme-mode.js +2 -44
  187. package/dist/messages/de/auth.json +4 -2
  188. package/dist/messages/de/common.json +83 -3
  189. package/dist/messages/de/email.json +1 -1
  190. package/dist/messages/de/index.d.ts +87 -0
  191. package/dist/messages/de/index.d.ts.map +1 -1
  192. package/dist/messages/de/settings.json +5 -0
  193. package/dist/messages/en/auth.json +4 -2
  194. package/dist/messages/en/common.json +83 -3
  195. package/dist/messages/en/email.json +1 -1
  196. package/dist/messages/en/index.d.ts +86 -0
  197. package/dist/messages/en/index.d.ts.map +1 -1
  198. package/dist/messages/en/settings.json +4 -0
  199. package/dist/messages/es/auth.json +4 -2
  200. package/dist/messages/es/common.json +83 -3
  201. package/dist/messages/es/email.json +1 -1
  202. package/dist/messages/es/index.d.ts +86 -0
  203. package/dist/messages/es/index.d.ts.map +1 -1
  204. package/dist/messages/es/settings.json +4 -0
  205. package/dist/messages/fr/auth.json +4 -2
  206. package/dist/messages/fr/common.json +83 -3
  207. package/dist/messages/fr/email.json +1 -1
  208. package/dist/messages/fr/index.d.ts +87 -0
  209. package/dist/messages/fr/index.d.ts.map +1 -1
  210. package/dist/messages/fr/settings.json +5 -0
  211. package/dist/messages/it/auth.json +4 -2
  212. package/dist/messages/it/common.json +83 -3
  213. package/dist/messages/it/email.json +1 -1
  214. package/dist/messages/it/index.d.ts +87 -0
  215. package/dist/messages/it/index.d.ts.map +1 -1
  216. package/dist/messages/it/settings.json +5 -0
  217. package/dist/messages/pt/auth.json +4 -2
  218. package/dist/messages/pt/common.json +83 -3
  219. package/dist/messages/pt/email.json +1 -1
  220. package/dist/messages/pt/index.d.ts +87 -0
  221. package/dist/messages/pt/index.d.ts.map +1 -1
  222. package/dist/messages/pt/settings.json +5 -0
  223. package/dist/nextspark-registries.d.ts +54 -0
  224. package/dist/providers/DashboardProviders.d.ts +13 -10
  225. package/dist/providers/DashboardProviders.d.ts.map +1 -1
  226. package/dist/providers/DashboardProviders.js +7 -1
  227. package/dist/templates/app/(auth)/forgot-password/page.tsx +2 -2
  228. package/dist/templates/app/(auth)/reset-password/page.tsx +6 -6
  229. package/dist/templates/app/403/page.tsx +6 -6
  230. package/dist/templates/app/api/v1/teams/switch/route.ts +24 -5
  231. package/dist/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
  232. package/dist/templates/app/dashboard/(main)/layout.tsx +4 -3
  233. package/dist/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
  234. package/dist/templates/app/dashboard/settings/profile/page.tsx +7 -6
  235. package/dist/templates/app/dashboard/settings/security/page.tsx +5 -4
  236. package/dist/templates/app/layout.ppr.tsx +8 -8
  237. package/dist/templates/app/layout.tsx +12 -17
  238. package/dist/templates/blocks/cta-section/component.tsx +5 -2
  239. package/dist/templates/blocks/cta-section/config.ts +3 -2
  240. package/dist/templates/blocks/cta-section/fields.ts +2 -2
  241. package/dist/templates/blocks/cta-section/schema.ts +2 -2
  242. package/dist/templates/blocks/features-grid/component.tsx +10 -2
  243. package/dist/templates/blocks/features-grid/config.ts +3 -2
  244. package/dist/templates/blocks/features-grid/fields.ts +2 -2
  245. package/dist/templates/blocks/features-grid/schema.ts +2 -2
  246. package/dist/templates/blocks/hero/component.tsx +6 -3
  247. package/dist/templates/blocks/hero/config.ts +3 -2
  248. package/dist/templates/blocks/hero/fields.ts +2 -2
  249. package/dist/templates/blocks/hero/schema.ts +2 -2
  250. package/dist/templates/blocks/testimonials/component.tsx +6 -3
  251. package/dist/templates/blocks/testimonials/config.ts +3 -2
  252. package/dist/templates/blocks/testimonials/fields.ts +2 -2
  253. package/dist/templates/blocks/testimonials/schema.ts +2 -2
  254. package/dist/templates/blocks/text-content/component.tsx +7 -3
  255. package/dist/templates/blocks/text-content/config.ts +3 -2
  256. package/dist/templates/blocks/text-content/fields.ts +2 -2
  257. package/dist/templates/blocks/text-content/schema.ts +2 -2
  258. package/dist/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
  259. package/dist/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
  260. package/dist/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
  261. package/dist/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
  262. package/dist/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
  263. package/dist/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
  264. package/dist/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
  265. package/dist/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
  266. package/dist/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
  267. package/dist/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
  268. package/dist/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
  269. package/dist/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
  270. package/dist/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
  271. package/dist/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
  272. package/dist/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
  273. package/dist/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
  274. package/dist/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
  275. package/dist/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
  276. package/dist/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
  277. package/dist/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
  278. package/dist/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
  279. package/dist/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
  280. package/dist/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
  281. package/dist/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
  282. package/dist/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
  283. package/dist/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
  284. package/dist/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
  285. package/dist/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
  286. package/dist/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
  287. package/dist/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
  288. package/dist/templates/contents/themes/starter/config/app.config.ts +8 -0
  289. package/dist/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
  290. package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
  291. package/dist/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
  292. package/dist/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
  293. package/dist/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
  294. package/dist/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
  295. package/dist/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
  296. package/dist/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
  297. package/dist/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
  298. package/dist/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
  299. package/dist/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
  300. package/dist/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
  301. package/dist/templates/features/blog/blocks/post-content/component.tsx +5 -1
  302. package/dist/templates/features/blog/blocks/post-content/schema.ts +1 -1
  303. package/dist/templates/features/pages/blocks/hero/component.tsx +3 -0
  304. package/dist/templates/features/pages/blocks/hero/schema.ts +1 -1
  305. package/dist/templates/proxy.ts +138 -53
  306. package/dist/types/blocks.d.ts.map +1 -1
  307. package/dist/types/blocks.js +1 -1
  308. package/dist/types/task.types.d.ts +1 -1
  309. package/dist/types/task.types.js +7 -7
  310. package/dist/utils/dev/TranslationDebugger.js +2 -2
  311. package/package.json +14 -5
  312. package/scripts/build/registry/__tests__/block-registry.test.mjs +73 -0
  313. package/scripts/build/registry/__tests__/icons-discovery.test.mjs +130 -0
  314. package/scripts/build/registry/__tests__/identifier.test.mjs +65 -0
  315. package/scripts/build/registry/__tests__/page-generator.test.mjs +430 -0
  316. package/scripts/build/registry/__tests__/scheduled-actions-registry.test.mjs +41 -0
  317. package/scripts/build/registry/__tests__/template-registry.test.mjs +89 -0
  318. package/scripts/build/registry/discovery/icons.mjs +275 -0
  319. package/scripts/build/registry/discovery/index.mjs +1 -0
  320. package/scripts/build/registry/generators/block-registry.mjs +203 -55
  321. package/scripts/build/registry/generators/feature-registry.mjs +9 -2
  322. package/scripts/build/registry/generators/icon-registry.mjs +56 -0
  323. package/scripts/build/registry/generators/identifier.mjs +28 -0
  324. package/scripts/build/registry/generators/index.mjs +1 -0
  325. package/scripts/build/registry/generators/plugin-registry.mjs +4 -3
  326. package/scripts/build/registry/generators/scheduled-actions-registry.mjs +4 -2
  327. package/scripts/build/registry/generators/template-registry.mjs +49 -41
  328. package/scripts/build/registry/generators/theme-registry.mjs +6 -7
  329. package/scripts/build/registry/post-build/page-generator.mjs +380 -59
  330. package/scripts/build/registry.mjs +9 -1
  331. package/templates/app/(auth)/forgot-password/page.tsx +2 -2
  332. package/templates/app/(auth)/reset-password/page.tsx +6 -6
  333. package/templates/app/403/page.tsx +6 -6
  334. package/templates/app/api/v1/teams/switch/route.ts +24 -5
  335. package/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
  336. package/templates/app/dashboard/(main)/layout.tsx +4 -3
  337. package/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
  338. package/templates/app/dashboard/settings/profile/page.tsx +7 -6
  339. package/templates/app/dashboard/settings/security/page.tsx +5 -4
  340. package/templates/app/layout.ppr.tsx +8 -8
  341. package/templates/app/layout.tsx +12 -17
  342. package/templates/blocks/cta-section/component.tsx +5 -2
  343. package/templates/blocks/cta-section/config.ts +3 -2
  344. package/templates/blocks/cta-section/fields.ts +2 -2
  345. package/templates/blocks/cta-section/schema.ts +2 -2
  346. package/templates/blocks/features-grid/component.tsx +10 -2
  347. package/templates/blocks/features-grid/config.ts +3 -2
  348. package/templates/blocks/features-grid/fields.ts +2 -2
  349. package/templates/blocks/features-grid/schema.ts +2 -2
  350. package/templates/blocks/hero/component.tsx +6 -3
  351. package/templates/blocks/hero/config.ts +3 -2
  352. package/templates/blocks/hero/fields.ts +2 -2
  353. package/templates/blocks/hero/schema.ts +2 -2
  354. package/templates/blocks/testimonials/component.tsx +6 -3
  355. package/templates/blocks/testimonials/config.ts +3 -2
  356. package/templates/blocks/testimonials/fields.ts +2 -2
  357. package/templates/blocks/testimonials/schema.ts +2 -2
  358. package/templates/blocks/text-content/component.tsx +7 -3
  359. package/templates/blocks/text-content/config.ts +3 -2
  360. package/templates/blocks/text-content/fields.ts +2 -2
  361. package/templates/blocks/text-content/schema.ts +2 -2
  362. package/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
  363. package/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
  364. package/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
  365. package/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
  366. package/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
  367. package/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
  368. package/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
  369. package/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
  370. package/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
  371. package/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
  372. package/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
  373. package/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
  374. package/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
  375. package/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
  376. package/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
  377. package/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
  378. package/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
  379. package/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
  380. package/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
  381. package/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
  382. package/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
  383. package/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
  384. package/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
  385. package/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
  386. package/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
  387. package/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
  388. package/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
  389. package/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
  390. package/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
  391. package/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
  392. package/templates/contents/themes/starter/config/app.config.ts +8 -0
  393. package/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
  394. package/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
  395. package/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
  396. package/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
  397. package/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
  398. package/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
  399. package/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
  400. package/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
  401. package/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
  402. package/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
  403. package/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
  404. package/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
  405. package/templates/features/blog/blocks/post-content/component.tsx +5 -1
  406. package/templates/features/blog/blocks/post-content/schema.ts +1 -1
  407. package/templates/features/pages/blocks/hero/component.tsx +3 -0
  408. package/templates/features/pages/blocks/hero/schema.ts +1 -1
  409. package/templates/proxy.ts +138 -53
  410. package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.client.ts +9 -0
  411. package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.lazy.ts +5 -0
  412. package/tests/jest/__mocks__/@nextsparkjs/registries/icon-registry.ts +42 -0
  413. package/tests/jest/__mocks__/next-intl-server.js +85 -5
  414. package/tests/jest/__mocks__/next-server.js +32 -0
@@ -0,0 +1,97 @@
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
+ * Features Grid 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
+ // Features-specific content fields
18
+ const featuresContentFields: FieldDefinition[] = [
19
+ {
20
+ name: 'items',
21
+ label: 'Features',
22
+ type: 'array',
23
+ tab: 'content',
24
+ required: true,
25
+ description: 'List of features to display in the grid',
26
+ helpText: 'Add up to 12 features with icon, title, and description',
27
+ minItems: 1,
28
+ maxItems: 12,
29
+ itemFields: [
30
+ {
31
+ name: 'icon',
32
+ label: 'Icon Name',
33
+ type: 'text',
34
+ tab: 'content',
35
+ required: true,
36
+ placeholder: 'Zap',
37
+ helpText: 'Lucide icon name (e.g., Zap, Shield, Star, Check)',
38
+ },
39
+ {
40
+ name: 'title',
41
+ label: 'Feature Title',
42
+ type: 'text',
43
+ tab: 'content',
44
+ required: true,
45
+ placeholder: 'Lightning Fast',
46
+ maxLength: 100,
47
+ },
48
+ {
49
+ name: 'description',
50
+ label: 'Description',
51
+ type: 'textarea',
52
+ tab: 'content',
53
+ required: true,
54
+ placeholder: 'Describe this feature...',
55
+ maxLength: 300,
56
+ rows: 2,
57
+ },
58
+ ],
59
+ },
60
+ ]
61
+
62
+ // Features-specific design fields
63
+ const featuresDesignFields: FieldDefinition[] = [
64
+ {
65
+ name: 'columns',
66
+ label: 'Grid Columns',
67
+ type: 'select',
68
+ tab: 'design',
69
+ required: false,
70
+ default: '3',
71
+ description: 'Number of columns in the grid layout',
72
+ options: [
73
+ { label: '2 Columns', value: '2' },
74
+ { label: '3 Columns', value: '3' },
75
+ { label: '4 Columns', value: '4' },
76
+ ],
77
+ },
78
+ ]
79
+
80
+ /**
81
+ * Complete field definitions organized by tab
82
+ */
83
+ export const fieldDefinitions: FieldDefinition[] = [
84
+ // Content tab: base fields + features-specific
85
+ ...baseContentFields,
86
+ ...featuresContentFields,
87
+
88
+ // Design tab: base fields + features-specific
89
+ ...baseDesignFields,
90
+ ...featuresDesignFields,
91
+
92
+ // Advanced tab: base fields only
93
+ ...baseAdvancedFields,
94
+ ]
95
+
96
+ // Alias for compatibility
97
+ export const fields = fieldDefinitions
@@ -0,0 +1,6 @@
1
+ export { config } from './config'
2
+ export { schema } from './schema'
3
+ export { fields } from './fields'
4
+ export { FeaturesGridBlock as Component } from './component'
5
+
6
+ export type { FeaturesGridBlockProps } from './schema'
@@ -0,0 +1,40 @@
1
+ import { z } from 'zod'
2
+ import { baseBlockSchema } from '@nextsparkjs/core/types/blocks'
3
+
4
+ /**
5
+ * Feature Item Schema
6
+ * Individual feature in the grid
7
+ */
8
+ const featureItemSchema = z.object({
9
+ icon: z.string().min(1, 'Icon name is required'),
10
+ title: z.string().min(1, 'Feature title is required').max(100),
11
+ description: z.string().min(1, 'Description is required').max(300),
12
+ })
13
+
14
+ export type FeatureItem = z.infer<typeof featureItemSchema>
15
+
16
+ /**
17
+ * Features Grid Block Schema
18
+ *
19
+ * Extends base schema with:
20
+ * - items: Array of feature items (icon, title, description)
21
+ * - columns: Grid layout option (2, 3, 4 columns)
22
+ *
23
+ * Note: Uses base schema title, description, cta, backgroundColor, className, id
24
+ */
25
+ export const featuresGridSpecificSchema = z.object({
26
+ // Content: array of feature items
27
+ items: z.array(featureItemSchema)
28
+ .min(1, 'At least one feature is required')
29
+ .max(12, 'Maximum 12 features allowed'),
30
+
31
+ // Design: column layout
32
+ columns: z.enum(['2', '3', '4']).default('3'),
33
+ })
34
+
35
+ /**
36
+ * Complete Features Grid Block Schema
37
+ */
38
+ export const schema = baseBlockSchema.extend(featuresGridSpecificSchema.shape)
39
+
40
+ export type FeaturesGridBlockProps = z.infer<typeof schema>
@@ -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,6 @@
1
+ export { config } from './config'
2
+ export { schema } from './schema'
3
+ export { fields } from './fields'
4
+ export { HeroBlock as Component } from './component'
5
+
6
+ export type { HeroBlockProps } from './schema'
@@ -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 }
@@ -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,6 @@
1
+ export { config } from './config'
2
+ export { schema } from './schema'
3
+ export { fields } from './fields'
4
+ export { TestimonialsBlock as Component } from './component'
5
+
6
+ export type { TestimonialsBlockProps } from './schema'
@@ -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>