@nextsparkjs/theme-default 0.1.0-beta.1

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 (333) hide show
  1. package/about/business.md +49 -0
  2. package/about/features.json +302 -0
  3. package/about/team.md +79 -0
  4. package/api/ai/chat/stream/route.ts +212 -0
  5. package/api/ai/orchestrator/route.ts +226 -0
  6. package/api/ai/single-agent/route.ts +291 -0
  7. package/api/ai/usage/route.ts +122 -0
  8. package/blocks/benefits/component.tsx +100 -0
  9. package/blocks/benefits/config.ts +11 -0
  10. package/blocks/benefits/examples.ts +85 -0
  11. package/blocks/benefits/fields.ts +156 -0
  12. package/blocks/benefits/schema.ts +33 -0
  13. package/blocks/cta-section/component.tsx +100 -0
  14. package/blocks/cta-section/config.ts +11 -0
  15. package/blocks/cta-section/examples.ts +41 -0
  16. package/blocks/cta-section/fields.ts +89 -0
  17. package/blocks/cta-section/index.ts +6 -0
  18. package/blocks/cta-section/schema.ts +32 -0
  19. package/blocks/cta-section/thumbnail.png +1 -0
  20. package/blocks/faq-accordion/component.tsx +156 -0
  21. package/blocks/faq-accordion/config.ts +11 -0
  22. package/blocks/faq-accordion/examples.ts +77 -0
  23. package/blocks/faq-accordion/fields.ts +119 -0
  24. package/blocks/faq-accordion/index.ts +6 -0
  25. package/blocks/faq-accordion/schema.ts +45 -0
  26. package/blocks/features-grid/component.tsx +112 -0
  27. package/blocks/features-grid/config.ts +11 -0
  28. package/blocks/features-grid/examples.ts +63 -0
  29. package/blocks/features-grid/fields.ts +97 -0
  30. package/blocks/features-grid/index.ts +6 -0
  31. package/blocks/features-grid/schema.ts +40 -0
  32. package/blocks/features-grid/thumbnail.png +1 -0
  33. package/blocks/hero/component.tsx +100 -0
  34. package/blocks/hero/config.ts +11 -0
  35. package/blocks/hero/examples.ts +35 -0
  36. package/blocks/hero/fields.ts +60 -0
  37. package/blocks/hero/index.ts +6 -0
  38. package/blocks/hero/schema.ts +32 -0
  39. package/blocks/hero/thumbnail.png +1 -0
  40. package/blocks/hero/thumbnail.png.txt +6 -0
  41. package/blocks/hero-with-form/component.tsx +232 -0
  42. package/blocks/hero-with-form/config.ts +11 -0
  43. package/blocks/hero-with-form/examples.ts +16 -0
  44. package/blocks/hero-with-form/fields.ts +207 -0
  45. package/blocks/hero-with-form/index.ts +6 -0
  46. package/blocks/hero-with-form/schema.ts +54 -0
  47. package/blocks/jumbotron/component.tsx +136 -0
  48. package/blocks/jumbotron/config.ts +11 -0
  49. package/blocks/jumbotron/examples.ts +36 -0
  50. package/blocks/jumbotron/fields.ts +202 -0
  51. package/blocks/jumbotron/index.ts +6 -0
  52. package/blocks/jumbotron/schema.ts +55 -0
  53. package/blocks/logo-cloud/component.tsx +154 -0
  54. package/blocks/logo-cloud/config.ts +11 -0
  55. package/blocks/logo-cloud/examples.ts +34 -0
  56. package/blocks/logo-cloud/fields.ts +133 -0
  57. package/blocks/logo-cloud/index.ts +6 -0
  58. package/blocks/logo-cloud/schema.ts +46 -0
  59. package/blocks/post-content/component.tsx +197 -0
  60. package/blocks/post-content/config.ts +11 -0
  61. package/blocks/post-content/examples.ts +33 -0
  62. package/blocks/post-content/fields.ts +165 -0
  63. package/blocks/post-content/index.ts +4 -0
  64. package/blocks/post-content/schema.ts +46 -0
  65. package/blocks/pricing-table/component.tsx +154 -0
  66. package/blocks/pricing-table/config.ts +11 -0
  67. package/blocks/pricing-table/examples.ts +96 -0
  68. package/blocks/pricing-table/fields.ts +161 -0
  69. package/blocks/pricing-table/index.ts +4 -0
  70. package/blocks/pricing-table/schema.ts +50 -0
  71. package/blocks/split-content/component.tsx +135 -0
  72. package/blocks/split-content/config.ts +11 -0
  73. package/blocks/split-content/examples.ts +38 -0
  74. package/blocks/split-content/fields.ts +198 -0
  75. package/blocks/split-content/index.ts +6 -0
  76. package/blocks/split-content/schema.ts +67 -0
  77. package/blocks/stats-counter/component.tsx +124 -0
  78. package/blocks/stats-counter/config.ts +11 -0
  79. package/blocks/stats-counter/examples.ts +61 -0
  80. package/blocks/stats-counter/fields.ts +134 -0
  81. package/blocks/stats-counter/index.ts +6 -0
  82. package/blocks/stats-counter/schema.ts +47 -0
  83. package/blocks/testimonials/component.tsx +114 -0
  84. package/blocks/testimonials/config.ts +11 -0
  85. package/blocks/testimonials/examples.ts +65 -0
  86. package/blocks/testimonials/fields.ts +105 -0
  87. package/blocks/testimonials/index.ts +6 -0
  88. package/blocks/testimonials/schema.ts +41 -0
  89. package/blocks/testimonials/thumbnail.png +1 -0
  90. package/blocks/text-content/component.tsx +97 -0
  91. package/blocks/text-content/config.ts +11 -0
  92. package/blocks/text-content/examples.ts +30 -0
  93. package/blocks/text-content/fields.ts +88 -0
  94. package/blocks/text-content/index.ts +6 -0
  95. package/blocks/text-content/schema.ts +30 -0
  96. package/blocks/text-content/thumbnail.png +1 -0
  97. package/blocks/timeline/component.tsx +267 -0
  98. package/blocks/timeline/config.ts +11 -0
  99. package/blocks/timeline/examples.ts +68 -0
  100. package/blocks/timeline/fields.ts +147 -0
  101. package/blocks/timeline/index.ts +6 -0
  102. package/blocks/timeline/schema.ts +49 -0
  103. package/blocks/video-hero/component.tsx +270 -0
  104. package/blocks/video-hero/config.ts +11 -0
  105. package/blocks/video-hero/examples.ts +24 -0
  106. package/blocks/video-hero/fields.ts +98 -0
  107. package/blocks/video-hero/index.ts +6 -0
  108. package/blocks/video-hero/schema.ts +39 -0
  109. package/components/ai-chat/ChatPanel.tsx +575 -0
  110. package/components/ai-chat/ConversationItem.tsx +266 -0
  111. package/components/ai-chat/ConversationSidebar.tsx +99 -0
  112. package/components/ai-chat/MarkdownRenderer.tsx +15 -0
  113. package/components/ai-chat/Message.tsx +42 -0
  114. package/components/ai-chat/MessageInput.tsx +49 -0
  115. package/components/ai-chat/MessageList.tsx +46 -0
  116. package/components/ai-chat/TypingIndicator.tsx +11 -0
  117. package/config/app.config.ts +367 -0
  118. package/config/billing.config.ts +349 -0
  119. package/config/dashboard.config.ts +506 -0
  120. package/config/dev.config.ts +104 -0
  121. package/config/features.config.ts +203 -0
  122. package/config/flows.config.ts +129 -0
  123. package/config/permissions.config.ts +245 -0
  124. package/config/theme.config.ts +74 -0
  125. package/docs/01-overview/01-introduction.md +335 -0
  126. package/docs/01-overview/02-customization.md +671 -0
  127. package/docs/02-features/01-components.md +155 -0
  128. package/docs/02-features/02-styling.md +139 -0
  129. package/docs/02-features/03-tasks-entity.md +407 -0
  130. package/docs/03-ai/01-overview.md +211 -0
  131. package/docs/03-ai/02-customization.md +436 -0
  132. package/entities/customers/customers.config.ts +75 -0
  133. package/entities/customers/customers.fields.ts +165 -0
  134. package/entities/customers/customers.service.ts +516 -0
  135. package/entities/customers/customers.types.ts +83 -0
  136. package/entities/customers/messages/en.json +66 -0
  137. package/entities/customers/messages/es.json +66 -0
  138. package/entities/customers/migrations/001_customers_table.sql +102 -0
  139. package/entities/customers/migrations/002_customers_metas.sql +92 -0
  140. package/entities/pages/messages/en.json +41 -0
  141. package/entities/pages/messages/es.json +41 -0
  142. package/entities/pages/migrations/001_pages_table.sql +112 -0
  143. package/entities/pages/migrations/002_pages_metas.sql +56 -0
  144. package/entities/pages/migrations/003_add_status.sql +50 -0
  145. package/entities/pages/pages-management.service.ts +610 -0
  146. package/entities/pages/pages.config.ts +94 -0
  147. package/entities/pages/pages.fields.ts +101 -0
  148. package/entities/pages/pages.service.ts +290 -0
  149. package/entities/pages/pages.types.ts +124 -0
  150. package/entities/posts/components/post-header.tsx +97 -0
  151. package/entities/posts/messages/en.json +55 -0
  152. package/entities/posts/messages/es.json +55 -0
  153. package/entities/posts/migrations/001_posts_table.sql +115 -0
  154. package/entities/posts/migrations/003_add_status.sql +44 -0
  155. package/entities/posts/migrations/004_entity_taxonomy_relations.sql +129 -0
  156. package/entities/posts/migrations/006_posts_metas.sql +56 -0
  157. package/entities/posts/posts.config.ts +101 -0
  158. package/entities/posts/posts.fields.ts +116 -0
  159. package/entities/posts/posts.service.ts +376 -0
  160. package/entities/posts/posts.types.ts +74 -0
  161. package/entities/tasks/messages/en.json +204 -0
  162. package/entities/tasks/messages/es.json +204 -0
  163. package/entities/tasks/migrations/001_tasks_table.sql +105 -0
  164. package/entities/tasks/migrations/002_task_metas.sql +85 -0
  165. package/entities/tasks/migrations/sample_data.json +77 -0
  166. package/entities/tasks/tasks.config.ts +79 -0
  167. package/entities/tasks/tasks.fields.ts +196 -0
  168. package/entities/tasks/tasks.service.ts +541 -0
  169. package/entities/tasks/tasks.types.ts +56 -0
  170. package/lib/hooks/useAiChat.ts +114 -0
  171. package/lib/hooks/useConversations.ts +376 -0
  172. package/lib/hooks/useOrchestratorChat.ts +122 -0
  173. package/lib/hooks/usePersistentChat.ts +315 -0
  174. package/lib/hooks/useStreamingChat.ts +127 -0
  175. package/lib/hooks/useTokenUsage.ts +63 -0
  176. package/lib/langchain/agents/customer-assistant.md +69 -0
  177. package/lib/langchain/agents/index.ts +61 -0
  178. package/lib/langchain/agents/orchestrator.md +59 -0
  179. package/lib/langchain/agents/page-assistant.md +85 -0
  180. package/lib/langchain/agents/single-agent.md +46 -0
  181. package/lib/langchain/agents/task-assistant.md +55 -0
  182. package/lib/langchain/config.ts +45 -0
  183. package/lib/langchain/handlers/customer-handler.ts +338 -0
  184. package/lib/langchain/handlers/page-handler.ts +232 -0
  185. package/lib/langchain/handlers/task-handler.ts +323 -0
  186. package/lib/langchain/langchain.config.ts +223 -0
  187. package/lib/langchain/observability.config.ts +30 -0
  188. package/lib/langchain/orchestrator.ts +562 -0
  189. package/lib/langchain/tools/customers.ts +176 -0
  190. package/lib/langchain/tools/index.ts +10 -0
  191. package/lib/langchain/tools/orchestrator.ts +92 -0
  192. package/lib/langchain/tools/pages.ts +289 -0
  193. package/lib/langchain/tools/tasks.ts +167 -0
  194. package/lib/scheduled-actions/billing.ts +149 -0
  195. package/lib/scheduled-actions/index.ts +170 -0
  196. package/lib/scheduled-actions/webhook.ts +231 -0
  197. package/lib/selectors.ts +197 -0
  198. package/messages/de/admin.json +219 -0
  199. package/messages/de/aiUsage.json +36 -0
  200. package/messages/de/buttons.json +19 -0
  201. package/messages/de/categories.json +35 -0
  202. package/messages/de/common.json +16 -0
  203. package/messages/de/dev.json +101 -0
  204. package/messages/de/docs.json +27 -0
  205. package/messages/de/entities.json +7 -0
  206. package/messages/de/features.json +119 -0
  207. package/messages/de/footer.json +22 -0
  208. package/messages/de/home.json +57 -0
  209. package/messages/de/index.ts +39 -0
  210. package/messages/de/mobileNav.json +13 -0
  211. package/messages/de/navigation.json +8 -0
  212. package/messages/de/observability.json +74 -0
  213. package/messages/de/posts.json +54 -0
  214. package/messages/de/pricing.json +102 -0
  215. package/messages/de/support.json +9 -0
  216. package/messages/de/teams.json +8 -0
  217. package/messages/en/admin.json +219 -0
  218. package/messages/en/aiUsage.json +36 -0
  219. package/messages/en/buttons.json +19 -0
  220. package/messages/en/categories.json +35 -0
  221. package/messages/en/common.json +16 -0
  222. package/messages/en/dev.json +106 -0
  223. package/messages/en/docs.json +27 -0
  224. package/messages/en/entities.json +7 -0
  225. package/messages/en/features.json +119 -0
  226. package/messages/en/footer.json +22 -0
  227. package/messages/en/home.json +57 -0
  228. package/messages/en/index.ts +39 -0
  229. package/messages/en/mobileNav.json +13 -0
  230. package/messages/en/navigation.json +8 -0
  231. package/messages/en/observability.json +74 -0
  232. package/messages/en/posts.json +54 -0
  233. package/messages/en/pricing.json +102 -0
  234. package/messages/en/support.json +9 -0
  235. package/messages/en/teams.json +8 -0
  236. package/messages/es/admin.json +219 -0
  237. package/messages/es/aiUsage.json +36 -0
  238. package/messages/es/buttons.json +19 -0
  239. package/messages/es/categories.json +35 -0
  240. package/messages/es/common.json +16 -0
  241. package/messages/es/dev.json +101 -0
  242. package/messages/es/docs.json +27 -0
  243. package/messages/es/entities.json +7 -0
  244. package/messages/es/features.json +119 -0
  245. package/messages/es/footer.json +22 -0
  246. package/messages/es/home.json +57 -0
  247. package/messages/es/index.ts +39 -0
  248. package/messages/es/mobileNav.json +13 -0
  249. package/messages/es/navigation.json +8 -0
  250. package/messages/es/observability.json +74 -0
  251. package/messages/es/posts.json +54 -0
  252. package/messages/es/pricing.json +102 -0
  253. package/messages/es/support.json +9 -0
  254. package/messages/es/teams.json +8 -0
  255. package/messages/fr/admin.json +219 -0
  256. package/messages/fr/aiUsage.json +36 -0
  257. package/messages/fr/buttons.json +19 -0
  258. package/messages/fr/categories.json +35 -0
  259. package/messages/fr/common.json +16 -0
  260. package/messages/fr/dev.json +101 -0
  261. package/messages/fr/docs.json +27 -0
  262. package/messages/fr/entities.json +7 -0
  263. package/messages/fr/features.json +119 -0
  264. package/messages/fr/footer.json +22 -0
  265. package/messages/fr/home.json +57 -0
  266. package/messages/fr/index.ts +39 -0
  267. package/messages/fr/mobileNav.json +13 -0
  268. package/messages/fr/navigation.json +8 -0
  269. package/messages/fr/observability.json +74 -0
  270. package/messages/fr/posts.json +54 -0
  271. package/messages/fr/pricing.json +102 -0
  272. package/messages/fr/support.json +9 -0
  273. package/messages/fr/teams.json +8 -0
  274. package/messages/it/admin.json +219 -0
  275. package/messages/it/aiUsage.json +36 -0
  276. package/messages/it/buttons.json +19 -0
  277. package/messages/it/categories.json +35 -0
  278. package/messages/it/common.json +16 -0
  279. package/messages/it/dev.json +101 -0
  280. package/messages/it/docs.json +27 -0
  281. package/messages/it/entities.json +7 -0
  282. package/messages/it/features.json +119 -0
  283. package/messages/it/footer.json +22 -0
  284. package/messages/it/home.json +57 -0
  285. package/messages/it/index.ts +39 -0
  286. package/messages/it/mobileNav.json +13 -0
  287. package/messages/it/navigation.json +8 -0
  288. package/messages/it/observability.json +74 -0
  289. package/messages/it/posts.json +54 -0
  290. package/messages/it/pricing.json +102 -0
  291. package/messages/it/support.json +9 -0
  292. package/messages/it/teams.json +8 -0
  293. package/messages/pt/admin.json +219 -0
  294. package/messages/pt/aiUsage.json +36 -0
  295. package/messages/pt/buttons.json +19 -0
  296. package/messages/pt/categories.json +35 -0
  297. package/messages/pt/common.json +16 -0
  298. package/messages/pt/dev.json +101 -0
  299. package/messages/pt/docs.json +27 -0
  300. package/messages/pt/entities.json +7 -0
  301. package/messages/pt/features.json +119 -0
  302. package/messages/pt/footer.json +22 -0
  303. package/messages/pt/home.json +57 -0
  304. package/messages/pt/index.ts +39 -0
  305. package/messages/pt/mobileNav.json +13 -0
  306. package/messages/pt/navigation.json +8 -0
  307. package/messages/pt/observability.json +74 -0
  308. package/messages/pt/posts.json +54 -0
  309. package/messages/pt/pricing.json +102 -0
  310. package/messages/pt/support.json +9 -0
  311. package/messages/pt/teams.json +8 -0
  312. package/migrations/089_add_editor_team_role.sql +39 -0
  313. package/migrations/090_demo_users_teams.sql +540 -0
  314. package/migrations/091_greek_teams_billing.sql +523 -0
  315. package/migrations/092_billing_sample_data.sql +774 -0
  316. package/migrations/093_pages_sample_data.sql +1158 -0
  317. package/migrations/094_posts_sample_data.sql +278 -0
  318. package/migrations/095_tasks_sample_data.sql +440 -0
  319. package/migrations/096_customers_sample_data.sql +358 -0
  320. package/migrations/097_scheduled_actions_sample_data.sql +111 -0
  321. package/package.json +22 -0
  322. package/public/docs/desktop-layout-example.png +0 -0
  323. package/styles/components.css +11 -0
  324. package/styles/globals.css +179 -0
  325. package/templates/(public)/blog/[slug]/page.tsx +65 -0
  326. package/templates/(public)/layout.tsx +25 -0
  327. package/templates/(public)/page.tsx +200 -0
  328. package/templates/(public)/support/page.tsx +321 -0
  329. package/templates/dashboard/(main)/agent-multi/page.tsx +63 -0
  330. package/templates/dashboard/(main)/agent-single/page.tsx +142 -0
  331. package/templates/dashboard/(main)/settings/ai-usage/page.tsx +157 -0
  332. package/templates/superadmin/ai-observability/[traceId]/page.tsx +27 -0
  333. package/templates/superadmin/ai-observability/page.tsx +17 -0
