@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.
- package/about/business.md +49 -0
- package/about/features.json +302 -0
- package/about/team.md +79 -0
- package/api/ai/chat/stream/route.ts +212 -0
- package/api/ai/orchestrator/route.ts +226 -0
- package/api/ai/single-agent/route.ts +291 -0
- package/api/ai/usage/route.ts +122 -0
- package/blocks/benefits/component.tsx +100 -0
- package/blocks/benefits/config.ts +11 -0
- package/blocks/benefits/examples.ts +85 -0
- package/blocks/benefits/fields.ts +156 -0
- package/blocks/benefits/schema.ts +33 -0
- package/blocks/cta-section/component.tsx +100 -0
- package/blocks/cta-section/config.ts +11 -0
- package/blocks/cta-section/examples.ts +41 -0
- package/blocks/cta-section/fields.ts +89 -0
- package/blocks/cta-section/index.ts +6 -0
- package/blocks/cta-section/schema.ts +32 -0
- package/blocks/cta-section/thumbnail.png +1 -0
- package/blocks/faq-accordion/component.tsx +156 -0
- package/blocks/faq-accordion/config.ts +11 -0
- package/blocks/faq-accordion/examples.ts +77 -0
- package/blocks/faq-accordion/fields.ts +119 -0
- package/blocks/faq-accordion/index.ts +6 -0
- package/blocks/faq-accordion/schema.ts +45 -0
- package/blocks/features-grid/component.tsx +112 -0
- package/blocks/features-grid/config.ts +11 -0
- package/blocks/features-grid/examples.ts +63 -0
- package/blocks/features-grid/fields.ts +97 -0
- package/blocks/features-grid/index.ts +6 -0
- package/blocks/features-grid/schema.ts +40 -0
- package/blocks/features-grid/thumbnail.png +1 -0
- package/blocks/hero/component.tsx +100 -0
- package/blocks/hero/config.ts +11 -0
- package/blocks/hero/examples.ts +35 -0
- package/blocks/hero/fields.ts +60 -0
- package/blocks/hero/index.ts +6 -0
- package/blocks/hero/schema.ts +32 -0
- package/blocks/hero/thumbnail.png +1 -0
- package/blocks/hero/thumbnail.png.txt +6 -0
- package/blocks/hero-with-form/component.tsx +232 -0
- package/blocks/hero-with-form/config.ts +11 -0
- package/blocks/hero-with-form/examples.ts +16 -0
- package/blocks/hero-with-form/fields.ts +207 -0
- package/blocks/hero-with-form/index.ts +6 -0
- package/blocks/hero-with-form/schema.ts +54 -0
- package/blocks/jumbotron/component.tsx +136 -0
- package/blocks/jumbotron/config.ts +11 -0
- package/blocks/jumbotron/examples.ts +36 -0
- package/blocks/jumbotron/fields.ts +202 -0
- package/blocks/jumbotron/index.ts +6 -0
- package/blocks/jumbotron/schema.ts +55 -0
- package/blocks/logo-cloud/component.tsx +154 -0
- package/blocks/logo-cloud/config.ts +11 -0
- package/blocks/logo-cloud/examples.ts +34 -0
- package/blocks/logo-cloud/fields.ts +133 -0
- package/blocks/logo-cloud/index.ts +6 -0
- package/blocks/logo-cloud/schema.ts +46 -0
- package/blocks/post-content/component.tsx +197 -0
- package/blocks/post-content/config.ts +11 -0
- package/blocks/post-content/examples.ts +33 -0
- package/blocks/post-content/fields.ts +165 -0
- package/blocks/post-content/index.ts +4 -0
- package/blocks/post-content/schema.ts +46 -0
- package/blocks/pricing-table/component.tsx +154 -0
- package/blocks/pricing-table/config.ts +11 -0
- package/blocks/pricing-table/examples.ts +96 -0
- package/blocks/pricing-table/fields.ts +161 -0
- package/blocks/pricing-table/index.ts +4 -0
- package/blocks/pricing-table/schema.ts +50 -0
- package/blocks/split-content/component.tsx +135 -0
- package/blocks/split-content/config.ts +11 -0
- package/blocks/split-content/examples.ts +38 -0
- package/blocks/split-content/fields.ts +198 -0
- package/blocks/split-content/index.ts +6 -0
- package/blocks/split-content/schema.ts +67 -0
- package/blocks/stats-counter/component.tsx +124 -0
- package/blocks/stats-counter/config.ts +11 -0
- package/blocks/stats-counter/examples.ts +61 -0
- package/blocks/stats-counter/fields.ts +134 -0
- package/blocks/stats-counter/index.ts +6 -0
- package/blocks/stats-counter/schema.ts +47 -0
- package/blocks/testimonials/component.tsx +114 -0
- package/blocks/testimonials/config.ts +11 -0
- package/blocks/testimonials/examples.ts +65 -0
- package/blocks/testimonials/fields.ts +105 -0
- package/blocks/testimonials/index.ts +6 -0
- package/blocks/testimonials/schema.ts +41 -0
- package/blocks/testimonials/thumbnail.png +1 -0
- package/blocks/text-content/component.tsx +97 -0
- package/blocks/text-content/config.ts +11 -0
- package/blocks/text-content/examples.ts +30 -0
- package/blocks/text-content/fields.ts +88 -0
- package/blocks/text-content/index.ts +6 -0
- package/blocks/text-content/schema.ts +30 -0
- package/blocks/text-content/thumbnail.png +1 -0
- package/blocks/timeline/component.tsx +267 -0
- package/blocks/timeline/config.ts +11 -0
- package/blocks/timeline/examples.ts +68 -0
- package/blocks/timeline/fields.ts +147 -0
- package/blocks/timeline/index.ts +6 -0
- package/blocks/timeline/schema.ts +49 -0
- package/blocks/video-hero/component.tsx +270 -0
- package/blocks/video-hero/config.ts +11 -0
- package/blocks/video-hero/examples.ts +24 -0
- package/blocks/video-hero/fields.ts +98 -0
- package/blocks/video-hero/index.ts +6 -0
- package/blocks/video-hero/schema.ts +39 -0
- package/components/ai-chat/ChatPanel.tsx +575 -0
- package/components/ai-chat/ConversationItem.tsx +266 -0
- package/components/ai-chat/ConversationSidebar.tsx +99 -0
- package/components/ai-chat/MarkdownRenderer.tsx +15 -0
- package/components/ai-chat/Message.tsx +42 -0
- package/components/ai-chat/MessageInput.tsx +49 -0
- package/components/ai-chat/MessageList.tsx +46 -0
- package/components/ai-chat/TypingIndicator.tsx +11 -0
- package/config/app.config.ts +367 -0
- package/config/billing.config.ts +349 -0
- package/config/dashboard.config.ts +506 -0
- package/config/dev.config.ts +104 -0
- package/config/features.config.ts +203 -0
- package/config/flows.config.ts +129 -0
- package/config/permissions.config.ts +245 -0
- package/config/theme.config.ts +74 -0
- package/docs/01-overview/01-introduction.md +335 -0
- package/docs/01-overview/02-customization.md +671 -0
- package/docs/02-features/01-components.md +155 -0
- package/docs/02-features/02-styling.md +139 -0
- package/docs/02-features/03-tasks-entity.md +407 -0
- package/docs/03-ai/01-overview.md +211 -0
- package/docs/03-ai/02-customization.md +436 -0
- package/entities/customers/customers.config.ts +75 -0
- package/entities/customers/customers.fields.ts +165 -0
- package/entities/customers/customers.service.ts +516 -0
- package/entities/customers/customers.types.ts +83 -0
- package/entities/customers/messages/en.json +66 -0
- package/entities/customers/messages/es.json +66 -0
- package/entities/customers/migrations/001_customers_table.sql +102 -0
- package/entities/customers/migrations/002_customers_metas.sql +92 -0
- package/entities/pages/messages/en.json +41 -0
- package/entities/pages/messages/es.json +41 -0
- package/entities/pages/migrations/001_pages_table.sql +112 -0
- package/entities/pages/migrations/002_pages_metas.sql +56 -0
- package/entities/pages/migrations/003_add_status.sql +50 -0
- package/entities/pages/pages-management.service.ts +610 -0
- package/entities/pages/pages.config.ts +94 -0
- package/entities/pages/pages.fields.ts +101 -0
- package/entities/pages/pages.service.ts +290 -0
- package/entities/pages/pages.types.ts +124 -0
- package/entities/posts/components/post-header.tsx +97 -0
- package/entities/posts/messages/en.json +55 -0
- package/entities/posts/messages/es.json +55 -0
- package/entities/posts/migrations/001_posts_table.sql +115 -0
- package/entities/posts/migrations/003_add_status.sql +44 -0
- package/entities/posts/migrations/004_entity_taxonomy_relations.sql +129 -0
- package/entities/posts/migrations/006_posts_metas.sql +56 -0
- package/entities/posts/posts.config.ts +101 -0
- package/entities/posts/posts.fields.ts +116 -0
- package/entities/posts/posts.service.ts +376 -0
- package/entities/posts/posts.types.ts +74 -0
- package/entities/tasks/messages/en.json +204 -0
- package/entities/tasks/messages/es.json +204 -0
- package/entities/tasks/migrations/001_tasks_table.sql +105 -0
- package/entities/tasks/migrations/002_task_metas.sql +85 -0
- package/entities/tasks/migrations/sample_data.json +77 -0
- package/entities/tasks/tasks.config.ts +79 -0
- package/entities/tasks/tasks.fields.ts +196 -0
- package/entities/tasks/tasks.service.ts +541 -0
- package/entities/tasks/tasks.types.ts +56 -0
- package/lib/hooks/useAiChat.ts +114 -0
- package/lib/hooks/useConversations.ts +376 -0
- package/lib/hooks/useOrchestratorChat.ts +122 -0
- package/lib/hooks/usePersistentChat.ts +315 -0
- package/lib/hooks/useStreamingChat.ts +127 -0
- package/lib/hooks/useTokenUsage.ts +63 -0
- package/lib/langchain/agents/customer-assistant.md +69 -0
- package/lib/langchain/agents/index.ts +61 -0
- package/lib/langchain/agents/orchestrator.md +59 -0
- package/lib/langchain/agents/page-assistant.md +85 -0
- package/lib/langchain/agents/single-agent.md +46 -0
- package/lib/langchain/agents/task-assistant.md +55 -0
- package/lib/langchain/config.ts +45 -0
- package/lib/langchain/handlers/customer-handler.ts +338 -0
- package/lib/langchain/handlers/page-handler.ts +232 -0
- package/lib/langchain/handlers/task-handler.ts +323 -0
- package/lib/langchain/langchain.config.ts +223 -0
- package/lib/langchain/observability.config.ts +30 -0
- package/lib/langchain/orchestrator.ts +562 -0
- package/lib/langchain/tools/customers.ts +176 -0
- package/lib/langchain/tools/index.ts +10 -0
- package/lib/langchain/tools/orchestrator.ts +92 -0
- package/lib/langchain/tools/pages.ts +289 -0
- package/lib/langchain/tools/tasks.ts +167 -0
- package/lib/scheduled-actions/billing.ts +149 -0
- package/lib/scheduled-actions/index.ts +170 -0
- package/lib/scheduled-actions/webhook.ts +231 -0
- package/lib/selectors.ts +197 -0
- package/messages/de/admin.json +219 -0
- package/messages/de/aiUsage.json +36 -0
- package/messages/de/buttons.json +19 -0
- package/messages/de/categories.json +35 -0
- package/messages/de/common.json +16 -0
- package/messages/de/dev.json +101 -0
- package/messages/de/docs.json +27 -0
- package/messages/de/entities.json +7 -0
- package/messages/de/features.json +119 -0
- package/messages/de/footer.json +22 -0
- package/messages/de/home.json +57 -0
- package/messages/de/index.ts +39 -0
- package/messages/de/mobileNav.json +13 -0
- package/messages/de/navigation.json +8 -0
- package/messages/de/observability.json +74 -0
- package/messages/de/posts.json +54 -0
- package/messages/de/pricing.json +102 -0
- package/messages/de/support.json +9 -0
- package/messages/de/teams.json +8 -0
- package/messages/en/admin.json +219 -0
- package/messages/en/aiUsage.json +36 -0
- package/messages/en/buttons.json +19 -0
- package/messages/en/categories.json +35 -0
- package/messages/en/common.json +16 -0
- package/messages/en/dev.json +106 -0
- package/messages/en/docs.json +27 -0
- package/messages/en/entities.json +7 -0
- package/messages/en/features.json +119 -0
- package/messages/en/footer.json +22 -0
- package/messages/en/home.json +57 -0
- package/messages/en/index.ts +39 -0
- package/messages/en/mobileNav.json +13 -0
- package/messages/en/navigation.json +8 -0
- package/messages/en/observability.json +74 -0
- package/messages/en/posts.json +54 -0
- package/messages/en/pricing.json +102 -0
- package/messages/en/support.json +9 -0
- package/messages/en/teams.json +8 -0
- package/messages/es/admin.json +219 -0
- package/messages/es/aiUsage.json +36 -0
- package/messages/es/buttons.json +19 -0
- package/messages/es/categories.json +35 -0
- package/messages/es/common.json +16 -0
- package/messages/es/dev.json +101 -0
- package/messages/es/docs.json +27 -0
- package/messages/es/entities.json +7 -0
- package/messages/es/features.json +119 -0
- package/messages/es/footer.json +22 -0
- package/messages/es/home.json +57 -0
- package/messages/es/index.ts +39 -0
- package/messages/es/mobileNav.json +13 -0
- package/messages/es/navigation.json +8 -0
- package/messages/es/observability.json +74 -0
- package/messages/es/posts.json +54 -0
- package/messages/es/pricing.json +102 -0
- package/messages/es/support.json +9 -0
- package/messages/es/teams.json +8 -0
- package/messages/fr/admin.json +219 -0
- package/messages/fr/aiUsage.json +36 -0
- package/messages/fr/buttons.json +19 -0
- package/messages/fr/categories.json +35 -0
- package/messages/fr/common.json +16 -0
- package/messages/fr/dev.json +101 -0
- package/messages/fr/docs.json +27 -0
- package/messages/fr/entities.json +7 -0
- package/messages/fr/features.json +119 -0
- package/messages/fr/footer.json +22 -0
- package/messages/fr/home.json +57 -0
- package/messages/fr/index.ts +39 -0
- package/messages/fr/mobileNav.json +13 -0
- package/messages/fr/navigation.json +8 -0
- package/messages/fr/observability.json +74 -0
- package/messages/fr/posts.json +54 -0
- package/messages/fr/pricing.json +102 -0
- package/messages/fr/support.json +9 -0
- package/messages/fr/teams.json +8 -0
- package/messages/it/admin.json +219 -0
- package/messages/it/aiUsage.json +36 -0
- package/messages/it/buttons.json +19 -0
- package/messages/it/categories.json +35 -0
- package/messages/it/common.json +16 -0
- package/messages/it/dev.json +101 -0
- package/messages/it/docs.json +27 -0
- package/messages/it/entities.json +7 -0
- package/messages/it/features.json +119 -0
- package/messages/it/footer.json +22 -0
- package/messages/it/home.json +57 -0
- package/messages/it/index.ts +39 -0
- package/messages/it/mobileNav.json +13 -0
- package/messages/it/navigation.json +8 -0
- package/messages/it/observability.json +74 -0
- package/messages/it/posts.json +54 -0
- package/messages/it/pricing.json +102 -0
- package/messages/it/support.json +9 -0
- package/messages/it/teams.json +8 -0
- package/messages/pt/admin.json +219 -0
- package/messages/pt/aiUsage.json +36 -0
- package/messages/pt/buttons.json +19 -0
- package/messages/pt/categories.json +35 -0
- package/messages/pt/common.json +16 -0
- package/messages/pt/dev.json +101 -0
- package/messages/pt/docs.json +27 -0
- package/messages/pt/entities.json +7 -0
- package/messages/pt/features.json +119 -0
- package/messages/pt/footer.json +22 -0
- package/messages/pt/home.json +57 -0
- package/messages/pt/index.ts +39 -0
- package/messages/pt/mobileNav.json +13 -0
- package/messages/pt/navigation.json +8 -0
- package/messages/pt/observability.json +74 -0
- package/messages/pt/posts.json +54 -0
- package/messages/pt/pricing.json +102 -0
- package/messages/pt/support.json +9 -0
- package/messages/pt/teams.json +8 -0
- package/migrations/089_add_editor_team_role.sql +39 -0
- package/migrations/090_demo_users_teams.sql +540 -0
- package/migrations/091_greek_teams_billing.sql +523 -0
- package/migrations/092_billing_sample_data.sql +774 -0
- package/migrations/093_pages_sample_data.sql +1158 -0
- package/migrations/094_posts_sample_data.sql +278 -0
- package/migrations/095_tasks_sample_data.sql +440 -0
- package/migrations/096_customers_sample_data.sql +358 -0
- package/migrations/097_scheduled_actions_sample_data.sql +111 -0
- package/package.json +22 -0
- package/public/docs/desktop-layout-example.png +0 -0
- package/styles/components.css +11 -0
- package/styles/globals.css +179 -0
- package/templates/(public)/blog/[slug]/page.tsx +65 -0
- package/templates/(public)/layout.tsx +25 -0
- package/templates/(public)/page.tsx +200 -0
- package/templates/(public)/support/page.tsx +321 -0
- package/templates/dashboard/(main)/agent-multi/page.tsx +63 -0
- package/templates/dashboard/(main)/agent-single/page.tsx +142 -0
- package/templates/dashboard/(main)/settings/ai-usage/page.tsx +157 -0
- package/templates/superadmin/ai-observability/[traceId]/page.tsx +27 -0
- package/templates/superadmin/ai-observability/page.tsx +17 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
import {
|
|
3
|
+
baseContentFields,
|
|
4
|
+
baseDesignFields,
|
|
5
|
+
baseAdvancedFields,
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Features Grid Block Field Definitions
|
|
10
|
+
*
|
|
11
|
+
* Organized into 3 tabs:
|
|
12
|
+
* - Content: title, description, cta (from base) + items array
|
|
13
|
+
* - Design: backgroundColor (from base) + columns
|
|
14
|
+
* - Advanced: className, id (from base)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Features-specific content fields
|
|
18
|
+
const featuresContentFields: FieldDefinition[] = [
|
|
19
|
+
{
|
|
20
|
+
name: 'items',
|
|
21
|
+
label: 'Features',
|
|
22
|
+
type: 'array',
|
|
23
|
+
tab: 'content',
|
|
24
|
+
required: true,
|
|
25
|
+
description: 'List of features to display in the grid',
|
|
26
|
+
helpText: 'Add up to 12 features with icon, title, and description',
|
|
27
|
+
minItems: 1,
|
|
28
|
+
maxItems: 12,
|
|
29
|
+
itemFields: [
|
|
30
|
+
{
|
|
31
|
+
name: 'icon',
|
|
32
|
+
label: 'Icon Name',
|
|
33
|
+
type: 'text',
|
|
34
|
+
tab: 'content',
|
|
35
|
+
required: true,
|
|
36
|
+
placeholder: 'Zap',
|
|
37
|
+
helpText: 'Lucide icon name (e.g., Zap, Shield, Star, Check)',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'title',
|
|
41
|
+
label: 'Feature Title',
|
|
42
|
+
type: 'text',
|
|
43
|
+
tab: 'content',
|
|
44
|
+
required: true,
|
|
45
|
+
placeholder: 'Lightning Fast',
|
|
46
|
+
maxLength: 100,
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'description',
|
|
50
|
+
label: 'Description',
|
|
51
|
+
type: 'textarea',
|
|
52
|
+
tab: 'content',
|
|
53
|
+
required: true,
|
|
54
|
+
placeholder: 'Describe this feature...',
|
|
55
|
+
maxLength: 300,
|
|
56
|
+
rows: 2,
|
|
57
|
+
},
|
|
58
|
+
],
|
|
59
|
+
},
|
|
60
|
+
]
|
|
61
|
+
|
|
62
|
+
// Features-specific design fields
|
|
63
|
+
const featuresDesignFields: FieldDefinition[] = [
|
|
64
|
+
{
|
|
65
|
+
name: 'columns',
|
|
66
|
+
label: 'Grid Columns',
|
|
67
|
+
type: 'select',
|
|
68
|
+
tab: 'design',
|
|
69
|
+
required: false,
|
|
70
|
+
default: '3',
|
|
71
|
+
description: 'Number of columns in the grid layout',
|
|
72
|
+
options: [
|
|
73
|
+
{ label: '2 Columns', value: '2' },
|
|
74
|
+
{ label: '3 Columns', value: '3' },
|
|
75
|
+
{ label: '4 Columns', value: '4' },
|
|
76
|
+
],
|
|
77
|
+
},
|
|
78
|
+
]
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Complete field definitions organized by tab
|
|
82
|
+
*/
|
|
83
|
+
export const fieldDefinitions: FieldDefinition[] = [
|
|
84
|
+
// Content tab: base fields + features-specific
|
|
85
|
+
...baseContentFields,
|
|
86
|
+
...featuresContentFields,
|
|
87
|
+
|
|
88
|
+
// Design tab: base fields + features-specific
|
|
89
|
+
...baseDesignFields,
|
|
90
|
+
...featuresDesignFields,
|
|
91
|
+
|
|
92
|
+
// Advanced tab: base fields only
|
|
93
|
+
...baseAdvancedFields,
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
// Alias for compatibility
|
|
97
|
+
export const fields = fieldDefinitions
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { baseBlockSchema } from '@nextsparkjs/core/types/blocks'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Feature Item Schema
|
|
6
|
+
* Individual feature in the grid
|
|
7
|
+
*/
|
|
8
|
+
const featureItemSchema = z.object({
|
|
9
|
+
icon: z.string().min(1, 'Icon name is required'),
|
|
10
|
+
title: z.string().min(1, 'Feature title is required').max(100),
|
|
11
|
+
description: z.string().min(1, 'Description is required').max(300),
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
export type FeatureItem = z.infer<typeof featureItemSchema>
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Features Grid Block Schema
|
|
18
|
+
*
|
|
19
|
+
* Extends base schema with:
|
|
20
|
+
* - items: Array of feature items (icon, title, description)
|
|
21
|
+
* - columns: Grid layout option (2, 3, 4 columns)
|
|
22
|
+
*
|
|
23
|
+
* Note: Uses base schema title, description, cta, backgroundColor, className, id
|
|
24
|
+
*/
|
|
25
|
+
export const featuresGridSpecificSchema = z.object({
|
|
26
|
+
// Content: array of feature items
|
|
27
|
+
items: z.array(featureItemSchema)
|
|
28
|
+
.min(1, 'At least one feature is required')
|
|
29
|
+
.max(12, 'Maximum 12 features allowed'),
|
|
30
|
+
|
|
31
|
+
// Design: column layout
|
|
32
|
+
columns: z.enum(['2', '3', '4']).default('3'),
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Complete Features Grid Block Schema
|
|
37
|
+
*/
|
|
38
|
+
export const schema = baseBlockSchema.merge(featuresGridSpecificSchema)
|
|
39
|
+
|
|
40
|
+
export type FeaturesGridBlockProps = z.infer<typeof schema>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Placeholder thumbnail for features-grid block
|
|
@@ -0,0 +1,100 @@
|
|
|
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 { HeroBlockProps } from './schema'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Hero Block Component
|
|
10
|
+
*
|
|
11
|
+
* Props from 3-tab structure:
|
|
12
|
+
* - Content: title, content, cta
|
|
13
|
+
* - Design: backgroundColor, backgroundImage, textColor
|
|
14
|
+
* - Advanced: className, id
|
|
15
|
+
*/
|
|
16
|
+
export function HeroBlock({
|
|
17
|
+
// Base content props
|
|
18
|
+
title,
|
|
19
|
+
content,
|
|
20
|
+
cta,
|
|
21
|
+
// Base design props
|
|
22
|
+
backgroundColor,
|
|
23
|
+
// Hero-specific design
|
|
24
|
+
backgroundImage,
|
|
25
|
+
textColor = 'light',
|
|
26
|
+
// Base advanced props
|
|
27
|
+
className,
|
|
28
|
+
id,
|
|
29
|
+
// Legacy props for backward compatibility
|
|
30
|
+
...legacyProps
|
|
31
|
+
}: HeroBlockProps & {
|
|
32
|
+
ctaText?: string
|
|
33
|
+
ctaLink?: string
|
|
34
|
+
subtitle?: string
|
|
35
|
+
description?: string
|
|
36
|
+
}) {
|
|
37
|
+
// Handle legacy CTA format (ctaText, ctaLink) for backward compatibility
|
|
38
|
+
const ctaConfig = cta || (legacyProps.ctaText ? {
|
|
39
|
+
text: legacyProps.ctaText,
|
|
40
|
+
link: legacyProps.ctaLink || '#',
|
|
41
|
+
target: '_self' as const,
|
|
42
|
+
} : undefined)
|
|
43
|
+
|
|
44
|
+
// Handle legacy subtitle/description props for backward compatibility
|
|
45
|
+
const displayContent = content || legacyProps.subtitle || legacyProps.description
|
|
46
|
+
|
|
47
|
+
// Build section classes with background and custom className
|
|
48
|
+
const sectionClasses = buildSectionClasses(
|
|
49
|
+
cn(
|
|
50
|
+
'relative flex min-h-[600px] items-center justify-center overflow-hidden px-4 py-20',
|
|
51
|
+
textColor === 'light' ? 'text-white' : 'text-gray-900'
|
|
52
|
+
),
|
|
53
|
+
{ backgroundColor, className }
|
|
54
|
+
)
|
|
55
|
+
|
|
56
|
+
return (
|
|
57
|
+
<section id={id} className={sectionClasses} data-cy={sel('blocks.hero.container')}>
|
|
58
|
+
{/* Background Image */}
|
|
59
|
+
{backgroundImage && (
|
|
60
|
+
<div
|
|
61
|
+
className="absolute inset-0 z-0"
|
|
62
|
+
style={{
|
|
63
|
+
backgroundImage: `url(${backgroundImage})`,
|
|
64
|
+
backgroundSize: 'cover',
|
|
65
|
+
backgroundPosition: 'center',
|
|
66
|
+
}}
|
|
67
|
+
>
|
|
68
|
+
<div className="absolute inset-0 bg-black/40" />
|
|
69
|
+
</div>
|
|
70
|
+
)}
|
|
71
|
+
|
|
72
|
+
{/* Content */}
|
|
73
|
+
<div className="container relative z-10 mx-auto max-w-4xl text-center">
|
|
74
|
+
{title && (
|
|
75
|
+
<h1 className="mb-6 text-5xl font-bold leading-tight md:text-6xl lg:text-7xl">
|
|
76
|
+
{title}
|
|
77
|
+
</h1>
|
|
78
|
+
)}
|
|
79
|
+
|
|
80
|
+
{displayContent && (
|
|
81
|
+
<p className="mb-8 text-xl md:text-2xl opacity-90">
|
|
82
|
+
{displayContent}
|
|
83
|
+
</p>
|
|
84
|
+
)}
|
|
85
|
+
|
|
86
|
+
{ctaConfig && (
|
|
87
|
+
<Button asChild size="lg" className="text-lg px-8 py-6">
|
|
88
|
+
<a
|
|
89
|
+
href={ctaConfig.link}
|
|
90
|
+
target={ctaConfig.target}
|
|
91
|
+
rel={ctaConfig.target === '_blank' ? 'noopener noreferrer' : undefined}
|
|
92
|
+
>
|
|
93
|
+
{ctaConfig.text}
|
|
94
|
+
</a>
|
|
95
|
+
</Button>
|
|
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: 'hero',
|
|
5
|
+
name: 'Hero Section',
|
|
6
|
+
description: 'Full-width hero section with title, subtitle, CTA button, and background image',
|
|
7
|
+
category: 'hero',
|
|
8
|
+
icon: 'Rocket',
|
|
9
|
+
thumbnail: '/theme/blocks/hero/thumbnail.png',
|
|
10
|
+
scope: ['pages', 'posts']
|
|
11
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { BlockExample } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
|
|
3
|
+
export const examples: BlockExample[] = [
|
|
4
|
+
{
|
|
5
|
+
name: 'Default',
|
|
6
|
+
description: 'Standard hero with dark background',
|
|
7
|
+
props: {
|
|
8
|
+
title: 'Build Your Next Big Idea',
|
|
9
|
+
content: 'The complete platform for launching and scaling your SaaS application. From authentication to payments, we handle the infrastructure so you can focus on building features.',
|
|
10
|
+
cta: {
|
|
11
|
+
text: 'Get Started Free',
|
|
12
|
+
link: '/signup',
|
|
13
|
+
target: '_self',
|
|
14
|
+
},
|
|
15
|
+
backgroundColor: 'gray-900',
|
|
16
|
+
textColor: 'light',
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: 'With Background Image',
|
|
21
|
+
description: 'Hero with background image overlay',
|
|
22
|
+
props: {
|
|
23
|
+
title: 'Transform Your Business',
|
|
24
|
+
content: 'Join thousands of teams who trust our platform to power their most critical workflows.',
|
|
25
|
+
cta: {
|
|
26
|
+
text: 'Schedule Demo',
|
|
27
|
+
link: '/demo',
|
|
28
|
+
target: '_self',
|
|
29
|
+
},
|
|
30
|
+
backgroundColor: 'gray-900',
|
|
31
|
+
backgroundImage: 'https://images.unsplash.com/photo-1451187580459-43490279c0fa?w=1920',
|
|
32
|
+
textColor: 'light',
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
]
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
import {
|
|
3
|
+
baseContentFields,
|
|
4
|
+
baseDesignFields,
|
|
5
|
+
baseAdvancedFields,
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Hero Block Field Definitions
|
|
10
|
+
*
|
|
11
|
+
* Organized into 3 tabs:
|
|
12
|
+
* - Content: title, content, cta (from base)
|
|
13
|
+
* - Design: backgroundColor (from base) + backgroundImage, textColor
|
|
14
|
+
* - Advanced: className, id (from base)
|
|
15
|
+
*
|
|
16
|
+
* Note: The `content` field from base serves as the hero subtitle/description
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Hero-specific design fields
|
|
20
|
+
const heroDesignFields: FieldDefinition[] = [
|
|
21
|
+
{
|
|
22
|
+
name: 'backgroundImage',
|
|
23
|
+
label: 'Background Image',
|
|
24
|
+
type: 'image',
|
|
25
|
+
tab: 'design',
|
|
26
|
+
required: false,
|
|
27
|
+
helpText: 'Optional background image (recommended: 1920x1080px minimum)',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'textColor',
|
|
31
|
+
label: 'Text Color',
|
|
32
|
+
type: 'select',
|
|
33
|
+
tab: 'design',
|
|
34
|
+
required: false,
|
|
35
|
+
default: 'light',
|
|
36
|
+
helpText: 'Choose text color based on background',
|
|
37
|
+
options: [
|
|
38
|
+
{ label: 'Light (for dark backgrounds)', value: 'light' },
|
|
39
|
+
{ label: 'Dark (for light backgrounds)', value: 'dark' },
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
]
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Complete field definitions organized by tab
|
|
46
|
+
*/
|
|
47
|
+
export const fieldDefinitions: FieldDefinition[] = [
|
|
48
|
+
// Content tab: base fields only (title, content, cta)
|
|
49
|
+
...baseContentFields,
|
|
50
|
+
|
|
51
|
+
// Design tab: base fields + hero-specific
|
|
52
|
+
...baseDesignFields,
|
|
53
|
+
...heroDesignFields,
|
|
54
|
+
|
|
55
|
+
// Advanced tab: base fields only
|
|
56
|
+
...baseAdvancedFields,
|
|
57
|
+
]
|
|
58
|
+
|
|
59
|
+
// Alias for compatibility
|
|
60
|
+
export const fields = fieldDefinitions
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import {
|
|
3
|
+
baseBlockSchema,
|
|
4
|
+
type BaseBlockProps,
|
|
5
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Hero Block Schema
|
|
9
|
+
*
|
|
10
|
+
* Extends base schema with hero-specific fields:
|
|
11
|
+
* - backgroundImage: Optional hero background
|
|
12
|
+
* - textColor: Light/dark for contrast
|
|
13
|
+
*
|
|
14
|
+
* Note: Uses base schema title, content, cta, backgroundColor, className, id
|
|
15
|
+
* The `content` field serves as the hero subtitle/description
|
|
16
|
+
*/
|
|
17
|
+
export const heroSpecificSchema = z.object({
|
|
18
|
+
// Hero-specific design fields
|
|
19
|
+
backgroundImage: z.string().url('Must be a valid URL').optional(),
|
|
20
|
+
textColor: z.enum(['light', 'dark']).default('light'),
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Complete Hero Block Schema
|
|
25
|
+
* Combines base fields + hero-specific fields
|
|
26
|
+
*/
|
|
27
|
+
export const schema = baseBlockSchema.merge(heroSpecificSchema)
|
|
28
|
+
|
|
29
|
+
export type HeroBlockProps = z.infer<typeof schema>
|
|
30
|
+
|
|
31
|
+
// Also export for type-only imports
|
|
32
|
+
export type { BaseBlockProps }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Placeholder thumbnail for hero block
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<!-- This is a placeholder. In production, replace with actual PNG image -->
|
|
2
|
+
<!-- SVG placeholder for Hero block thumbnail -->
|
|
3
|
+
<svg width="400" height="300" xmlns="http://www.w3.org/2000/svg">
|
|
4
|
+
<rect width="400" height="300" fill="#6366f1"/>
|
|
5
|
+
<text x="200" y="150" font-family="Arial" font-size="24" fill="white" text-anchor="middle">Hero Section</text>
|
|
6
|
+
</svg>
|
|
@@ -0,0 +1,232 @@
|
|
|
1
|
+
'use client'
|
|
2
|
+
|
|
3
|
+
import React from 'react'
|
|
4
|
+
import { Button } from '@nextsparkjs/core/components/ui/button'
|
|
5
|
+
import { Input } from '@nextsparkjs/core/components/ui/input'
|
|
6
|
+
import { Checkbox } from '@nextsparkjs/core/components/ui/checkbox'
|
|
7
|
+
import {
|
|
8
|
+
Select,
|
|
9
|
+
SelectContent,
|
|
10
|
+
SelectItem,
|
|
11
|
+
SelectTrigger,
|
|
12
|
+
SelectValue,
|
|
13
|
+
} from '@nextsparkjs/core/components/ui/select'
|
|
14
|
+
import { cn } from '@nextsparkjs/core/lib/utils'
|
|
15
|
+
import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
|
|
16
|
+
import { sel } from '../../lib/selectors'
|
|
17
|
+
import type { HeroWithFormBlockProps } from './schema'
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Hero With Form Block Component
|
|
21
|
+
*
|
|
22
|
+
* Props from 3-tab structure:
|
|
23
|
+
* - Content: title, subtitle, backgroundImage, form fields
|
|
24
|
+
* - Design: backgroundColor, overlayOpacity
|
|
25
|
+
* - Advanced: className, id
|
|
26
|
+
*/
|
|
27
|
+
export function HeroWithFormBlock({
|
|
28
|
+
// Base content props
|
|
29
|
+
title,
|
|
30
|
+
subtitle,
|
|
31
|
+
backgroundImage,
|
|
32
|
+
// Form content props
|
|
33
|
+
formTitle = 'Get Started',
|
|
34
|
+
formSubtitle,
|
|
35
|
+
firstNamePlaceholder = 'First Name',
|
|
36
|
+
lastNamePlaceholder = 'Last Name',
|
|
37
|
+
emailPlaceholder = 'Email',
|
|
38
|
+
phonePlaceholder = 'Phone',
|
|
39
|
+
areaOfInterestPlaceholder = 'Area of Interest',
|
|
40
|
+
areaOfInterestOptions,
|
|
41
|
+
consentCheckboxLabel,
|
|
42
|
+
submitButtonText = 'Submit',
|
|
43
|
+
legalDisclaimer,
|
|
44
|
+
termsLinkText = 'Terms of Service',
|
|
45
|
+
termsLinkUrl,
|
|
46
|
+
privacyLinkText = 'Privacy Policy',
|
|
47
|
+
privacyLinkUrl,
|
|
48
|
+
formAction,
|
|
49
|
+
// Design props
|
|
50
|
+
backgroundColor,
|
|
51
|
+
overlayOpacity = '40',
|
|
52
|
+
// Advanced props
|
|
53
|
+
className,
|
|
54
|
+
id,
|
|
55
|
+
}: HeroWithFormBlockProps) {
|
|
56
|
+
// Build section classes with background and custom className
|
|
57
|
+
const sectionClasses = buildSectionClasses(
|
|
58
|
+
'relative min-h-screen',
|
|
59
|
+
{ backgroundColor, className }
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
// Calculate overlay opacity class
|
|
63
|
+
const overlayClass = overlayOpacity === '0'
|
|
64
|
+
? 'bg-transparent'
|
|
65
|
+
: `bg-black/${overlayOpacity}`
|
|
66
|
+
|
|
67
|
+
// Parse area of interest options (handle both \n and actual newlines)
|
|
68
|
+
const areaOptions = areaOfInterestOptions
|
|
69
|
+
? areaOfInterestOptions
|
|
70
|
+
.split(/\\n|\n/)
|
|
71
|
+
.map((opt: string) => opt.trim())
|
|
72
|
+
.filter(Boolean)
|
|
73
|
+
: []
|
|
74
|
+
|
|
75
|
+
return (
|
|
76
|
+
<section id={id} className={sectionClasses} data-cy={sel('blocks.heroWithForm.container')}>
|
|
77
|
+
{/* Background Image with overlay - full coverage */}
|
|
78
|
+
<div className="absolute inset-0">
|
|
79
|
+
<div
|
|
80
|
+
className="h-full w-full"
|
|
81
|
+
style={{
|
|
82
|
+
backgroundImage: `url(${backgroundImage})`,
|
|
83
|
+
backgroundSize: 'cover',
|
|
84
|
+
backgroundPosition: 'center',
|
|
85
|
+
}}
|
|
86
|
+
/>
|
|
87
|
+
<div className={cn('absolute inset-0', overlayClass)} />
|
|
88
|
+
</div>
|
|
89
|
+
|
|
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">
|
|
93
|
+
|
|
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">
|
|
96
|
+
{title && (
|
|
97
|
+
<h1 className="text-4xl lg:text-5xl xl:text-6xl font-bold italic mb-4 leading-tight">
|
|
98
|
+
{title}
|
|
99
|
+
</h1>
|
|
100
|
+
)}
|
|
101
|
+
{subtitle && (
|
|
102
|
+
<p className="text-lg lg:text-xl xl:text-2xl opacity-90 max-w-lg">
|
|
103
|
+
{subtitle}
|
|
104
|
+
</p>
|
|
105
|
+
)}
|
|
106
|
+
</div>
|
|
107
|
+
|
|
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">
|
|
111
|
+
{/* Form Header */}
|
|
112
|
+
{formTitle && (
|
|
113
|
+
<h2 className="text-xl font-bold text-center text-primary mb-2">
|
|
114
|
+
{formTitle}
|
|
115
|
+
</h2>
|
|
116
|
+
)}
|
|
117
|
+
{formSubtitle && (
|
|
118
|
+
<p className="text-sm text-center text-muted-foreground mb-6">
|
|
119
|
+
{formSubtitle}
|
|
120
|
+
</p>
|
|
121
|
+
)}
|
|
122
|
+
|
|
123
|
+
{/* Form */}
|
|
124
|
+
<form action={formAction} method="POST" className="space-y-4">
|
|
125
|
+
<Input
|
|
126
|
+
placeholder={firstNamePlaceholder}
|
|
127
|
+
name="firstName"
|
|
128
|
+
required
|
|
129
|
+
data-cy={sel('blocks.heroWithForm.form.firstname')}
|
|
130
|
+
/>
|
|
131
|
+
|
|
132
|
+
<Input
|
|
133
|
+
placeholder={lastNamePlaceholder}
|
|
134
|
+
name="lastName"
|
|
135
|
+
required
|
|
136
|
+
data-cy={sel('blocks.heroWithForm.form.lastname')}
|
|
137
|
+
/>
|
|
138
|
+
|
|
139
|
+
<Input
|
|
140
|
+
type="email"
|
|
141
|
+
placeholder={emailPlaceholder}
|
|
142
|
+
name="email"
|
|
143
|
+
required
|
|
144
|
+
data-cy={sel('blocks.heroWithForm.form.email')}
|
|
145
|
+
/>
|
|
146
|
+
|
|
147
|
+
<Input
|
|
148
|
+
type="tel"
|
|
149
|
+
placeholder={phonePlaceholder}
|
|
150
|
+
name="phone"
|
|
151
|
+
data-cy={sel('blocks.heroWithForm.form.phone')}
|
|
152
|
+
/>
|
|
153
|
+
|
|
154
|
+
{areaOptions.length > 0 && (
|
|
155
|
+
<Select name="areaOfInterest">
|
|
156
|
+
<SelectTrigger data-cy={sel('blocks.heroWithForm.form.area')}>
|
|
157
|
+
<SelectValue placeholder={areaOfInterestPlaceholder} />
|
|
158
|
+
</SelectTrigger>
|
|
159
|
+
<SelectContent>
|
|
160
|
+
{areaOptions.map((option: string, index: number) => (
|
|
161
|
+
<SelectItem key={index} value={option}>
|
|
162
|
+
{option}
|
|
163
|
+
</SelectItem>
|
|
164
|
+
))}
|
|
165
|
+
</SelectContent>
|
|
166
|
+
</Select>
|
|
167
|
+
)}
|
|
168
|
+
|
|
169
|
+
{consentCheckboxLabel && (
|
|
170
|
+
<div className="flex items-start gap-3">
|
|
171
|
+
<Checkbox
|
|
172
|
+
id="consent"
|
|
173
|
+
name="consent"
|
|
174
|
+
className="mt-0.5"
|
|
175
|
+
data-cy={sel('blocks.heroWithForm.form.consent')}
|
|
176
|
+
/>
|
|
177
|
+
<label
|
|
178
|
+
htmlFor="consent"
|
|
179
|
+
className="text-sm text-muted-foreground leading-tight cursor-pointer"
|
|
180
|
+
>
|
|
181
|
+
{consentCheckboxLabel}
|
|
182
|
+
</label>
|
|
183
|
+
</div>
|
|
184
|
+
)}
|
|
185
|
+
|
|
186
|
+
<Button
|
|
187
|
+
type="submit"
|
|
188
|
+
className="w-full"
|
|
189
|
+
size="lg"
|
|
190
|
+
data-cy={sel('blocks.heroWithForm.form.submit')}
|
|
191
|
+
>
|
|
192
|
+
{submitButtonText}
|
|
193
|
+
</Button>
|
|
194
|
+
</form>
|
|
195
|
+
|
|
196
|
+
{/* Legal Disclaimer */}
|
|
197
|
+
{(legalDisclaimer || termsLinkUrl || privacyLinkUrl) && (
|
|
198
|
+
<p className="text-xs text-muted-foreground mt-4 leading-relaxed">
|
|
199
|
+
{legalDisclaimer && <span>{legalDisclaimer} </span>}
|
|
200
|
+
{termsLinkUrl && (
|
|
201
|
+
<>
|
|
202
|
+
<a
|
|
203
|
+
href={termsLinkUrl}
|
|
204
|
+
className="underline hover:text-primary"
|
|
205
|
+
target="_blank"
|
|
206
|
+
rel="noopener noreferrer"
|
|
207
|
+
>
|
|
208
|
+
{termsLinkText}
|
|
209
|
+
</a>
|
|
210
|
+
{privacyLinkUrl && <span> y </span>}
|
|
211
|
+
</>
|
|
212
|
+
)}
|
|
213
|
+
{privacyLinkUrl && (
|
|
214
|
+
<a
|
|
215
|
+
href={privacyLinkUrl}
|
|
216
|
+
className="underline hover:text-primary"
|
|
217
|
+
target="_blank"
|
|
218
|
+
rel="noopener noreferrer"
|
|
219
|
+
>
|
|
220
|
+
{privacyLinkText}
|
|
221
|
+
</a>
|
|
222
|
+
)}
|
|
223
|
+
</p>
|
|
224
|
+
)}
|
|
225
|
+
</div>
|
|
226
|
+
</div>
|
|
227
|
+
|
|
228
|
+
</div>
|
|
229
|
+
</div>
|
|
230
|
+
</section>
|
|
231
|
+
)
|
|
232
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
|
|
3
|
+
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
|
+
slug: 'hero-with-form',
|
|
5
|
+
name: 'Hero With Form',
|
|
6
|
+
description: 'Full-width hero section with background image, title/subtitle on the left, and a lead capture form card on the right',
|
|
7
|
+
category: 'hero',
|
|
8
|
+
icon: 'FileText',
|
|
9
|
+
thumbnail: '/theme/blocks/hero-with-form/thumbnail.png',
|
|
10
|
+
scope: ['pages']
|
|
11
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { BlockExample } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
|
|
3
|
+
export const examples: BlockExample[] = [
|
|
4
|
+
{
|
|
5
|
+
name: 'Default',
|
|
6
|
+
description: 'Hero with email signup form',
|
|
7
|
+
props: {
|
|
8
|
+
title: 'Start Growing Your Business Today',
|
|
9
|
+
content: 'Join over 10,000 businesses using our platform to streamline their operations and boost productivity.',
|
|
10
|
+
formPlaceholder: 'Enter your email',
|
|
11
|
+
formButtonText: 'Get Started',
|
|
12
|
+
backgroundColor: 'primary',
|
|
13
|
+
textColor: 'light',
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
]
|