@nextsparkjs/theme-default 0.1.0-beta.1 → 0.1.0-beta.101

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 (330) hide show
  1. package/LICENSE +21 -0
  2. package/api/ai/chat/stream/route.ts +4 -1
  3. package/api/ai/orchestrator/route.ts +10 -3
  4. package/api/ai/single-agent/route.ts +10 -3
  5. package/api/ai/usage/route.ts +4 -1
  6. package/blocks/benefits/component.tsx +4 -4
  7. package/blocks/cta-section/component.tsx +4 -4
  8. package/blocks/faq-accordion/component.tsx +2 -2
  9. package/blocks/features-grid/component.tsx +5 -5
  10. package/blocks/hero/component.tsx +2 -2
  11. package/blocks/hero/fields.ts +1 -1
  12. package/blocks/hero-with-form/component.tsx +7 -7
  13. package/blocks/hero-with-form/fields.ts +1 -1
  14. package/blocks/jumbotron/component.tsx +7 -7
  15. package/blocks/jumbotron/fields.ts +1 -1
  16. package/blocks/logo-cloud/component.tsx +6 -6
  17. package/blocks/logo-cloud/fields.ts +1 -1
  18. package/blocks/post-content/component.tsx +2 -2
  19. package/blocks/pricing-table/component.tsx +5 -5
  20. package/blocks/split-content/component.tsx +5 -5
  21. package/blocks/split-content/fields.ts +1 -1
  22. package/blocks/stats-counter/component.tsx +9 -9
  23. package/blocks/testimonials/component.tsx +4 -4
  24. package/blocks/testimonials/fields.ts +1 -1
  25. package/blocks/text-content/component.tsx +12 -10
  26. package/blocks/timeline/component.tsx +12 -12
  27. package/blocks/video-hero/component.tsx +7 -7
  28. package/blocks/video-hero/fields.ts +1 -1
  29. package/components/ai-chat/ChatPanel.tsx +7 -7
  30. package/components/ai-chat/Message.tsx +2 -2
  31. package/components/ai-chat/MessageInput.tsx +3 -3
  32. package/components/ai-chat/MessageList.tsx +3 -3
  33. package/components/ai-chat/TypingIndicator.tsx +2 -2
  34. package/config/app.config.ts +75 -62
  35. package/config/dashboard.config.ts +14 -0
  36. package/config/features.config.ts +10 -0
  37. package/config/permissions.config.ts +26 -1
  38. package/docs/{01-overview → public/01-overview}/01-introduction.md +5 -0
  39. package/docs/{01-overview → public/01-overview}/02-customization.md +5 -0
  40. package/docs/{02-features → public/02-features}/03-tasks-entity.md +5 -0
  41. package/docs/{03-ai → public/03-ai}/01-overview.md +5 -0
  42. package/docs/{03-ai → public/03-ai}/02-customization.md +5 -0
  43. package/docs/superadmin/01-setup/01-configuration.md +79 -0
  44. package/docs/superadmin/01-setup/02-deployment.md +82 -0
  45. package/docs/superadmin/02-management/01-users.md +83 -0
  46. package/docs/superadmin/03-integrations/01-langchain.md +139 -0
  47. package/entities/customers/api/docs.md +107 -0
  48. package/entities/customers/api/presets.ts +80 -0
  49. package/entities/pages/api/docs.md +114 -0
  50. package/entities/pages/api/presets.ts +72 -0
  51. package/entities/posts/api/docs.md +120 -0
  52. package/entities/posts/api/presets.ts +74 -0
  53. package/entities/tasks/api/docs.md +126 -0
  54. package/entities/tasks/api/presets.ts +84 -0
  55. package/lib/selectors.ts +7 -4
  56. package/messages/de/admin.json +45 -0
  57. package/messages/en/admin.json +56 -0
  58. package/messages/en/navigation.json +2 -1
  59. package/messages/es/admin.json +56 -0
  60. package/messages/es/navigation.json +2 -1
  61. package/messages/fr/admin.json +45 -0
  62. package/messages/it/admin.json +45 -0
  63. package/messages/pt/admin.json +45 -0
  64. package/migrations/090_demo_users_teams.sql +11 -11
  65. package/migrations/091_greek_teams_billing.sql +15 -15
  66. package/migrations/093_pages_sample_data.sql +7 -7
  67. package/migrations/098_patterns_sample_data.sql +234 -0
  68. package/package.json +8 -3
  69. package/styles/globals.css +42 -0
  70. package/templates/(public)/blog/[slug]/page.tsx +1 -1
  71. package/templates/(public)/page.tsx +1 -1
  72. package/tests/cypress/e2e/_utils/devtools/access.bdd.md +262 -0
  73. package/tests/cypress/e2e/_utils/devtools/access.cy.ts +171 -0
  74. package/tests/cypress/e2e/_utils/devtools/navigation.bdd.md +261 -0
  75. package/tests/cypress/e2e/_utils/devtools/navigation.cy.ts +157 -0
  76. package/tests/cypress/e2e/_utils/devtools/pages.bdd.md +303 -0
  77. package/tests/cypress/e2e/_utils/devtools/pages.cy.ts +184 -0
  78. package/tests/cypress/e2e/_utils/docs/README.md +215 -0
  79. package/tests/cypress/e2e/_utils/selectors/auth.bdd.md +354 -0
  80. package/tests/cypress/e2e/_utils/selectors/auth.cy.ts +310 -0
  81. package/tests/cypress/e2e/_utils/selectors/billing.bdd.md +276 -0
  82. package/tests/cypress/e2e/_utils/selectors/billing.cy.ts +182 -0
  83. package/tests/cypress/e2e/_utils/selectors/block-editor.bdd.md +615 -0
  84. package/tests/cypress/e2e/_utils/selectors/block-editor.cy.ts +783 -0
  85. package/tests/cypress/e2e/_utils/selectors/dashboard-container.cy.ts +52 -0
  86. package/tests/cypress/e2e/_utils/selectors/dashboard-mobile.bdd.md +205 -0
  87. package/tests/cypress/e2e/_utils/selectors/dashboard-mobile.cy.ts +137 -0
  88. package/tests/cypress/e2e/_utils/selectors/dashboard-navigation.bdd.md +147 -0
  89. package/tests/cypress/e2e/_utils/selectors/dashboard-navigation.cy.ts +114 -0
  90. package/tests/cypress/e2e/_utils/selectors/dashboard-sidebar.bdd.md +76 -0
  91. package/tests/cypress/e2e/_utils/selectors/dashboard-sidebar.cy.ts +68 -0
  92. package/tests/cypress/e2e/_utils/selectors/dashboard-topnav.bdd.md +326 -0
  93. package/tests/cypress/e2e/_utils/selectors/dashboard-topnav.cy.ts +177 -0
  94. package/tests/cypress/e2e/_utils/selectors/devtools.bdd.md +306 -0
  95. package/tests/cypress/e2e/_utils/selectors/devtools.cy.ts +273 -0
  96. package/tests/cypress/e2e/_utils/selectors/global-search.bdd.md +115 -0
  97. package/tests/cypress/e2e/_utils/selectors/global-search.cy.ts +93 -0
  98. package/tests/cypress/e2e/_utils/selectors/patterns.bdd.md +388 -0
  99. package/tests/cypress/e2e/_utils/selectors/patterns.cy.ts +559 -0
  100. package/tests/cypress/e2e/_utils/selectors/public.cy.ts +112 -0
  101. package/tests/cypress/e2e/_utils/selectors/settings-api-keys.bdd.md +266 -0
  102. package/tests/cypress/e2e/_utils/selectors/settings-api-keys.cy.ts +233 -0
  103. package/tests/cypress/e2e/_utils/selectors/settings-billing.bdd.md +78 -0
  104. package/tests/cypress/e2e/_utils/selectors/settings-billing.cy.ts +108 -0
  105. package/tests/cypress/e2e/_utils/selectors/settings-layout.bdd.md +129 -0
  106. package/tests/cypress/e2e/_utils/selectors/settings-layout.cy.ts +115 -0
  107. package/tests/cypress/e2e/_utils/selectors/settings-password.bdd.md +82 -0
  108. package/tests/cypress/e2e/_utils/selectors/settings-password.cy.ts +74 -0
  109. package/tests/cypress/e2e/_utils/selectors/settings-profile.bdd.md +77 -0
  110. package/tests/cypress/e2e/_utils/selectors/settings-profile.cy.ts +79 -0
  111. package/tests/cypress/e2e/_utils/selectors/settings-teams.bdd.md +130 -0
  112. package/tests/cypress/e2e/_utils/selectors/settings-teams.cy.ts +86 -0
  113. package/tests/cypress/e2e/_utils/selectors/superadmin.bdd.md +261 -0
  114. package/tests/cypress/e2e/_utils/selectors/superadmin.cy.ts +193 -0
  115. package/tests/cypress/e2e/_utils/selectors/tasks.bdd.md +593 -0
  116. package/tests/cypress/e2e/_utils/selectors/tasks.cy.ts +864 -0
  117. package/tests/cypress/e2e/_utils/selectors/taxonomies.cy.ts +126 -0
  118. package/tests/cypress/e2e/_utils/selectors/teams.bdd.md +278 -0
  119. package/tests/cypress/e2e/_utils/selectors/teams.cy.ts +195 -0
  120. package/tests/cypress/e2e/_utils/superadmin/all-teams.bdd.md +261 -0
  121. package/tests/cypress/e2e/_utils/superadmin/all-teams.cy.ts +177 -0
  122. package/tests/cypress/e2e/_utils/superadmin/all-users.bdd.md +406 -0
  123. package/tests/cypress/e2e/_utils/superadmin/all-users.cy.ts +294 -0
  124. package/tests/cypress/e2e/_utils/superadmin/dashboard.bdd.md +235 -0
  125. package/tests/cypress/e2e/_utils/superadmin/dashboard.cy.ts +149 -0
  126. package/tests/cypress/e2e/_utils/superadmin/subscriptions-overview.bdd.md +290 -0
  127. package/tests/cypress/e2e/_utils/superadmin/subscriptions-overview.cy.ts +194 -0
  128. package/tests/cypress/e2e/ai/ai-usage.cy.ts +209 -0
  129. package/tests/cypress/e2e/ai/chat-api.cy.ts +119 -0
  130. package/tests/cypress/e2e/ai/guardrails.cy.ts +332 -0
  131. package/tests/cypress/e2e/api/_core/billing/BillingAPIController.js +319 -0
  132. package/tests/cypress/e2e/api/_core/billing/check-action.cy.ts +326 -0
  133. package/tests/cypress/e2e/api/_core/billing/checkout.cy.ts +358 -0
  134. package/tests/cypress/e2e/api/_core/billing/lifecycle.cy.ts +423 -0
  135. package/tests/cypress/e2e/api/_core/billing/plans/README.md +345 -0
  136. package/tests/cypress/e2e/api/_core/billing/plans/business.cy.ts +412 -0
  137. package/tests/cypress/e2e/api/_core/billing/plans/downgrade.cy.ts +510 -0
  138. package/tests/cypress/e2e/api/_core/billing/plans/fixtures/billing-plans.json +163 -0
  139. package/tests/cypress/e2e/api/_core/billing/plans/free.cy.ts +500 -0
  140. package/tests/cypress/e2e/api/_core/billing/plans/pro.cy.ts +497 -0
  141. package/tests/cypress/e2e/api/_core/billing/plans/starter.cy.ts +342 -0
  142. package/tests/cypress/e2e/api/_core/billing/portal.cy.ts +313 -0
  143. package/tests/cypress/e2e/api/_core/devtools/registries.bdd.md +300 -0
  144. package/tests/cypress/e2e/api/_core/devtools/registries.cy.ts +368 -0
  145. package/tests/cypress/e2e/api/_core/scheduled-actions/cron-endpoint.bdd.md +375 -0
  146. package/tests/cypress/e2e/api/_core/scheduled-actions/cron-endpoint.cy.ts +346 -0
  147. package/tests/cypress/e2e/api/_core/scheduled-actions/devtools-endpoint.bdd.md +451 -0
  148. package/tests/cypress/e2e/api/_core/scheduled-actions/devtools-endpoint.cy.ts +447 -0
  149. package/tests/cypress/e2e/api/_core/scheduled-actions/scheduling.bdd.md +649 -0
  150. package/tests/cypress/e2e/api/_core/scheduled-actions/scheduling.cy.ts +333 -0
  151. package/tests/cypress/e2e/api/_core/security/security-headers.cy.ts +601 -0
  152. package/tests/cypress/e2e/api/_core/settings/api-keys.crud.cy.ts +923 -0
  153. package/tests/cypress/e2e/api/_core/teams/teams-security.cy.ts +415 -0
  154. package/tests/cypress/e2e/api/_core/users/users-crud.cy.ts +469 -0
  155. package/tests/cypress/e2e/api/_core/users/users-metas.cy.ts +913 -0
  156. package/tests/cypress/e2e/api/_core/users/users-security.cy.ts +375 -0
  157. package/tests/cypress/e2e/api/entities/customers/customers-crud.cy.ts +648 -0
  158. package/tests/cypress/e2e/api/entities/customers/customers-metas.cy.ts +839 -0
  159. package/tests/cypress/e2e/api/entities/media/media-crud.cy.ts +600 -0
  160. package/tests/cypress/e2e/api/entities/media/media-role-permissions.cy.ts +617 -0
  161. package/tests/cypress/e2e/api/entities/media/media-team-isolation.cy.ts +464 -0
  162. package/tests/cypress/e2e/api/entities/pages/blocks-scope.cy.ts +396 -0
  163. package/tests/cypress/e2e/api/entities/pages/pages-crud.cy.ts +425 -0
  164. package/tests/cypress/e2e/api/entities/pages/pages-status.cy.ts +335 -0
  165. package/tests/cypress/e2e/api/entities/posts/post-categories-crud.cy.ts +610 -0
  166. package/tests/cypress/e2e/api/entities/posts/posts-crud.cy.ts +709 -0
  167. package/tests/cypress/e2e/api/entities/posts/posts-status.cy.ts +396 -0
  168. package/tests/cypress/e2e/api/entities/tasks/tasks-crud.cy.ts +602 -0
  169. package/tests/cypress/e2e/api/entities/tasks/tasks-metas.cy.ts +878 -0
  170. package/tests/cypress/e2e/patterns/patterns-in-pages.cy.ts +367 -0
  171. package/tests/cypress/e2e/uat/_core/auth/app-roles/developer-login.bdd.md +231 -0
  172. package/tests/cypress/e2e/uat/_core/auth/app-roles/developer-login.cy.ts +144 -0
  173. package/tests/cypress/e2e/uat/_core/auth/app-roles/superadmin-login.bdd.md +118 -0
  174. package/tests/cypress/e2e/uat/_core/auth/app-roles/superadmin-login.cy.ts +84 -0
  175. package/tests/cypress/e2e/uat/_core/auth/custom-roles/editor-login.bdd.md +288 -0
  176. package/tests/cypress/e2e/uat/_core/auth/custom-roles/editor-login.cy.ts +188 -0
  177. package/tests/cypress/e2e/uat/_core/auth/login-logout.bdd.md +160 -0
  178. package/tests/cypress/e2e/uat/_core/auth/login-logout.cy.ts +116 -0
  179. package/tests/cypress/e2e/uat/_core/auth/password-reset.bdd.md +289 -0
  180. package/tests/cypress/e2e/uat/_core/auth/password-reset.cy.ts +200 -0
  181. package/tests/cypress/e2e/uat/_core/auth/registration-control-invitation.cy.ts +176 -0
  182. package/tests/cypress/e2e/uat/_core/auth/registration-control-open.cy.ts +131 -0
  183. package/tests/cypress/e2e/uat/_core/auth/registration-control.cy.ts +140 -0
  184. package/tests/cypress/e2e/uat/_core/auth/team-roles/admin-login.bdd.md +225 -0
  185. package/tests/cypress/e2e/uat/_core/auth/team-roles/admin-login.cy.ts +148 -0
  186. package/tests/cypress/e2e/uat/_core/auth/team-roles/member-login.bdd.md +251 -0
  187. package/tests/cypress/e2e/uat/_core/auth/team-roles/member-login.cy.ts +163 -0
  188. package/tests/cypress/e2e/uat/_core/auth/team-roles/owner-login.bdd.md +231 -0
  189. package/tests/cypress/e2e/uat/_core/auth/team-roles/owner-login.cy.ts +141 -0
  190. package/tests/cypress/e2e/uat/_core/billing/extended.bdd.md +273 -0
  191. package/tests/cypress/e2e/uat/_core/billing/extended.cy.ts +209 -0
  192. package/tests/cypress/e2e/uat/_core/billing/feature-gates.bdd.md +407 -0
  193. package/tests/cypress/e2e/uat/_core/billing/feature-gates.cy.ts +307 -0
  194. package/tests/cypress/e2e/uat/_core/billing/page.bdd.md +329 -0
  195. package/tests/cypress/e2e/uat/_core/billing/page.cy.ts +250 -0
  196. package/tests/cypress/e2e/uat/_core/billing/status.bdd.md +190 -0
  197. package/tests/cypress/e2e/uat/_core/billing/status.cy.ts +145 -0
  198. package/tests/cypress/e2e/uat/_core/billing/team-switch.bdd.md +156 -0
  199. package/tests/cypress/e2e/uat/_core/billing/team-switch.cy.ts +122 -0
  200. package/tests/cypress/e2e/uat/_core/billing/usage.bdd.md +218 -0
  201. package/tests/cypress/e2e/uat/_core/billing/usage.cy.ts +176 -0
  202. package/tests/cypress/e2e/uat/_core/blocks/hero.bdd.md +124 -0
  203. package/tests/cypress/e2e/uat/_core/blocks/hero.cy.ts +56 -0
  204. package/tests/cypress/e2e/uat/_core/devtools/api-tester.cy.ts +390 -0
  205. package/tests/cypress/e2e/uat/_core/performance/suspense-loading.cy.ts +134 -0
  206. package/tests/cypress/e2e/uat/_core/scheduled-actions/devtools-ui.bdd.md +736 -0
  207. package/tests/cypress/e2e/uat/_core/scheduled-actions/devtools-ui.cy.ts +740 -0
  208. package/tests/cypress/e2e/uat/_core/teams/inline-edit.cy.ts +278 -0
  209. package/tests/cypress/e2e/uat/_core/teams/roles-matrix.bdd.md +553 -0
  210. package/tests/cypress/e2e/uat/_core/teams/roles-matrix.cy.ts +185 -0
  211. package/tests/cypress/e2e/uat/_core/teams/switcher.bdd.md +1151 -0
  212. package/tests/cypress/e2e/uat/_core/teams/switcher.cy.ts +497 -0
  213. package/tests/cypress/e2e/uat/_core/teams/team-switcher.md +198 -0
  214. package/tests/cypress/e2e/uat/entities/customers/member.bdd.md +275 -0
  215. package/tests/cypress/e2e/uat/entities/customers/member.cy.ts +122 -0
  216. package/tests/cypress/e2e/uat/entities/customers/owner.bdd.md +243 -0
  217. package/tests/cypress/e2e/uat/entities/customers/owner.cy.ts +165 -0
  218. package/tests/cypress/e2e/uat/entities/pages/block-crud.bdd.md +476 -0
  219. package/tests/cypress/e2e/uat/entities/pages/block-crud.cy.ts +486 -0
  220. package/tests/cypress/e2e/uat/entities/pages/block-editor.bdd.md +460 -0
  221. package/tests/cypress/e2e/uat/entities/pages/block-editor.cy.ts +301 -0
  222. package/tests/cypress/e2e/uat/entities/pages/list.bdd.md +432 -0
  223. package/tests/cypress/e2e/uat/entities/pages/list.cy.ts +273 -0
  224. package/tests/cypress/e2e/uat/entities/pages/public-rendering.bdd.md +696 -0
  225. package/tests/cypress/e2e/uat/entities/pages/public-rendering.cy.ts +340 -0
  226. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.bdd.md +161 -0
  227. package/tests/cypress/e2e/uat/entities/posts/categories-api-aware.cy.ts +104 -0
  228. package/tests/cypress/e2e/uat/entities/posts/categories.bdd.md +375 -0
  229. package/tests/cypress/e2e/uat/entities/posts/categories.cy.ts +241 -0
  230. package/tests/cypress/e2e/uat/entities/posts/editor.bdd.md +429 -0
  231. package/tests/cypress/e2e/uat/entities/posts/editor.cy.ts +257 -0
  232. package/tests/cypress/e2e/uat/entities/posts/list.bdd.md +340 -0
  233. package/tests/cypress/e2e/uat/entities/posts/list.cy.ts +177 -0
  234. package/tests/cypress/e2e/uat/entities/posts/public.bdd.md +614 -0
  235. package/tests/cypress/e2e/uat/entities/posts/public.cy.ts +249 -0
  236. package/tests/cypress/e2e/uat/entities/tasks/member.bdd.md +222 -0
  237. package/tests/cypress/e2e/uat/entities/tasks/member.cy.ts +165 -0
  238. package/tests/cypress/e2e/uat/entities/tasks/owner.bdd.md +419 -0
  239. package/tests/cypress/e2e/uat/entities/tasks/owner.cy.ts +191 -0
  240. package/tests/cypress/e2e/uat/features/roles/editor-role.bdd.md +552 -0
  241. package/tests/cypress/e2e/uat/features/roles/editor-role.cy.ts +210 -0
  242. package/tests/cypress/e2e/uat/features/roles/member-restrictions.bdd.md +450 -0
  243. package/tests/cypress/e2e/uat/features/roles/member-restrictions.cy.ts +189 -0
  244. package/tests/cypress/e2e/uat/features/roles/owner-full-crud.bdd.md +530 -0
  245. package/tests/cypress/e2e/uat/features/roles/owner-full-crud.cy.ts +247 -0
  246. package/tests/cypress/fixtures/blocks.json +218 -0
  247. package/tests/cypress/fixtures/entities.json +87 -0
  248. package/tests/cypress/fixtures/page-builder.json +21 -0
  249. package/tests/cypress/src/components/CategoriesPOM.ts +382 -0
  250. package/tests/cypress/src/components/CustomersPOM.ts +439 -0
  251. package/tests/cypress/src/components/DevKeyringPOM.ts +160 -0
  252. package/tests/cypress/src/components/EntityForm.ts +375 -0
  253. package/tests/cypress/src/components/EntityList.ts +389 -0
  254. package/tests/cypress/src/components/PageBuilderPOM.ts +710 -0
  255. package/tests/cypress/src/components/PostEditorPOM.ts +370 -0
  256. package/tests/cypress/src/components/PostsListPOM.ts +223 -0
  257. package/tests/cypress/src/components/PublicPagePOM.ts +447 -0
  258. package/tests/cypress/src/components/PublicPostPOM.ts +146 -0
  259. package/tests/cypress/src/components/TasksPOM.ts +272 -0
  260. package/tests/cypress/src/components/TeamSwitcherPOM.ts +450 -0
  261. package/tests/cypress/src/components/index.ts +21 -0
  262. package/tests/cypress/src/controllers/ApiKeysAPIController.js +178 -0
  263. package/tests/cypress/src/controllers/BaseAPIController.js +317 -0
  264. package/tests/cypress/src/controllers/CustomerAPIController.js +251 -0
  265. package/tests/cypress/src/controllers/MediaAPIController.js +231 -0
  266. package/tests/cypress/src/controllers/PagesAPIController.js +226 -0
  267. package/tests/cypress/src/controllers/PostsAPIController.js +250 -0
  268. package/tests/cypress/src/controllers/TaskAPIController.js +240 -0
  269. package/tests/cypress/src/controllers/UsersAPIController.js +242 -0
  270. package/tests/cypress/src/controllers/index.js +25 -0
  271. package/tests/cypress/src/core/AuthPOM.ts +450 -0
  272. package/tests/cypress/src/core/BasePOM.ts +33 -0
  273. package/tests/cypress/src/core/BlockEditorBasePOM.ts +874 -0
  274. package/tests/cypress/src/core/DashboardEntityPOM.ts +41 -0
  275. package/tests/cypress/src/core/index.ts +14 -0
  276. package/tests/cypress/src/entities/CustomersPOM.ts +172 -0
  277. package/tests/cypress/src/entities/PagesPOM.ts +137 -0
  278. package/tests/cypress/src/entities/PatternsPOM.ts +329 -0
  279. package/tests/cypress/src/entities/PostsPOM.ts +137 -0
  280. package/tests/cypress/src/entities/TasksPOM.ts +246 -0
  281. package/tests/cypress/src/entities/index.ts +16 -0
  282. package/tests/cypress/src/features/BillingPOM.ts +385 -0
  283. package/tests/cypress/src/features/DashboardPOM.ts +271 -0
  284. package/tests/cypress/src/features/DevtoolsPOM.ts +750 -0
  285. package/tests/cypress/src/features/PageBuilderPOM.ts +283 -0
  286. package/tests/cypress/src/features/PostEditorPOM.ts +313 -0
  287. package/tests/cypress/src/features/ScheduledActionsPOM.ts +463 -0
  288. package/tests/cypress/src/features/SettingsPOM.ts +707 -0
  289. package/tests/cypress/src/features/SuperadminPOM.ts +851 -0
  290. package/tests/cypress/src/features/SuperadminTeamRolesPOM.ts +285 -0
  291. package/tests/cypress/src/features/index.ts +28 -0
  292. package/tests/cypress/src/helpers/ApiInterceptor.ts +20 -0
  293. package/tests/cypress/src/index.ts +101 -0
  294. package/tests/cypress/src/pages/dashboard/Dashboard.js +677 -0
  295. package/tests/cypress/src/pages/dashboard/DashboardPage.js +43 -0
  296. package/tests/cypress/src/pages/dashboard/DashboardStats.js +546 -0
  297. package/tests/cypress/src/pages/dashboard/index.js +6 -0
  298. package/tests/cypress/src/pages/index.js +5 -0
  299. package/tests/cypress/src/pages/public/FeaturesPage.js +28 -0
  300. package/tests/cypress/src/pages/public/LandingPage.js +69 -0
  301. package/tests/cypress/src/pages/public/PricingPage.js +33 -0
  302. package/tests/cypress/src/pages/public/index.js +6 -0
  303. package/tests/cypress/src/selectors.ts +46 -0
  304. package/tests/cypress/src/session-helpers.ts +518 -0
  305. package/tests/cypress/support/doc-commands.ts +260 -0
  306. package/tests/cypress/support/e2e.ts +90 -0
  307. package/tests/cypress.config.ts +178 -0
  308. package/tests/jest/__mocks__/@nextsparkjs/core/components/ui/badge.js +16 -0
  309. package/tests/jest/__mocks__/@nextsparkjs/core/lib/db.js +11 -0
  310. package/tests/jest/__mocks__/@nextsparkjs/registries/permissions-registry.ts +160 -0
  311. package/tests/jest/__mocks__/@nextsparkjs/registries/theme-registry.ts +68 -0
  312. package/tests/jest/__mocks__/jose.js +22 -0
  313. package/tests/jest/__mocks__/next/image.js +15 -0
  314. package/tests/jest/__mocks__/next-server.js +56 -0
  315. package/tests/jest/components/post-header.test.tsx +377 -0
  316. package/tests/jest/jest.config.cjs +154 -0
  317. package/tests/jest/langchain/COVERAGE.md +372 -0
  318. package/tests/jest/langchain/guardrails.test.ts +465 -0
  319. package/tests/jest/langchain/streaming.test.ts +370 -0
  320. package/tests/jest/langchain/token-tracker.test.ts +455 -0
  321. package/tests/jest/langchain/tracer-callbacks.test.ts +881 -0
  322. package/tests/jest/langchain/tracer.test.ts +823 -0
  323. package/tests/jest/services/tasks.service.test.ts +707 -0
  324. package/tests/jest/setup.ts +170 -0
  325. package/tests/jest/tsconfig.jest.json +6 -0
  326. package/tests/jest/validation/categories.test.ts +429 -0
  327. package/tests/jest/validation/posts.test.ts +546 -0
  328. package/tests/tsconfig.json +21 -0
  329. /package/docs/{02-features → public/02-features}/01-components.md +0 -0
  330. /package/docs/{02-features → public/02-features}/02-styling.md +0 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 NextSpark
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -26,6 +26,7 @@
26
26
  import { NextRequest } from 'next/server'
