@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,100 @@
1
+ import { cn } from '@nextsparkjs/core/lib/utils'
2
+ import { getBackgroundClasses } from '@nextsparkjs/core/types/blocks'
3
+ import { sel } from '../../lib/selectors'
4
+ import type { BenefitsProps } from './schema'
5
+
6
+ interface BenefitItem {
7
+ title: string
8
+ description?: string
9
+ borderColor?: string
10
+ }
11
+
12
+ export function BenefitsBlock({
13
+ sectionTitle,
14
+ sectionSubtitle,
15
+ benefits = [],
16
+ showColoredBorders = false,
17
+ columns = '3',
18
+ cardStyle = 'bordered',
19
+ backgroundColor,
20
+ className,
21
+ id,
22
+ }: BenefitsProps) {
23
+ const bgClasses = getBackgroundClasses(backgroundColor)
24
+
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',
29
+ }
30
+
31
+ const cardStyles = {
32
+ minimal: '',
33
+ bordered: 'border border-border',
34
+ elevated: 'shadow-lg',
35
+ }
36
+
37
+ return (
38
+ <section
39
+ id={id}
40
+ className={cn(
41
+ 'py-16 px-4',
42
+ bgClasses,
43
+ className
44
+ )}
45
+ data-cy={sel('blocks.benefits.container')}
46
+ >
47
+ <div className="max-w-7xl mx-auto">
48
+ {/* Section Header */}
49
+ {(sectionTitle || sectionSubtitle) && (
50
+ <div className="text-center mb-12">
51
+ {sectionTitle && (
52
+ <h2 className="text-3xl md:text-4xl font-bold mb-4">
53
+ {sectionTitle}
54
+ </h2>
55
+ )}
56
+ {sectionSubtitle && (
57
+ <p className="text-lg text-muted-foreground max-w-2xl mx-auto">
58
+ {sectionSubtitle}
59
+ </p>
60
+ )}
61
+ </div>
62
+ )}
63
+
64
+ {/* Benefits Grid */}
65
+ <div className={cn(
66
+ 'grid gap-6',
67
+ gridCols[columns as keyof typeof gridCols]
68
+ )}>
69
+ {(benefits as BenefitItem[]).map((benefit, index) => (
70
+ <div
71
+ key={index}
72
+ className={cn(
73
+ 'bg-card rounded-lg p-6 transition-all hover:scale-[1.02]',
74
+ cardStyles[cardStyle as keyof typeof cardStyles],
75
+ showColoredBorders && 'border-t-4'
76
+ )}
77
+ style={showColoredBorders ? { borderTopColor: benefit.borderColor || '#3b82f6' } : undefined}
78
+ >
79
+ <h3 className="text-xl font-semibold mb-2">
80
+ {benefit.title}
81
+ </h3>
82
+ {benefit.description && (
83
+ <p className="text-muted-foreground">
84
+ {benefit.description}
85
+ </p>
86
+ )}
87
+ </div>
88
+ ))}
89
+ </div>
90
+
91
+ {/* Empty state */}
92
+ {(!benefits || benefits.length === 0) && (
93
+ <div className="text-center py-12 text-muted-foreground">
94
+ <p>No benefits added yet. Add some benefits to display them here.</p>
95
+ </div>
96
+ )}
97
+ </div>
98
+ </section>
99
+ )
100
+ }
@@ -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: 'benefits',
5
+ name: 'Benefits Grid',
6
+ description: '3-column grid showcasing benefits with optional colored top borders',
7
+ category: 'features',
8
+ icon: 'LayoutGrid',
9
+ thumbnail: '/theme/blocks/benefits/thumbnail.png',
10
+ scope: ['pages']
11
+ }
@@ -0,0 +1,85 @@
1
+ import type { BlockExample } from '@nextsparkjs/core/types/blocks'
2
+
3
+ export const examples: BlockExample[] = [
4
+ {
5
+ name: 'Bordered',
6
+ description: 'Benefits grid with bordered cards',
7
+ props: {
8
+ sectionTitle: 'Why Choose Our Platform',
9
+ sectionSubtitle: 'Everything you need to succeed, all in one place',
10
+ backgroundColor: 'white',
11
+ cardStyle: 'bordered',
12
+ showColoredBorders: true,
13
+ columns: '3',
14
+ benefits: [
15
+ {
16
+ title: 'Lightning Fast',
17
+ description: 'Optimized for performance with sub-second load times',
18
+ borderColor: '#3b82f6',
19
+ },
20
+ {
21
+ title: 'Secure by Default',
22
+ description: 'Enterprise-grade security with SOC 2 Type II compliance',
23
+ borderColor: '#10b981',
24
+ },
25
+ {
26
+ title: 'Scale Effortlessly',
27
+ description: 'From startup to enterprise, we grow with you',
28
+ borderColor: '#f59e0b',
29
+ },
30
+ ],
31
+ },
32
+ },
33
+ {
34
+ name: 'Elevated',
35
+ description: 'Benefits grid with elevated cards',
36
+ props: {
37
+ sectionTitle: 'Built for Modern Teams',
38
+ sectionSubtitle: 'Collaboration tools that actually work',
39
+ backgroundColor: 'gray-50',
40
+ cardStyle: 'elevated',
41
+ showColoredBorders: false,
42
+ columns: '3',
43
+ benefits: [
44
+ {
45
+ title: 'Real-time Collaboration',
46
+ description: 'Work together seamlessly with live updates',
47
+ borderColor: '#3b82f6',
48
+ },
49
+ {
50
+ title: 'Smart Automation',
51
+ description: 'Automate repetitive tasks and focus on what matters',
52
+ borderColor: '#10b981',
53
+ },
54
+ {
55
+ title: 'Advanced Analytics',
56
+ description: 'Make data-driven decisions with powerful insights',
57
+ borderColor: '#8b5cf6',
58
+ },
59
+ ],
60
+ },
61
+ },
62
+ {
63
+ name: 'Minimal',
64
+ description: 'Minimal benefits layout',
65
+ props: {
66
+ sectionTitle: 'Simple. Powerful. Effective.',
67
+ backgroundColor: 'white',
68
+ cardStyle: 'minimal',
69
+ showColoredBorders: false,
70
+ columns: '3',
71
+ benefits: [
72
+ {
73
+ title: 'Easy Setup',
74
+ description: 'Get started in minutes, not hours',
75
+ borderColor: '#3b82f6',
76
+ },
77
+ {
78
+ title: 'Intuitive Design',
79
+ description: 'No training required, just works',
80
+ borderColor: '#10b981',
81
+ },
82
+ ],
83
+ },
84
+ },
85
+ ]
@@ -0,0 +1,156 @@
1
+ import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
2
+
3
+ export const fieldDefinitions: FieldDefinition[] = [
4
+ // === CONTENT TAB ===
5
+ {
6
+ name: 'sectionTitle',
7
+ label: 'Section Title',
8
+ type: 'text',
9
+ tab: 'content',
10
+ required: false,
11
+ placeholder: 'Why Choose Us',
12
+ helpText: 'Main heading for this section',
13
+ },
14
+ {
15
+ name: 'sectionSubtitle',
16
+ label: 'Section Subtitle',
17
+ type: 'textarea',
18
+ tab: 'content',
19
+ required: false,
20
+ placeholder: 'Discover the key benefits of working with us',
21
+ rows: 2,
22
+ },
23
+ {
24
+ name: 'benefits',
25
+ label: 'Benefits',
26
+ type: 'array',
27
+ tab: 'content',
28
+ required: true,
29
+ minItems: 1,
30
+ maxItems: 6,
31
+ helpText: 'Add up to 6 benefit cards',
32
+ itemFields: [
33
+ {
34
+ name: 'title',
35
+ label: 'Title',
36
+ type: 'text',
37
+ tab: 'content',
38
+ required: true,
39
+ placeholder: 'Benefit title',
40
+ },
41
+ {
42
+ name: 'description',
43
+ label: 'Description',
44
+ type: 'textarea',
45
+ tab: 'content',
46
+ required: false,
47
+ placeholder: 'Describe this benefit...',
48
+ rows: 3,
49
+ },
50
+ {
51
+ name: 'borderColor',
52
+ label: 'Border Color',
53
+ type: 'color',
54
+ tab: 'content',
55
+ required: false,
56
+ default: '#3b82f6',
57
+ helpText: 'Top border color (when enabled)',
58
+ },
59
+ ],
60
+ },
61
+
62
+ // === DESIGN TAB ===
63
+ {
64
+ name: 'showColoredBorders',
65
+ label: 'Enable Colored Borders',
66
+ type: 'checkbox',
67
+ tab: 'design',
68
+ required: false,
69
+ default: false,
70
+ checkboxLabel: 'Show colored top border on each card',
71
+ helpText: 'When enabled, each card displays a colored top border',
72
+ },
73
+ {
74
+ name: 'columns',
75
+ label: 'Number of Columns',
76
+ type: 'select',
77
+ tab: 'design',
78
+ required: false,
79
+ default: '3',
80
+ options: [
81
+ { label: '2 Columns', value: '2' },
82
+ { label: '3 Columns', value: '3' },
83
+ { label: '4 Columns', value: '4' },
84
+ ],
85
+ },
86
+ {
87
+ name: 'cardStyle',
88
+ label: 'Card Style',
89
+ type: 'radio',
90
+ tab: 'design',
91
+ required: false,
92
+ default: 'bordered',
93
+ options: [
94
+ { label: 'Minimal', value: 'minimal' },
95
+ { label: 'Bordered', value: 'bordered' },
96
+ { label: 'Elevated (Shadow)', value: 'elevated' },
97
+ ],
98
+ helpText: 'Visual style for benefit cards',
99
+ },
100
+ {
101
+ name: 'backgroundColor',
102
+ label: 'Background Color',
103
+ type: 'select',
104
+ tab: 'design',
105
+ required: false,
106
+ default: 'transparent',
107
+ options: [
108
+ { label: 'Transparent', value: 'transparent' },
109
+ { label: 'White', value: 'white' },
110
+ { label: 'Gray 50', value: 'gray-50' },
111
+ { label: 'Gray 100', value: 'gray-100' },
112
+ ],
113
+ },
114
+
115
+ // === ADVANCED TAB (Testing new field types) ===
116
+ {
117
+ name: 'publishDate',
118
+ label: 'Publish Date',
119
+ type: 'date',
120
+ tab: 'advanced',
121
+ required: false,
122
+ helpText: 'Date field example (date picker)',
123
+ },
124
+ {
125
+ name: 'eventTime',
126
+ label: 'Event Time',
127
+ type: 'time',
128
+ tab: 'advanced',
129
+ required: false,
130
+ helpText: 'Time field example (time picker)',
131
+ },
132
+ {
133
+ name: 'lastUpdated',
134
+ label: 'Last Updated',
135
+ type: 'datetime',
136
+ tab: 'advanced',
137
+ required: false,
138
+ helpText: 'Datetime field example (date + time)',
139
+ },
140
+ {
141
+ name: 'className',
142
+ label: 'CSS Class',
143
+ type: 'text',
144
+ tab: 'advanced',
145
+ required: false,
146
+ placeholder: 'my-custom-class',
147
+ },
148
+ {
149
+ name: 'id',
150
+ label: 'HTML ID',
151
+ type: 'text',
152
+ tab: 'advanced',
153
+ required: false,
154
+ placeholder: 'benefits-section',
155
+ },
156
+ ]
@@ -0,0 +1,33 @@
1
+ import { z } from 'zod'
2
+ import { baseBlockSchema } from '@nextsparkjs/core/types/blocks'
3
+
4
+ const benefitItemSchema = z.object({
5
+ title: z.string().min(1, 'Title is required'),
6
+ description: z.string().optional(),
7
+ borderColor: z.string().optional().default('#3b82f6'),
8
+ })
9
+
10
+ export const benefitsSchema = baseBlockSchema.extend({
11
+ // Content
12
+ sectionTitle: z.string().optional(),
13
+ sectionSubtitle: z.string().optional(),
14
+
15
+ // Benefits array
16
+ benefits: z.array(benefitItemSchema).min(1).max(6).default([
17
+ { title: 'Benefit 1', description: 'Description for benefit 1', borderColor: '#3b82f6' },
18
+ { title: 'Benefit 2', description: 'Description for benefit 2', borderColor: '#10b981' },
19
+ { title: 'Benefit 3', description: 'Description for benefit 3', borderColor: '#f59e0b' },
20
+ ]),
21
+
22
+ // Design options
23
+ showColoredBorders: z.boolean().default(false),
24
+ columns: z.enum(['2', '3', '4']).default('3'),
25
+
26
+ // Demo fields for testing new field types
27
+ publishDate: z.string().optional(),
28
+ eventTime: z.string().optional(),
29
+ lastUpdated: z.string().optional(),
30
+ cardStyle: z.enum(['minimal', 'bordered', 'elevated']).default('bordered'),
31
+ })
32
+
33
+ export type BenefitsProps = z.infer<typeof benefitsSchema>
@@ -0,0 +1,100 @@
1
+ import React from 'react'
2
+ import { Button } from '@nextsparkjs/core/components/ui/button'
3
+ import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
4
+ import { sel } from '../../lib/selectors'
5
+ import type { CTASectionBlockProps } from './schema'
6
+
7
+ /**
8
+ * CTA Section Block Component
9
+ *
10
+ * Props from 3-tab structure:
11
+ * - Content: title, content, cta (primary), secondaryButton
12
+ * - Design: backgroundColor
13
+ * - Advanced: className, id
14
+ */
15
+ export function CTASectionBlock({
16
+ // Base content props
17
+ title,
18
+ content,
19
+ cta,
20
+ // CTA-specific content
21
+ secondaryButton,
22
+ // Base design props
23
+ backgroundColor,
24
+ // Base advanced props
25
+ className,
26
+ id,
27
+ // Legacy props for backward compatibility
28
+ ...legacyProps
29
+ }: CTASectionBlockProps & {
30
+ buttonText?: string
31
+ buttonLink?: string
32
+ primaryButton?: { text: string; link: string; variant?: string }
33
+ description?: string
34
+ }) {
35
+ // Handle legacy format (buttonText/buttonLink or primaryButton)
36
+ const primaryCta = cta || (legacyProps.primaryButton ? {
37
+ text: legacyProps.primaryButton.text,
38
+ link: legacyProps.primaryButton.link,
39
+ target: '_self' as const,
40
+ } : legacyProps.buttonText ? {
41
+ text: legacyProps.buttonText,
42
+ link: legacyProps.buttonLink || '#',
43
+ target: '_self' as const,
44
+ } : undefined)
45
+
46
+ // Handle legacy description prop
47
+ const displayContent = content || (legacyProps as { description?: string }).description
48
+
49
+ // Build section classes with background and custom className
50
+ const sectionClasses = buildSectionClasses(
51
+ 'py-16 px-4 md:py-24',
52
+ { backgroundColor, className }
53
+ )
54
+
55
+ return (
56
+ <section id={id} className={sectionClasses} data-cy={sel('blocks.ctaSection.container')}>
57
+ <div className="container mx-auto max-w-4xl text-center">
58
+ {title && (
59
+ <h2 className="mb-4 text-4xl font-bold md:text-5xl">{title}</h2>
60
+ )}
61
+
62
+ {displayContent && (
63
+ <p className="mb-8 text-lg md:text-xl opacity-90">{displayContent}</p>
64
+ )}
65
+
66
+ {(primaryCta || secondaryButton) && (
67
+ <div className="flex flex-col gap-4 sm:flex-row sm:justify-center">
68
+ {primaryCta && (
69
+ <Button asChild size="lg">
70
+ <a
71
+ href={primaryCta.link}
72
+ target={primaryCta.target}
73
+ rel={primaryCta.target === '_blank' ? 'noopener noreferrer' : undefined}
74
+ >
75
+ {primaryCta.text}
76
+ </a>
77
+ </Button>
78
+ )}
79
+
80
+ {secondaryButton && (
81
+ <Button
82
+ asChild
83
+ size="lg"
84
+ variant={secondaryButton.variant || 'outline'}
85
+ >
86
+ <a
87
+ href={secondaryButton.link}
88
+ target={secondaryButton.target}
89
+ rel={secondaryButton.target === '_blank' ? 'noopener noreferrer' : undefined}
90
+ >
91
+ {secondaryButton.text}
92
+ </a>
93
+ </Button>
94
+ )}
95
+ </div>
96
+ )}
97
+ </div>
98
+ </section>
99
+ )
100
+ }
@@ -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: 'cta-section',
5
+ name: 'CTA Section',
6
+ description: 'Call-to-action section with title, description, and action buttons',
7
+ category: 'cta',
8
+ icon: 'Megaphone',
9
+ thumbnail: '/theme/blocks/cta-section/thumbnail.png',
10
+ scope: ['pages']
11
+ }
@@ -0,0 +1,41 @@
1
+ import type { BlockExample } from '@nextsparkjs/core/types/blocks'
2
+
3
+ export const examples: BlockExample[] = [
4
+ {
5
+ name: 'Primary CTA',
6
+ description: 'Single primary call-to-action',
7
+ props: {
8
+ title: 'Ready to Get Started?',
9
+ content: 'Join thousands of teams already using our platform to accelerate their growth.',
10
+ primaryCta: {
11
+ text: 'Start Free Trial',
12
+ link: '/signup',
13
+ target: '_self',
14
+ },
15
+ backgroundColor: 'primary',
16
+ textColor: 'light',
17
+ alignment: 'center',
18
+ },
19
+ },
20
+ {
21
+ name: 'With Secondary CTA',
22
+ description: 'Primary and secondary CTAs',
23
+ props: {
24
+ title: 'Transform Your Workflow',
25
+ content: 'Experience the difference with our comprehensive suite of tools. No credit card required.',
26
+ primaryCta: {
27
+ text: 'Get Started Free',
28
+ link: '/signup',
29
+ target: '_self',
30
+ },
31
+ secondaryCta: {
32
+ text: 'Schedule Demo',
33
+ link: '/demo',
34
+ target: '_self',
35
+ },
36
+ backgroundColor: 'gray-900',
37
+ textColor: 'light',
38
+ alignment: 'center',
39
+ },
40
+ },
41
+ ]
@@ -0,0 +1,89 @@
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
+ * CTA Section Block Field Definitions
10
+ *
11
+ * Organized into 3 tabs:
12
+ * - Content: title, description, cta (from base) + secondaryButton
13
+ * - Design: backgroundColor (from base)
14
+ * - Advanced: className, id (from base)
15
+ *
16
+ * Note: The base CTA fields serve as the primary button
17
+ */
18
+
19
+ // CTA-specific content fields (secondary button) - grouped in UI
20
+ const ctaContentFields: FieldDefinition[] = [
21
+ {
22
+ name: 'secondaryButton.text',
23
+ label: 'Text',
24
+ type: 'text',
25
+ tab: 'content',
26
+ required: false,
27
+ placeholder: 'Learn More',
28
+ helpText: 'Button text',
29
+ group: 'secondaryButton',
30
+ groupLabel: 'Secondary Button',
31
+ },
32
+ {
33
+ name: 'secondaryButton.link',
34
+ label: 'Link',
35
+ type: 'url',
36
+ tab: 'content',
37
+ required: false,
38
+ placeholder: '/about or https://...',
39
+ helpText: 'URL the button links to',
40
+ group: 'secondaryButton',
41
+ },
42
+ {
43
+ name: 'secondaryButton.target',
44
+ label: 'Open in',
45
+ type: 'select',
46
+ tab: 'content',
47
+ required: false,
48
+ default: '_self',
49
+ helpText: 'How the link opens',
50
+ group: 'secondaryButton',
51
+ options: [
52
+ { label: 'Same window', value: '_self' },
53
+ { label: 'New tab', value: '_blank' },
54
+ ],
55
+ },
56
+ {
57
+ name: 'secondaryButton.variant',
58
+ label: 'Style',
59
+ type: 'select',
60
+ tab: 'content',
61
+ required: false,
62
+ default: 'outline',
63
+ helpText: 'Visual style of the button',
64
+ group: 'secondaryButton',
65
+ options: [
66
+ { label: 'Default', value: 'default' },
67
+ { label: 'Outline', value: 'outline' },
68
+ { label: 'Ghost', value: 'ghost' },
69
+ ],
70
+ },
71
+ ]
72
+
73
+ /**
74
+ * Complete field definitions organized by tab
75
+ */
76
+ export const fieldDefinitions: FieldDefinition[] = [
77
+ // Content tab: base fields + cta-specific
78
+ ...baseContentFields,
79
+ ...ctaContentFields,
80
+
81
+ // Design tab: base fields only
82
+ ...baseDesignFields,
83
+
84
+ // Advanced tab: base fields only
85
+ ...baseAdvancedFields,
86
+ ]
87
+
88
+ // Alias for compatibility
89
+ 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 { CTASectionBlock as Component } from './component'
5
+
6
+ export type { CTASectionBlockProps } from './schema'
@@ -0,0 +1,32 @@
1
+ import { z } from 'zod'
2
+ import { baseBlockSchema, ctaSchema } from '@nextsparkjs/core/types/blocks'
3
+
4
+ /**
5
+ * Secondary Button Schema (CTA-specific)
6
+ * Uses same structure as CTA but with outline variant default
7
+ */
8
+ const secondaryButtonSchema = ctaSchema.extend({
9
+ variant: z.enum(['default', 'outline', 'ghost']).default('outline'),
10
+ })
11
+
12
+ export type SecondaryButton = z.infer<typeof secondaryButtonSchema>
13
+
14
+ /**
15
+ * CTA Section Block Schema
16
+ *
17
+ * Extends base schema with:
18
+ * - secondaryButton: Optional secondary CTA button
19
+ *
20
+ * Note: Uses base schema title, description, cta (as primary), backgroundColor, className, id
21
+ */
22
+ export const ctaSectionSpecificSchema = z.object({
23
+ // Content: secondary button option
24
+ secondaryButton: secondaryButtonSchema.optional(),
25
+ })
26
+
27
+ /**
28
+ * Complete CTA Section Block Schema
29
+ */
30
+ export const schema = baseBlockSchema.merge(ctaSectionSpecificSchema)
31
+
32
+ export type CTASectionBlockProps = z.infer<typeof schema>
@@ -0,0 +1 @@
1
+ Placeholder