@@ -0,0 +1,207 @@
1
+ import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
2
+ import {
3
+ baseDesignFields,
4
+ baseAdvancedFields,
5
+ } from '@nextsparkjs/core/types/blocks'
6
+
7
+ /**
8
+ * Hero With Form Block Field Definitions
9
+ *
10
+ * Organized into 3 tabs:
11
+ * - Content: title, subtitle, backgroundImage, form fields
12
+ * - Design: backgroundColor (from base) + overlayOpacity
13
+ * - Advanced: className, id (from base)
14
+ */
15
+
16
+ // Hero with form content fields
17
+ const heroWithFormContentFields: FieldDefinition[] = [
18
+ {
19
+ name: 'title',
20
+ label: 'Main Headline',
21
+ type: 'text',
22
+ tab: 'content',
23
+ required: true,
24
+ helpText: 'Main hero headline (appears on left side)',
25
+ },
26
+ {
27
+ name: 'subtitle',
28
+ label: 'Subtitle',
29
+ type: 'textarea',
30
+ tab: 'content',
31
+ required: false,
32
+ helpText: 'Supporting text below the headline',
33
+ },
34
+ {
35
+ name: 'backgroundImage',
36
+ label: 'Background Image',
37
+ type: 'image',
38
+ tab: 'content',
39
+ required: true,
40
+ helpText: 'Full-width background image (recommended: 1920x1080px minimum)',
41
+ },
42
+ {
43
+ name: 'formTitle',
44
+ label: 'Form Title',
45
+ type: 'text',
46
+ tab: 'content',
47
+ required: false,
48
+ default: 'Get Started',
49
+ helpText: 'Title displayed at the top of the form card',
50
+ },
51
+ {
52
+ name: 'formSubtitle',
53
+ label: 'Form Subtitle',
54
+ type: 'text',
55
+ tab: 'content',
56
+ required: false,
57
+ helpText: 'Optional subtitle below form title',
58
+ },
59
+ {
60
+ name: 'firstNamePlaceholder',
61
+ label: 'First Name Placeholder',
62
+ type: 'text',
63
+ tab: 'content',
64
+ required: false,
65
+ default: 'First Name',
66
+ },
67
+ {
68
+ name: 'lastNamePlaceholder',
69
+ label: 'Last Name Placeholder',
70
+ type: 'text',
71
+ tab: 'content',
72
+ required: false,
73
+ default: 'Last Name',
74
+ },
75
+ {
76
+ name: 'emailPlaceholder',
77
+ label: 'Email Placeholder',
78
+ type: 'text',
79
+ tab: 'content',
80
+ required: false,
81
+ default: 'Email',
82
+ },
83
+ {
84
+ name: 'phonePlaceholder',
85
+ label: 'Phone Placeholder',
86
+ type: 'text',
87
+ tab: 'content',
88
+ required: false,
89
+ default: 'Phone',
90
+ },
91
+ {
92
+ name: 'areaOfInterestPlaceholder',
93
+ label: 'Area of Interest Placeholder',
94
+ type: 'text',
95
+ tab: 'content',
96
+ required: false,
97
+ default: 'Area of Interest',
98
+ },
99
+ {
100
+ name: 'areaOfInterestOptions',
101
+ label: 'Area of Interest Options',
102
+ type: 'textarea',
103
+ tab: 'content',
104
+ required: false,
105
+ helpText: 'Enter one option per line for the dropdown',
106
+ },
107
+ {
108
+ name: 'consentCheckboxLabel',
109
+ label: 'Consent Checkbox Label',
110
+ type: 'text',
111
+ tab: 'content',
112
+ required: false,
113
+ helpText: 'Label for the consent checkbox',
114
+ },
115
+ {
116
+ name: 'submitButtonText',
117
+ label: 'Submit Button Text',
118
+ type: 'text',
119
+ tab: 'content',
120
+ required: false,
121
+ default: 'Submit',
122
+ },
123
+ {
124
+ name: 'legalDisclaimer',
125
+ label: 'Legal Disclaimer',
126
+ type: 'textarea',
127
+ tab: 'content',
128
+ required: false,
129
+ helpText: 'Legal text displayed below the form',
130
+ },
131
+ {
132
+ name: 'termsLinkText',
133
+ label: 'Terms Link Text',
134
+ type: 'text',
135
+ tab: 'content',
136
+ required: false,
137
+ default: 'Terms of Service',
138
+ },
139
+ {
140
+ name: 'termsLinkUrl',
141
+ label: 'Terms Link URL',
142
+ type: 'url',
143
+ tab: 'content',
144
+ required: false,
145
+ },
146
+ {
147
+ name: 'privacyLinkText',
148
+ label: 'Privacy Link Text',
149
+ type: 'text',
150
+ tab: 'content',
151
+ required: false,
152
+ default: 'Privacy Policy',
153
+ },
154
+ {
155
+ name: 'privacyLinkUrl',
156
+ label: 'Privacy Link URL',
157
+ type: 'url',
158
+ tab: 'content',
159
+ required: false,
160
+ },
161
+ {
162
+ name: 'formAction',
163
+ label: 'Form Action URL',
164
+ type: 'url',
165
+ tab: 'content',
166
+ required: true,
167
+ helpText: 'URL where the form will be submitted',
168
+ },
169
+ ]
170
+
171
+ // Hero with form design fields
172
+ const heroWithFormDesignFields: FieldDefinition[] = [
173
+ {
174
+ name: 'overlayOpacity',
175
+ label: 'Overlay Opacity',
176
+ type: 'select',
177
+ tab: 'design',
178
+ required: false,
179
+ default: '40',
180
+ helpText: 'Dark overlay opacity for text readability (0-80)',
181
+ options: [
182
+ { label: 'None (0%)', value: '0' },
183
+ { label: 'Light (20%)', value: '20' },
184
+ { label: 'Medium (40%)', value: '40' },
185
+ { label: 'Dark (60%)', value: '60' },
186
+ { label: 'Very Dark (80%)', value: '80' },
187
+ ],
188
+ },
189
+ ]
190
+
191
+ /**
192
+ * Complete field definitions organized by tab
193
+ */
194
+ export const fieldDefinitions: FieldDefinition[] = [
195
+ // Content tab: hero with form fields
196
+ ...heroWithFormContentFields,
197
+
198
+ // Design tab: base fields + hero with form specific
199
+ ...baseDesignFields,
200
+ ...heroWithFormDesignFields,
201
+
202
+ // Advanced tab: base fields only
203
+ ...baseAdvancedFields,
204
+ ]
205
+
206
+ // Alias for compatibility
207
+ 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 { HeroWithFormBlock as Component } from './component'
5
+
6
+ export type { HeroWithFormBlockProps } from './schema'
@@ -0,0 +1,54 @@
1
+ import { z } from 'zod'
2
+ import {
3
+ baseBlockSchema,
4
+ type BaseBlockProps,
5
+ } from '@nextsparkjs/core/types/blocks'
6
+
7
+ /**
8
+ * Hero With Form Block Schema
9
+ *
10
+ * Extends base schema with hero-with-form-specific fields:
11
+ * - backgroundImage: Required hero background
12
+ * - overlayOpacity: Dark overlay for text readability
13
+ * - Form fields for lead capture
14
+ *
15
+ * Note: Uses base schema backgroundColor, className, id
16
+ * The base `title` and `content` serve as main headline and subtitle
17
+ */
18
+ export const heroWithFormSpecificSchema = z.object({
19
+ // Content fields
20
+ subtitle: z.string().optional(),
21
+ backgroundImage: z.string().url('Must be a valid URL'),
22
+
23
+ // Form content
24
+ formTitle: z.string().default('Get Started'),
25
+ formSubtitle: z.string().optional(),
26
+ firstNamePlaceholder: z.string().default('First Name'),
27
+ lastNamePlaceholder: z.string().default('Last Name'),
28
+ emailPlaceholder: z.string().default('Email'),
29
+ phonePlaceholder: z.string().default('Phone'),
30
+ areaOfInterestPlaceholder: z.string().default('Area of Interest'),
31
+ areaOfInterestOptions: z.string().optional(),
32
+ consentCheckboxLabel: z.string().optional(),
33
+ submitButtonText: z.string().default('Submit'),
34
+ legalDisclaimer: z.string().optional(),
35
+ termsLinkText: z.string().default('Terms of Service'),
36
+ termsLinkUrl: z.string().url().optional(),
37
+ privacyLinkText: z.string().default('Privacy Policy'),
38
+ privacyLinkUrl: z.string().url().optional(),
39
+ formAction: z.string().url('Must be a valid URL'),
40
+
41
+ // Design fields
42
+ overlayOpacity: z.enum(['0', '20', '40', '60', '80']).default('40'),
43
+ })
44
+
45
+ /**
46
+ * Complete Hero With Form Block Schema
47
+ * Combines base fields + hero-with-form-specific fields
48
+ */
49
+ export const schema = baseBlockSchema.merge(heroWithFormSpecificSchema)
50
+
51
+ export type HeroWithFormBlockProps = z.infer<typeof schema>
52
+
53
+ // Also export for type-only imports
54
+ export type { BaseBlockProps }
@@ -0,0 +1,136 @@
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 } from '@nextsparkjs/core/types/blocks'
5
+ import { sel } from '../../lib/selectors'
6
+ import type { JumbotronBlockProps } from './schema'
7
+
8
+ /**
9
+ * Jumbotron Block Component
10
+ *
11
+ * Props from 3-tab structure:
12
+ * - Content: title, subtitle, primaryCta, secondaryCta
13
+ * - Design: backgroundColor, fullscreen, backgroundImage, textColor, textAlign
14
+ * - Advanced: className, id
15
+ */
16
+ export function JumbotronBlock({
17
+ // Base content props
18
+ title,
19
+ // Jumbotron-specific content
20
+ subtitle,
21
+ primaryCta,
22
+ secondaryCta,
23
+ // Base design props
24
+ backgroundColor,
25
+ // Jumbotron-specific design
26
+ fullscreen = false,
27
+ backgroundImage,
28
+ textColor = 'light',
29
+ textAlign = 'center',
30
+ // Base advanced props
31
+ className,
32
+ id,
33
+ }: JumbotronBlockProps) {
34
+ // Determine alignment classes
35
+ const align = textAlign as 'center' | 'left' | 'right'
36
+ const alignmentClasses = {
37
+ center: 'text-center items-center justify-center',
38
+ left: 'text-left items-start justify-start',
39
+ right: 'text-right items-end justify-end',
40
+ }[align]
41
+
42
+ const contentAlignmentClasses = {
43
+ center: 'mx-auto',
44
+ left: 'mr-auto',
45
+ right: 'ml-auto',
46
+ }[align]
47
+
48
+ const ctaJustifyClasses = {
49
+ center: 'sm:justify-center',
50
+ left: 'sm:justify-start',
51
+ right: 'sm:justify-end',
52
+ }[align]
53
+
54
+ // Build section classes with fullscreen or standard padding
55
+ const sectionClasses = buildSectionClasses(
56
+ cn(
57
+ 'relative flex overflow-hidden px-4',
58
+ fullscreen ? 'min-h-screen' : 'py-16 md:py-24',
59
+ alignmentClasses,
60
+ textColor === 'light' ? 'text-white' : 'text-gray-900'
61
+ ),
62
+ { backgroundColor, className }
63
+ )
64
+
65
+ return (
66
+ <section id={id} className={sectionClasses} data-cy={sel('blocks.jumbotron.container')}>
67
+ {/* Background Image */}
68
+ {backgroundImage && (
69
+ <div
70
+ className="absolute inset-0 z-0"
71
+ style={{
72
+ backgroundImage: `url(${backgroundImage})`,
73
+ backgroundSize: 'cover',
74
+ backgroundPosition: 'center',
75
+ }}
76
+ >
77
+ <div className="absolute inset-0 bg-black/40" />
78
+ </div>
79
+ )}
80
+
81
+ {/* Content */}
82
+ <div className={cn('container relative z-10 max-w-4xl', contentAlignmentClasses)}>
83
+ {title && (
84
+ <h1 className="mb-6 text-5xl font-bold leading-tight md:text-6xl lg:text-7xl">
85
+ {title}
86
+ </h1>
87
+ )}
88
+
89
+ {subtitle && (
90
+ <p className="mb-8 text-xl md:text-2xl opacity-90">
91
+ {subtitle}
92
+ </p>
93
+ )}
94
+
95
+ {/* CTAs - automatically center based on count */}
96
+ {(primaryCta || secondaryCta) && (
97
+ <div className={cn('flex flex-col gap-4 sm:flex-row', ctaJustifyClasses)}>
98
+ {primaryCta && primaryCta.text && (
99
+ <Button
100
+ asChild
101
+ size="lg"
102
+ variant={primaryCta.variant || 'default'}
103
+ className="text-lg px-8 py-6"
104
+ >
105
+ <a
106
+ href={primaryCta.link || '#'}
107
+ target={primaryCta.target || '_self'}
108
+ rel={primaryCta.target === '_blank' ? 'noopener noreferrer' : undefined}
109
+ >
110
+ {primaryCta.text}
111
+ </a>
112
+ </Button>
113
+ )}
114
+
115
+ {secondaryCta && secondaryCta.text && (
116
+ <Button
117
+ asChild
118
+ size="lg"
119
+ variant={secondaryCta.variant || 'outline'}
120
+ className="text-lg px-8 py-6"
121
+ >
122
+ <a
123
+ href={secondaryCta.link || '#'}
124
+ target={secondaryCta.target || '_self'}
125
+ rel={secondaryCta.target === '_blank' ? 'noopener noreferrer' : undefined}
126
+ >
127
+ {secondaryCta.text}
128
+ </a>
129
+ </Button>
130
+ )}
131
+ </div>
132
+ )}
133
+ </div>
134
+ </section>
135
+ )
136
+ }
@@ -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: 'jumbotron',
5
+ name: 'Jumbotron',
6
+ description: 'A large, attention-grabbing hero block with optional fullscreen mode that takes 100% of the viewport height when enabled. Features centered content with support for 1-2 CTAs that automatically center based on count.',
7
+ category: 'hero',
8
+ icon: 'Maximize2',
9
+ thumbnail: '/theme/blocks/jumbotron/thumbnail.png',
10
+ scope: ['pages', 'posts']
11
+ }
@@ -0,0 +1,36 @@
1
+ import type { BlockExample } from '@nextsparkjs/core/types/blocks'
2
+
3
+ export const examples: BlockExample[] = [
4
+ {
5
+ name: 'Default',
6
+ description: 'Standard jumbotron with centered content',
7
+ props: {
8
+ title: 'Welcome to Our Platform',
9
+ content: 'Discover powerful tools designed to help your team collaborate more effectively and achieve better results.',
10
+ cta: {
11
+ text: 'Learn More',
12
+ link: '/features',
13
+ target: '_self',
14
+ },
15
+ backgroundColor: 'gray-50',
16
+ textColor: 'dark',
17
+ fullscreen: false,
18
+ },
19
+ },
20
+ {
21
+ name: 'Fullscreen',
22
+ description: 'Fullscreen jumbotron with vertical centering',
23
+ props: {
24
+ title: 'Your Success Starts Here',
25
+ content: 'Experience the difference with our comprehensive suite of business tools.',
26
+ cta: {
27
+ text: 'Get Started',
28
+ link: '/signup',
29
+ target: '_self',
30
+ },
31
+ backgroundColor: 'primary',
32
+ textColor: 'light',
33
+ fullscreen: true,
34
+ },
35
+ },
36
+ ]
@@ -0,0 +1,202 @@
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
+ * Jumbotron Block Field Definitions
10
+ *
11
+ * Organized into 3 tabs:
12
+ * - Content: title (from base) + subtitle, primaryCta, secondaryCta
13
+ * - Design: backgroundColor (from base) + fullscreen, backgroundImage, textColor, textAlign
14
+ * - Advanced: className, id (from base)
15
+ */
16
+
17
+ // Filter out base content fields we don't need (content and cta)
18
+ const filteredBaseContentFields = baseContentFields.filter(
19
+ field => field.name !== 'content' && field.name !== 'cta.text' && field.name !== 'cta.link' && field.name !== 'cta.target'
20
+ )
21
+
22
+ // Jumbotron-specific content fields
23
+ const jumbotronContentFields: FieldDefinition[] = [
24
+ {
25
+ name: 'subtitle',
26
+ label: 'Subtitle',
27
+ type: 'textarea',
28
+ tab: 'content',
29
+ required: false,
30
+ placeholder: 'Supporting text or description',
31
+ helpText: 'Optional subtitle text displayed below the main title',
32
+ },
33
+ // Primary CTA
34
+ {
35
+ name: 'primaryCta.text',
36
+ label: 'Button Text',
37
+ type: 'text',
38
+ tab: 'content',
39
+ required: false,
40
+ placeholder: 'Get Started',
41
+ helpText: 'Primary button text',
42
+ group: 'primaryCta',
43
+ groupLabel: 'Primary CTA',
44
+ },
45
+ {
46
+ name: 'primaryCta.link',
47
+ label: 'Link',
48
+ type: 'url',
49
+ tab: 'content',
50
+ required: false,
51
+ placeholder: '/signup or https://...',
52
+ helpText: 'URL the button links to',
53
+ group: 'primaryCta',
54
+ },
55
+ {
56
+ name: 'primaryCta.target',
57
+ label: 'Open in',
58
+ type: 'select',
59
+ tab: 'content',
60
+ required: false,
61
+ default: '_self',
62
+ helpText: 'How the link opens',
63
+ group: 'primaryCta',
64
+ options: [
65
+ { label: 'Same window', value: '_self' },
66
+ { label: 'New tab', value: '_blank' },
67
+ ],
68
+ },
69
+ {
70
+ name: 'primaryCta.variant',
71
+ label: 'Button Style',
72
+ type: 'select',
73
+ tab: 'content',
74
+ required: false,
75
+ default: 'default',
76
+ helpText: 'Visual style of the primary button',
77
+ group: 'primaryCta',
78
+ options: [
79
+ { label: 'Default', value: 'default' },
80
+ { label: 'Outline', value: 'outline' },
81
+ { label: 'Secondary', value: 'secondary' },
82
+ ],
83
+ },
84
+ // Secondary CTA
85
+ {
86
+ name: 'secondaryCta.text',
87
+ label: 'Button Text',
88
+ type: 'text',
89
+ tab: 'content',
90
+ required: false,
91
+ placeholder: 'Learn More',
92
+ helpText: 'Secondary button text',
93
+ group: 'secondaryCta',
94
+ groupLabel: 'Secondary CTA',
95
+ },
96
+ {
97
+ name: 'secondaryCta.link',
98
+ label: 'Link',
99
+ type: 'url',
100
+ tab: 'content',
101
+ required: false,
102
+ placeholder: '/about or https://...',
103
+ helpText: 'URL the button links to',
104
+ group: 'secondaryCta',
105
+ },
106
+ {
107
+ name: 'secondaryCta.target',
108
+ label: 'Open in',
109
+ type: 'select',
110
+ tab: 'content',
111
+ required: false,
112
+ default: '_self',
113
+ helpText: 'How the link opens',
114
+ group: 'secondaryCta',
115
+ options: [
116
+ { label: 'Same window', value: '_self' },
117
+ { label: 'New tab', value: '_blank' },
118
+ ],
119
+ },
120
+ {
121
+ name: 'secondaryCta.variant',
122
+ label: 'Button Style',
123
+ type: 'select',
124
+ tab: 'content',
125
+ required: false,
126
+ default: 'outline',
127
+ helpText: 'Visual style of the secondary button',
128
+ group: 'secondaryCta',
129
+ options: [
130
+ { label: 'Default', value: 'default' },
131
+ { label: 'Outline', value: 'outline' },
132
+ { label: 'Secondary', value: 'secondary' },
133
+ ],
134
+ },
135
+ ]
136
+
137
+ // Jumbotron-specific design fields
138
+ const jumbotronDesignFields: FieldDefinition[] = [
139
+ {
140
+ name: 'fullscreen',
141
+ label: 'Fullscreen Mode',
142
+ type: 'checkbox',
143
+ tab: 'design',
144
+ required: false,
145
+ default: false,
146
+ helpText: 'When enabled, block takes 100% of viewport height. When disabled, uses standard section padding.',
147
+ },
148
+ {
149
+ name: 'backgroundImage',
150
+ label: 'Background Image',
151
+ type: 'image',
152
+ tab: 'design',
153
+ required: false,
154
+ helpText: 'Optional background image (recommended: 1920x1080px minimum)',
155
+ },
156
+ {
157
+ name: 'textColor',
158
+ label: 'Text Color',
159
+ type: 'select',
160
+ tab: 'design',
161
+ required: false,
162
+ default: 'light',
163
+ helpText: 'Choose text color based on background',
164
+ options: [
165
+ { label: 'Light (for dark backgrounds)', value: 'light' },
166
+ { label: 'Dark (for light backgrounds)', value: 'dark' },
167
+ ],
168
+ },
169
+ {
170
+ name: 'textAlign',
171
+ label: 'Text Alignment',
172
+ type: 'select',
173
+ tab: 'design',
174
+ required: false,
175
+ default: 'center',
176
+ helpText: 'Horizontal alignment of content',
177
+ options: [
178
+ { label: 'Center', value: 'center' },
179
+ { label: 'Left', value: 'left' },
180
+ { label: 'Right', value: 'right' },
181
+ ],
182
+ },
183
+ ]
184
+
185
+ /**
186
+ * Complete field definitions organized by tab
187
+ */
188
+ export const fieldDefinitions: FieldDefinition[] = [
189
+ // Content tab: filtered base fields + jumbotron-specific
190
+ ...filteredBaseContentFields,
191
+ ...jumbotronContentFields,
192
+
193
+ // Design tab: base fields + jumbotron-specific
194
+ ...baseDesignFields,
195
+ ...jumbotronDesignFields,
196
+
197
+ // Advanced tab: base fields only
198
+ ...baseAdvancedFields,
199
+ ]
200
+
201
+ // Alias for compatibility
202
+ 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 { JumbotronBlock as Component } from './component'
5
+
6
+ export type { JumbotronBlockProps } from './schema'