27
27
  import { z } from 'zod'
28
28
  import { authenticateRequest } from '@nextsparkjs/core/lib/api/auth/dual-auth'
29
+ import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
29
30
  import { streamChat } from '@/plugins/langchain/lib/agent-factory'
30
31
  import { createSSEEncoder } from '@/plugins/langchain/lib/streaming'
31
32
  import { loadSystemPrompt } from '@/themes/default/lib/langchain/agents'
@@ -46,7 +47,7 @@ const StreamChatRequestSchema = z.object({
46
47
  /**
47
48
  * POST - Stream chat response
48
49
  */
49
- export async function POST(request: NextRequest) {
50
+ const postHandler = async (request: NextRequest) => {
50
51
  try {
51
52
  // 1. Authentication
52
53
  const authResult = await authenticateRequest(request)
@@ -210,3 +211,5 @@ export async function POST(request: NextRequest) {
210
211
  ) as any
211
212
  }
212
213
  }
214
+
215
+ export const POST = withRateLimitTier(postHandler, 'write')
@@ -1,6 +1,7 @@
1
1
  import { NextRequest, NextResponse } from 'next/server'
2
2
  import { z } from 'zod'
3
3
  import { authenticateRequest } from '@nextsparkjs/core/lib/api/auth/dual-auth'
4
+ import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
4
5
  import { processMessage } from '@/themes/default/lib/langchain/orchestrator'
5
6
  import { dbMemoryStore } from '@/plugins/langchain/lib/db-memory-store'
6
7
  import type { ChatMessage } from '@/plugins/langchain/types/langchain.types'
@@ -52,7 +53,7 @@ function convertToApiMessages(
52
53
  * - Sub-agents: task-assistant, customer-assistant, page-assistant
53
54
  * - Handles ambiguous requests by asking for clarification
54
55
  */
55
- export async function POST(req: NextRequest) {
56
+ const postHandler = async (req: NextRequest) => {
56
57
  try {
57
58
  // 1. Dual authentication (API key or session)
58
59
  const authResult = await authenticateRequest(req)
@@ -118,10 +119,12 @@ export async function POST(req: NextRequest) {
118
119
  }
119
120
  }
120
121
 
122
+ export const POST = withRateLimitTier(postHandler, 'write')
123
+
121
124
  /**
122
125
  * GET - Retrieve conversation history
123
126
  */
124
- export async function GET(req: NextRequest) {
127
+ const getHandler = async (req: NextRequest) => {
125
128
  const { searchParams } = new URL(req.url)
126
129
  const sessionId = searchParams.get('sessionId')
127
130
 
@@ -187,10 +190,12 @@ export async function GET(req: NextRequest) {
187
190
  }
188
191
  }
189
192
 
193
+ export const GET = withRateLimitTier(getHandler, 'read')
194
+
190
195
  /**
191
196
  * DELETE - Clear conversation
192
197
  */
193
- export async function DELETE(req: NextRequest) {
198
+ const deleteHandler = async (req: NextRequest) => {
194
199
  const authResult = await authenticateRequest(req)
195
200
  if (!authResult.success || !authResult.user) {
196
201
  return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 })
@@ -224,3 +229,5 @@ export async function DELETE(req: NextRequest) {
224
229
  return NextResponse.json({ success: false, error: 'Failed to clear' }, { status: 500 })
225
230
  }
226
231
  }
232
+
233
+ export const DELETE = withRateLimitTier(deleteHandler, 'write')
@@ -14,6 +14,7 @@
14
14
  import { NextRequest, NextResponse } from 'next/server'
15
15
  import { z } from 'zod'
16
16
  import { authenticateRequest } from '@nextsparkjs/core/lib/api/auth/dual-auth'
17
+ import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
17
18
  import { createAgent } from '@/plugins/langchain/lib/agent-factory'
18
19
  import {
19
20
  dbMemoryStore,
@@ -74,7 +75,7 @@ function convertToApiMessages(
74
75
  /**
75
76
  * POST - Send message to single agent
76
77
  */
77
- export async function POST(req: NextRequest) {
78
+ const postHandler = async (req: NextRequest) => {
78
79
  try {
79
80
  // 1. Authentication
80
81
  const authResult = await authenticateRequest(req)
@@ -181,10 +182,12 @@ export async function POST(req: NextRequest) {
181
182
  }
182
183
  }
183
184
 
185
+ export const POST = withRateLimitTier(postHandler, 'write')
186
+
184
187
  /**
185
188
  * GET - Retrieve conversation history
186
189
  */
187
- export async function GET(req: NextRequest) {
190
+ const getHandler = async (req: NextRequest) => {
188
191
  const { searchParams } = new URL(req.url)
189
192
  const sessionId = searchParams.get('sessionId')
190
193
 
@@ -252,10 +255,12 @@ export async function GET(req: NextRequest) {
252
255
  }
253
256
  }
254
257
 
258
+ export const GET = withRateLimitTier(getHandler, 'read')
259
+
255
260
  /**
256
261
  * DELETE - Clear conversation
257
262
  */
258
- export async function DELETE(req: NextRequest) {
263
+ const deleteHandler = async (req: NextRequest) => {
259
264
  const authResult = await authenticateRequest(req)
260
265
  if (!authResult.success || !authResult.user) {
261
266
  return NextResponse.json({ success: false, error: 'Unauthorized' }, { status: 401 })
@@ -289,3 +294,5 @@ export async function DELETE(req: NextRequest) {
289
294
  return NextResponse.json({ success: false, error: 'Failed to clear' }, { status: 500 })
290
295
  }
291
296
  }
297
+
298
+ export const DELETE = withRateLimitTier(deleteHandler, 'write')
@@ -20,6 +20,7 @@
20
20
 
21
21
  import { NextRequest, NextResponse } from 'next/server'
22
22
  import { authenticateRequest } from '@nextsparkjs/core/lib/api/auth/dual-auth'
23
+ import { withRateLimitTier } from '@nextsparkjs/core/lib/api/rate-limit'
23
24
  import { tokenTracker } from '@/plugins/langchain/lib/token-tracker'
24
25
  import { queryOne } from '@nextsparkjs/core/lib/db'
25
26
 
@@ -28,7 +29,7 @@ type Period = 'today' | '7d' | '30d' | 'all'
28
29
  /**
29
30
  * GET - Retrieve token usage statistics
30
31
  */
31
- export async function GET(request: NextRequest) {
32
+ const getHandler = async (request: NextRequest) => {
32
33
  try {
33
34
  // 1. Authentication
34
35
  const authResult = await authenticateRequest(request)
@@ -120,3 +121,5 @@ export async function GET(request: NextRequest) {
120
121
  )
121
122
  }
122
123
  }
124
+
125
+ export const GET = withRateLimitTier(getHandler, 'read')
@@ -23,9 +23,9 @@ export function BenefitsBlock({
23
23
  const bgClasses = getBackgroundClasses(backgroundColor)
24
24
 
25
25
  const gridCols = {
26
- '2': 'md:grid-cols-2',
27
- '3': 'md:grid-cols-3',
28
- '4': 'md:grid-cols-2 lg:grid-cols-4',
26
+ '2': '@md:grid-cols-2',
27
+ '3': '@md:grid-cols-3',
28
+ '4': '@md:grid-cols-2 @lg:grid-cols-4',
29
29
  }
30
30
 
31
31
  const cardStyles = {
@@ -49,7 +49,7 @@ export function BenefitsBlock({
49
49
  {(sectionTitle || sectionSubtitle) && (
50
50
  <div className="text-center mb-12">
51
51
  {sectionTitle && (
52
- <h2 className="text-3xl md:text-4xl font-bold mb-4">
52
+ <h2 className="text-3xl @md:text-4xl font-bold mb-4">
53
53
  {sectionTitle}
54
54
  </h2>
55
55
  )}
@@ -48,7 +48,7 @@ export function CTASectionBlock({
48
48
 
49
49
  // Build section classes with background and custom className
50
50
  const sectionClasses = buildSectionClasses(
51
- 'py-16 px-4 md:py-24',
51
+ 'py-16 px-4 @md:py-24',
52
52
  { backgroundColor, className }
53
53
  )
54
54
 
@@ -56,15 +56,15 @@ export function CTASectionBlock({
56
56
  <section id={id} className={sectionClasses} data-cy={sel('blocks.ctaSection.container')}>
57
57
  <div className="container mx-auto max-w-4xl text-center">
58
58
  {title && (
59
- <h2 className="mb-4 text-4xl font-bold md:text-5xl">{title}</h2>
59
+ <h2 className="mb-4 text-4xl font-bold @md:text-5xl">{title}</h2>
60
60
  )}
61
61
 
62
62
  {displayContent && (
63
- <p className="mb-8 text-lg md:text-xl opacity-90">{displayContent}</p>
63
+ <p className="mb-8 text-lg @md:text-xl opacity-90">{displayContent}</p>
64
64
  )}
65
65
 
66
66
  {(primaryCta || secondaryButton) && (
67
- <div className="flex flex-col gap-4 sm:flex-row sm:justify-center">
67
+ <div className="flex flex-col gap-4 @sm:flex-row @sm:justify-center">
68
68
  {primaryCta && (
69
69
  <Button asChild size="lg">
70
70
  <a
@@ -44,7 +44,7 @@ export function FaqAccordionBlock({
44
44
 
45
45
  // Build section classes with background and custom className
46
46
  const sectionClasses = buildSectionClasses(
47
- 'py-16 px-4 md:py-24',
47
+ 'py-16 px-4 @md:py-24',
48
48
  { backgroundColor, className }
49
49
  )
50
50
 
@@ -80,7 +80,7 @@ export function FaqAccordionBlock({
80
80
  {(title || subtitle) && (
81
81
  <div className="mb-12 text-center">
82
82
  {title && (
83
- <h2 className="mb-4 text-4xl font-bold md:text-5xl">
83
+ <h2 className="mb-4 text-4xl font-bold @md:text-5xl">
84
84
  {title}
85
85
  </h2>
86
86
  )}
@@ -42,14 +42,14 @@ export function FeaturesGridBlock({
42
42
 
43
43
  // Build column classes based on columns prop
44
44
  const columnClasses: Record<string, string> = {
45
- '2': 'sm:grid-cols-2',
46
- '3': 'sm:grid-cols-2 lg:grid-cols-3',
47
- '4': 'sm:grid-cols-2 lg:grid-cols-4',
45
+ '2': '@sm:grid-cols-2',
46
+ '3': '@sm:grid-cols-2 @lg:grid-cols-3',
47
+ '4': '@sm:grid-cols-2 @lg:grid-cols-4',
48
48
  }
49
49
 
50
50
  // Build section classes with background and custom className
51
51
  const sectionClasses = buildSectionClasses(
52
- 'py-16 px-4 md:py-24',
52
+ 'py-16 px-4 @md:py-24',
53
53
  { backgroundColor, className }
54
54
  )
55
55
 
@@ -60,7 +60,7 @@ export function FeaturesGridBlock({
60
60
  {(title || displayContent) && (
61
61
  <div className="mb-12 text-center">
62
62
  {title && (
63
- <h2 className="mb-4 text-4xl font-bold md:text-5xl">
63
+ <h2 className="mb-4 text-4xl font-bold @md:text-5xl">
64
64
  {title}
65
65
  </h2>
66
66
  )}
@@ -72,13 +72,13 @@ export function HeroBlock({
72
72
  {/* Content */}
73
73
  <div className="container relative z-10 mx-auto max-w-4xl text-center">
74
74
  {title && (
75
- <h1 className="mb-6 text-5xl font-bold leading-tight md:text-6xl lg:text-7xl">
75
+ <h1 className="mb-6 text-5xl font-bold leading-tight @md:text-6xl @lg:text-7xl">
76
76
  {title}
77
77
  </h1>
78
78
  )}
79
79
 
80
80
  {displayContent && (
81
- <p className="mb-8 text-xl md:text-2xl opacity-90">
81
+ <p className="mb-8 text-xl @md:text-2xl opacity-90">
82
82
  {displayContent}
83
83
  </p>
84
84
  )}
@@ -21,7 +21,7 @@ const heroDesignFields: FieldDefinition[] = [
21
21
  {
22
22
  name: 'backgroundImage',
23
23
  label: 'Background Image',
24
- type: 'image',
24
+ type: 'media-library',
25
25
  tab: 'design',
26
26
  required: false,
27
27
  helpText: 'Optional background image (recommended: 1920x1080px minimum)',
@@ -88,26 +88,26 @@ export function HeroWithFormBlock({
88
88
  </div>
89
89
 
90
90
  {/* Content Container */}
91
- <div className="container relative z-10 mx-auto px-4 py-12 lg:py-0">
92
- <div className="grid lg:grid-cols-2 gap-8 lg:gap-16 min-h-screen items-center">
91
+ <div className="container relative z-10 mx-auto px-4 py-12 @lg:py-0">
92
+ <div className="grid @lg:grid-cols-2 gap-8 @lg:gap-16 min-h-screen items-center">
93
93
 
94
94
  {/* Left: Title/Subtitle - vertically centered, bottom aligned on mobile */}
95
- <div className="text-white order-2 lg:order-1 flex flex-col justify-end lg:justify-center pb-8 lg:pb-0">
95
+ <div className="text-white order-2 @lg:order-1 flex flex-col justify-end @lg:justify-center pb-8 @lg:pb-0">
96
96
  {title && (
97
- <h1 className="text-4xl lg:text-5xl xl:text-6xl font-bold italic mb-4 leading-tight">
97
+ <h1 className="text-4xl @lg:text-5xl @xl:text-6xl font-bold italic mb-4 leading-tight">
98
98
  {title}
99
99
  </h1>
100
100
  )}
101
101
  {subtitle && (
102
- <p className="text-lg lg:text-xl xl:text-2xl opacity-90 max-w-lg">
102
+ <p className="text-lg @lg:text-xl @xl:text-2xl opacity-90 max-w-lg">
103
103
  {subtitle}
104
104
  </p>
105
105
  )}
106
106
  </div>
107
107
 
108
108
  {/* Right: Form Card - centered vertically */}
109
- <div className="order-1 lg:order-2 flex justify-center lg:justify-end items-start lg:items-center pt-8 lg:pt-0">
110
- <div className="bg-white rounded-lg shadow-2xl p-6 sm:p-8 w-full max-w-md">
109
+ <div className="order-1 @lg:order-2 flex justify-center @lg:justify-end items-start @lg:items-center pt-8 @lg:pt-0">
110
+ <div className="bg-white rounded-lg shadow-2xl p-6 @sm:p-8 w-full max-w-md">
111
111
  {/* Form Header */}
112
112
  {formTitle && (
113
113
  <h2 className="text-xl font-bold text-center text-primary mb-2">
@@ -34,7 +34,7 @@ const heroWithFormContentFields: FieldDefinition[] = [
34
34
  {
35
35
  name: 'backgroundImage',
36
36
  label: 'Background Image',
37
- type: 'image',
37
+ type: 'media-library',
38
38
  tab: 'content',
39
39
  required: true,
40
40
  helpText: 'Full-width background image (recommended: 1920x1080px minimum)',
@@ -46,16 +46,16 @@ export function JumbotronBlock({
46
46
  }[align]
47
47
 
48
48
  const ctaJustifyClasses = {
49
- center: 'sm:justify-center',
50
- left: 'sm:justify-start',
51
- right: 'sm:justify-end',
49
+ center: '@sm:justify-center',
50
+ left: '@sm:justify-start',
51
+ right: '@sm:justify-end',
52
52
  }[align]
53
53
 
54
54
  // Build section classes with fullscreen or standard padding
55
55
  const sectionClasses = buildSectionClasses(
56
56
  cn(
57
57
  'relative flex overflow-hidden px-4',
58
- fullscreen ? 'min-h-screen' : 'py-16 md:py-24',
58
+ fullscreen ? 'min-h-screen' : 'py-16 @md:py-24',
59
59
  alignmentClasses,
60
60
  textColor === 'light' ? 'text-white' : 'text-gray-900'
61
61
  ),
@@ -81,20 +81,20 @@ export function JumbotronBlock({
81
81
  {/* Content */}
82
82
  <div className={cn('container relative z-10 max-w-4xl', contentAlignmentClasses)}>
83
83
  {title && (
84
- <h1 className="mb-6 text-5xl font-bold leading-tight md:text-6xl lg:text-7xl">
84
+ <h1 className="mb-6 text-5xl font-bold leading-tight @md:text-6xl @lg:text-7xl">
85
85
  {title}
86
86
  </h1>
87
87
  )}
88
88
 
89
89
  {subtitle && (
90
- <p className="mb-8 text-xl md:text-2xl opacity-90">
90
+ <p className="mb-8 text-xl @md:text-2xl opacity-90">
91
91
  {subtitle}
92
92
  </p>
93
93
  )}
94
94
 
95
95
  {/* CTAs - automatically center based on count */}
96
96
  {(primaryCta || secondaryCta) && (
97
- <div className={cn('flex flex-col gap-4 sm:flex-row', ctaJustifyClasses)}>
97
+ <div className={cn('flex flex-col gap-4 @sm:flex-row', ctaJustifyClasses)}>
98
98
  {primaryCta && primaryCta.text && (
99
99
  <Button
100
100
  asChild
@@ -148,7 +148,7 @@ const jumbotronDesignFields: FieldDefinition[] = [
148
148
  {
149
149
  name: 'backgroundImage',
150
150
  label: 'Background Image',
151
- type: 'image',
151
+ type: 'media-library',
152
152
  tab: 'design',
153
153
  required: false,
154
154
  helpText: 'Optional background image (recommended: 1920x1080px minimum)',
@@ -43,10 +43,10 @@ export function LogoCloudBlock({
43
43
 
44
44
  // Build column classes for grid layout
45
45
  const columnClasses: Record<string, string> = {
46
- '3': 'grid-cols-2 sm:grid-cols-3',
47
- '4': 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-4',
48
- '5': 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-5',
49
- '6': 'grid-cols-2 sm:grid-cols-3 lg:grid-cols-6',
46
+ '3': 'grid-cols-2 @sm:grid-cols-3',
47
+ '4': 'grid-cols-2 @sm:grid-cols-3 @lg:grid-cols-4',
48
+ '5': 'grid-cols-2 @sm:grid-cols-3 @lg:grid-cols-5',
49
+ '6': 'grid-cols-2 @sm:grid-cols-3 @lg:grid-cols-6',
50
50
  }
51
51
 
52
52
  // Build size classes for logo containers
@@ -66,7 +66,7 @@ export function LogoCloudBlock({
66
66
 
67
67
  // Build section classes with background and custom className
68
68
  const sectionClasses = buildSectionClasses(
69
- 'py-12 px-4 md:py-16',
69
+ 'py-12 px-4 @md:py-16',
70
70
  { backgroundColor, className }
71
71
  )
72
72
 
@@ -77,7 +77,7 @@ export function LogoCloudBlock({
77
77
  {(title || content) && (
78
78
  <div className="mb-10 text-center">
79
79
  {title && (
80
- <h2 className="mb-3 text-2xl font-semibold md:text-3xl">
80
+ <h2 className="mb-3 text-2xl font-semibold @md:text-3xl">
81
81
  {title}
82
82
  </h2>
83
83
  )}
@@ -30,7 +30,7 @@ const logoCloudContentFields: FieldDefinition[] = [
30
30
  {
31
31
  name: 'image',
32
32
  label: 'Logo Image',
33
- type: 'image',
33
+ type: 'media-library',
34
34
  tab: 'content',
35
35
  required: true,
36
36
  helpText: 'Logo image URL (recommended: transparent PNG, 200x100px)',
@@ -79,7 +79,7 @@ export function PostContentBlock({
79
79
 
80
80
  // Build section classes with background
81
81
  const sectionClasses = buildSectionClasses(
82
- 'py-16 px-4 md:py-24',
82
+ 'py-16 px-4 @md:py-24',
83
83
  { backgroundColor, className }
84
84
  )
85
85
 
@@ -119,7 +119,7 @@ export function PostContentBlock({
119
119
  {/* Optional Section Title */}
120
120
  {title && (
121
121
  <div className={cn('mb-12 text-center', maxWidthClasses[maxWidth], 'mx-auto')}>
122
- <h2 className="text-4xl font-bold md:text-5xl lg:text-6xl tracking-tight">
122
+ <h2 className="text-4xl font-bold @md:text-5xl @lg:text-6xl tracking-tight">
123
123
  {title}
124
124
  </h2>
125
125
  </div>
@@ -38,14 +38,14 @@ export function PricingTableBlock({
38
38
 
39
39
  // Build column classes based on columns prop
40
40
  const columnClasses: Record<string, string> = {
41
- '2': 'sm:grid-cols-2',
42
- '3': 'sm:grid-cols-2 lg:grid-cols-3',
43
- '4': 'sm:grid-cols-2 lg:grid-cols-4',
41
+ '2': '@sm:grid-cols-2',
42
+ '3': '@sm:grid-cols-2 @lg:grid-cols-3',
43
+ '4': '@sm:grid-cols-2 @lg:grid-cols-4',
44
44
  }
45
45
 
46
46
  // Build section classes with background and custom className
47
47
  const sectionClasses = buildSectionClasses(
48
- 'py-16 px-4 md:py-24',
48
+ 'py-16 px-4 @md:py-24',
49
49
  { backgroundColor, className }
50
50
  )
51
51
 
@@ -59,7 +59,7 @@ export function PricingTableBlock({
59
59
  {(title || content) && (
60
60
  <div className="mb-12 text-center">
61
61
  {title && (
62
- <h2 className="mb-4 text-4xl font-bold md:text-5xl">
62
+ <h2 className="mb-4 text-4xl font-bold @md:text-5xl">
63
63
  {title}
64
64
  </h2>
65
65
  )}
@@ -38,7 +38,7 @@ export function SplitContentBlock({
38
38
 
39
39
  // Build section classes with background and custom className
40
40
  const sectionClasses = buildSectionClasses(
41
- 'py-16 px-4 md:py-24',
41
+ 'py-16 px-4 @md:py-24',
42
42
  { backgroundColor, className }
43
43
  )
44
44
 
@@ -57,13 +57,13 @@ export function SplitContentBlock({
57
57
  }
58
58
 
59
59
  // Grid order classes based on image position
60
- const imageOrderClass = imagePosition === 'right' ? 'lg:order-2' : 'lg:order-1'
61
- const contentOrderClass = imagePosition === 'right' ? 'lg:order-1' : 'lg:order-2'
60
+ const imageOrderClass = imagePosition === 'right' ? '@lg:order-2' : '@lg:order-1'
61
+ const contentOrderClass = imagePosition === 'right' ? '@lg:order-1' : '@lg:order-2'
62
62
 
63
63
  return (
64
64
  <section id={id} className={sectionClasses} data-cy={sel('blocks.splitContent.container')}>
65
65
  <div className="container mx-auto max-w-7xl">
66
- <div className={cn('grid gap-8 lg:grid-cols-2 lg:gap-12', alignmentClasses[verticalAlign as 'top' | 'center' | 'bottom'])}>
66
+ <div className={cn('grid gap-8 @lg:grid-cols-2 @lg:gap-12', alignmentClasses[verticalAlign as 'top' | 'center' | 'bottom'])}>
67
67
  {/* Image Column */}
68
68
  <div className={cn('relative', imageOrderClass)}>
69
69
  <div className="relative aspect-[4/3] w-full overflow-hidden">
@@ -86,7 +86,7 @@ export function SplitContentBlock({
86
86
  )}
87
87
 
88
88
  {title && (
89
- <h2 className="mb-4 text-3xl font-bold md:text-4xl lg:text-5xl">
89
+ <h2 className="mb-4 text-3xl font-bold @md:text-4xl @lg:text-5xl">
90
90
  {title}
91
91
  </h2>
92
92
  )}
@@ -46,7 +46,7 @@ const splitContentFields: FieldDefinition[] = [
46
46
  {
47
47
  name: 'image',
48
48
  label: 'Image',
49
- type: 'image',
49
+ type: 'media-library',
50
50
  tab: 'content',
51
51
  required: true,
52
52
  helpText: 'Featured image (recommended: 800x600px minimum)',
@@ -34,16 +34,16 @@ export function StatsCounterBlock({
34
34
 
35
35
  // Build column classes based on columns prop
36
36
  const columnClasses: Record<string, string> = {
37
- '2': 'sm:grid-cols-2',
38
- '3': 'sm:grid-cols-2 lg:grid-cols-3',
39
- '4': 'sm:grid-cols-2 lg:grid-cols-4',
37
+ '2': '@sm:grid-cols-2',
38
+ '3': '@sm:grid-cols-2 @lg:grid-cols-3',
39
+ '4': '@sm:grid-cols-2 @lg:grid-cols-4',
40
40
  }
41
41
 
42
42
  // Size classes for numbers
43
43
  const sizeClasses: Record<string, string> = {
44
- sm: 'text-3xl md:text-4xl',
45
- md: 'text-4xl md:text-5xl',
46
- lg: 'text-5xl md:text-6xl lg:text-7xl',
44
+ sm: 'text-3xl @md:text-4xl',
45
+ md: 'text-4xl @md:text-5xl',
46
+ lg: 'text-5xl @md:text-6xl @lg:text-7xl',
47
47
  }
48
48
 
49
49
  // Variant-specific stat item classes
@@ -62,7 +62,7 @@ export function StatsCounterBlock({
62
62
 
63
63
  // Build section classes with background and custom className
64
64
  const sectionClasses = buildSectionClasses(
65
- 'py-16 px-4 md:py-24',
65
+ 'py-16 px-4 @md:py-24',
66
66
  { backgroundColor, className }
67
67
  )
68
68
 
@@ -73,7 +73,7 @@ export function StatsCounterBlock({
73
73
  {(title || content) && (
74
74
  <div className="mb-12 text-center">
75
75
  {title && (
76
- <h2 className="mb-4 text-4xl font-bold md:text-5xl">
76
+ <h2 className="mb-4 text-4xl font-bold @md:text-5xl">
77
77
  {title}
78
78
  </h2>
79
79
  )}
@@ -98,7 +98,7 @@ export function StatsCounterBlock({
98
98
  <span className="text-primary">{stat.suffix}</span>
99
99
  )}
100
100
  </div>
101
- <div className="text-sm md:text-base text-muted-foreground font-medium">
101
+ <div className="text-sm @md:text-base text-muted-foreground font-medium">
102
102
  {stat.label}
103
103
  </div>
104
104
  </div>
@@ -31,13 +31,13 @@ export function TestimonialsBlock({
31
31
  }: TestimonialsBlockProps) {
32
32
  // Build column classes based on columns prop
33
33
  const columnClasses: Record<string, string> = {
34
- '2': 'md:grid-cols-2',
35
- '3': 'md:grid-cols-2 lg:grid-cols-3',
34
+ '2': '@md:grid-cols-2',
35
+ '3': '@md:grid-cols-2 @lg:grid-cols-3',
36
36
  }
37
37
 
38
38
  // Build section classes with background and custom className
39
39
  const sectionClasses = buildSectionClasses(
40
- 'py-16 px-4 md:py-24',
40
+ 'py-16 px-4 @md:py-24',
41
41
  { backgroundColor, className }
42
42
  )
43
43
 
@@ -51,7 +51,7 @@ export function TestimonialsBlock({
51
51
  {(title || content) && (
52
52
  <div className="mb-12 text-center">
53
53
  {title && (
54
- <h2 className="mb-4 text-4xl font-bold md:text-5xl">
54
+ <h2 className="mb-4 text-4xl font-bold @md:text-5xl">
55
55
  {title}
56
56
  </h2>
57
57
  )}
@@ -58,7 +58,7 @@ const testimonialsContentFields: FieldDefinition[] = [
58
58
  {
59
59
  name: 'avatar',
60
60
  label: 'Avatar Image',
61
- type: 'image',
61
+ type: 'media-library',
62
62
  tab: 'content',
63
63
  required: false,
64
64
  description: 'Profile picture of the person',