@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,165 @@
|
|
|
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
|
+
* Post Content Block Field Definitions
|
|
10
|
+
*
|
|
11
|
+
* Organized into 3 tabs:
|
|
12
|
+
* - Content: title, cta (from base) + content (rich-text, replaces base content)
|
|
13
|
+
* - Design: backgroundColor (from base) + editorial typography options
|
|
14
|
+
* - Advanced: className, id (from base)
|
|
15
|
+
*
|
|
16
|
+
* Note: The `content` field is overridden with a rich-text version for editorial content
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// Filter out base content field (we'll replace it with rich-text version)
|
|
20
|
+
const baseContentFieldsWithoutContent = baseContentFields.filter(
|
|
21
|
+
(field) => field.name !== 'content'
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
// Post-content-specific content fields (rich-text content)
|
|
25
|
+
const postContentFields: FieldDefinition[] = [
|
|
26
|
+
{
|
|
27
|
+
name: 'content',
|
|
28
|
+
label: 'Article Content',
|
|
29
|
+
type: 'rich-text',
|
|
30
|
+
tab: 'content',
|
|
31
|
+
required: true,
|
|
32
|
+
placeholder: 'Write your article content here...',
|
|
33
|
+
helpText: 'Main article body with rich text formatting support',
|
|
34
|
+
},
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
// Post-content-specific design fields (editorial styling)
|
|
38
|
+
const postDesignFields: FieldDefinition[] = [
|
|
39
|
+
// Drop cap section
|
|
40
|
+
{
|
|
41
|
+
name: 'showDropCap',
|
|
42
|
+
label: 'Show Drop Cap',
|
|
43
|
+
type: 'checkbox',
|
|
44
|
+
tab: 'design',
|
|
45
|
+
required: false,
|
|
46
|
+
default: false,
|
|
47
|
+
helpText: 'Display a decorative large first letter',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'dropCapStyle',
|
|
51
|
+
label: 'Drop Cap Style',
|
|
52
|
+
type: 'select',
|
|
53
|
+
tab: 'design',
|
|
54
|
+
required: false,
|
|
55
|
+
default: 'serif',
|
|
56
|
+
helpText: 'Visual style for the drop cap',
|
|
57
|
+
options: [
|
|
58
|
+
{ label: 'Serif (Classic)', value: 'serif' },
|
|
59
|
+
{ label: 'Sans-Serif (Modern)', value: 'sans-serif' },
|
|
60
|
+
{ label: 'Decorative', value: 'decorative' },
|
|
61
|
+
],
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
// Typography section
|
|
65
|
+
{
|
|
66
|
+
name: 'maxWidth',
|
|
67
|
+
label: 'Reading Width',
|
|
68
|
+
type: 'select',
|
|
69
|
+
tab: 'design',
|
|
70
|
+
required: false,
|
|
71
|
+
default: 'narrow',
|
|
72
|
+
helpText: 'Optimal reading width for long-form content',
|
|
73
|
+
options: [
|
|
74
|
+
{ label: 'Narrow (680px) - Optimal for reading', value: 'narrow' },
|
|
75
|
+
{ label: 'Medium (768px)', value: 'medium' },
|
|
76
|
+
{ label: 'Wide (900px)', value: 'wide' },
|
|
77
|
+
],
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'fontSize',
|
|
81
|
+
label: 'Base Font Size',
|
|
82
|
+
type: 'select',
|
|
83
|
+
tab: 'design',
|
|
84
|
+
required: false,
|
|
85
|
+
default: 'medium',
|
|
86
|
+
helpText: 'Base font size for article text',
|
|
87
|
+
options: [
|
|
88
|
+
{ label: 'Small (16px)', value: 'small' },
|
|
89
|
+
{ label: 'Medium (18px) - Recommended', value: 'medium' },
|
|
90
|
+
{ label: 'Large (20px)', value: 'large' },
|
|
91
|
+
],
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
name: 'lineHeight',
|
|
95
|
+
label: 'Line Spacing',
|
|
96
|
+
type: 'select',
|
|
97
|
+
tab: 'design',
|
|
98
|
+
required: false,
|
|
99
|
+
default: 'relaxed',
|
|
100
|
+
helpText: 'Vertical spacing between lines',
|
|
101
|
+
options: [
|
|
102
|
+
{ label: 'Compact (1.6)', value: 'compact' },
|
|
103
|
+
{ label: 'Normal (1.7)', value: 'normal' },
|
|
104
|
+
{ label: 'Relaxed (1.8) - Recommended', value: 'relaxed' },
|
|
105
|
+
],
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
name: 'paragraphSpacing',
|
|
109
|
+
label: 'Paragraph Spacing',
|
|
110
|
+
type: 'select',
|
|
111
|
+
tab: 'design',
|
|
112
|
+
required: false,
|
|
113
|
+
default: 'normal',
|
|
114
|
+
helpText: 'Vertical spacing between paragraphs',
|
|
115
|
+
options: [
|
|
116
|
+
{ label: 'Tight', value: 'tight' },
|
|
117
|
+
{ label: 'Normal', value: 'normal' },
|
|
118
|
+
{ label: 'Loose', value: 'loose' },
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
|
|
122
|
+
// Dividers section
|
|
123
|
+
{
|
|
124
|
+
name: 'showDividers',
|
|
125
|
+
label: 'Show Section Dividers',
|
|
126
|
+
type: 'checkbox',
|
|
127
|
+
tab: 'design',
|
|
128
|
+
required: false,
|
|
129
|
+
default: false,
|
|
130
|
+
helpText: 'Display subtle dividers between content sections',
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
name: 'dividerStyle',
|
|
134
|
+
label: 'Divider Style',
|
|
135
|
+
type: 'select',
|
|
136
|
+
tab: 'design',
|
|
137
|
+
required: false,
|
|
138
|
+
default: 'line',
|
|
139
|
+
helpText: 'Visual style for section dividers',
|
|
140
|
+
options: [
|
|
141
|
+
{ label: 'Line', value: 'line' },
|
|
142
|
+
{ label: 'Dots (•••)', value: 'dots' },
|
|
143
|
+
{ label: 'Asterisks (***)', value: 'asterisks' },
|
|
144
|
+
],
|
|
145
|
+
},
|
|
146
|
+
]
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Complete field definitions organized by tab
|
|
150
|
+
*/
|
|
151
|
+
export const fieldDefinitions: FieldDefinition[] = [
|
|
152
|
+
// Content tab: base fields (without content) + rich-text content
|
|
153
|
+
...baseContentFieldsWithoutContent,
|
|
154
|
+
...postContentFields,
|
|
155
|
+
|
|
156
|
+
// Design tab: base fields + editorial-specific
|
|
157
|
+
...baseDesignFields,
|
|
158
|
+
...postDesignFields,
|
|
159
|
+
|
|
160
|
+
// Advanced tab: base fields only (ALWAYS last)
|
|
161
|
+
...baseAdvancedFields,
|
|
162
|
+
]
|
|
163
|
+
|
|
164
|
+
// Alias for compatibility
|
|
165
|
+
export const fields = fieldDefinitions
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { baseBlockSchema } from '@nextsparkjs/core/types/blocks'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Post Content Block Schema
|
|
6
|
+
*
|
|
7
|
+
* Extends base schema with editorial-focused fields:
|
|
8
|
+
* - content: Main article content (overrides base content with required)
|
|
9
|
+
* - showDropCap: Display decorative drop cap on first letter
|
|
10
|
+
* - dropCapStyle: Style variant for the drop cap
|
|
11
|
+
* - maxWidth: Reading width control for optimal typography
|
|
12
|
+
* - fontSize: Base font size for content
|
|
13
|
+
* - lineHeight: Line spacing for readability
|
|
14
|
+
* - paragraphSpacing: Vertical spacing between paragraphs
|
|
15
|
+
* - showDividers: Show subtle section dividers
|
|
16
|
+
* - dividerStyle: Visual style for dividers
|
|
17
|
+
*
|
|
18
|
+
* Note: Uses base schema title, cta, backgroundColor, className, id
|
|
19
|
+
* The `content` field is overridden to be required and serves as the main article body
|
|
20
|
+
*/
|
|
21
|
+
export const postContentSpecificSchema = z.object({
|
|
22
|
+
// Content: rich text body (overrides base optional content)
|
|
23
|
+
content: z.string().min(1, 'Content is required'),
|
|
24
|
+
|
|
25
|
+
// Design: drop cap styling
|
|
26
|
+
showDropCap: z.boolean().default(false),
|
|
27
|
+
dropCapStyle: z.enum(['serif', 'sans-serif', 'decorative']).default('serif'),
|
|
28
|
+
|
|
29
|
+
// Design: layout and typography
|
|
30
|
+
maxWidth: z.enum(['narrow', 'medium', 'wide']).default('narrow'),
|
|
31
|
+
fontSize: z.enum(['small', 'medium', 'large']).default('medium'),
|
|
32
|
+
lineHeight: z.enum(['compact', 'normal', 'relaxed']).default('relaxed'),
|
|
33
|
+
paragraphSpacing: z.enum(['tight', 'normal', 'loose']).default('normal'),
|
|
34
|
+
|
|
35
|
+
// Design: section dividers
|
|
36
|
+
showDividers: z.boolean().default(false),
|
|
37
|
+
dividerStyle: z.enum(['line', 'dots', 'asterisks']).default('line'),
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Complete Post Content Block Schema
|
|
42
|
+
* Note: postContentSpecificSchema.content overrides baseBlockSchema.content
|
|
43
|
+
*/
|
|
44
|
+
export const schema = baseBlockSchema.merge(postContentSpecificSchema)
|
|
45
|
+
|
|
46
|
+
export type PostContentBlockProps = z.infer<typeof schema>
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Button } from '@nextsparkjs/core/components/ui/button'
|
|
3
|
+
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@nextsparkjs/core/components/ui/card'
|
|
4
|
+
import { Check } from 'lucide-react'
|
|
5
|
+
import { cn } from '@nextsparkjs/core/lib/utils'
|
|
6
|
+
import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
|
|
7
|
+
import { sel } from '../../lib/selectors'
|
|
8
|
+
import type { PricingTableBlockProps, PlanItem } from './schema'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Pricing Table Block Component
|
|
12
|
+
*
|
|
13
|
+
* Props from 3-tab structure:
|
|
14
|
+
* - Content: title, content, plans
|
|
15
|
+
* - Design: backgroundColor, columns, highlightPopular
|
|
16
|
+
* - Advanced: className, id
|
|
17
|
+
*/
|
|
18
|
+
export function PricingTableBlock({
|
|
19
|
+
// Base content props
|
|
20
|
+
title,
|
|
21
|
+
content,
|
|
22
|
+
// Pricing-specific content
|
|
23
|
+
plans,
|
|
24
|
+
// Base design props
|
|
25
|
+
backgroundColor,
|
|
26
|
+
// Pricing-specific design
|
|
27
|
+
columns = '3',
|
|
28
|
+
highlightPopular = true,
|
|
29
|
+
// Base advanced props
|
|
30
|
+
className,
|
|
31
|
+
id,
|
|
32
|
+
}: PricingTableBlockProps) {
|
|
33
|
+
// Parse features from newline-separated string
|
|
34
|
+
const parseFeatures = (features?: string): string[] => {
|
|
35
|
+
if (!features) return []
|
|
36
|
+
return features.split('\n').map(f => f.trim()).filter(Boolean)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Build column classes based on columns prop
|
|
40
|
+
const columnClasses: Record<string, string> = {
|
|
41
|
+
'2': 'sm:grid-cols-2',
|
|
42
|
+
'3': 'sm:grid-cols-2 lg:grid-cols-3',
|
|
43
|
+
'4': 'sm:grid-cols-2 lg:grid-cols-4',
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Build section classes with background and custom className
|
|
47
|
+
const sectionClasses = buildSectionClasses(
|
|
48
|
+
'py-16 px-4 md:py-24',
|
|
49
|
+
{ backgroundColor, className }
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
// Safe plans array (fallback to empty array)
|
|
53
|
+
const safePlans = Array.isArray(plans) ? plans : []
|
|
54
|
+
|
|
55
|
+
return (
|
|
56
|
+
<section id={id} className={sectionClasses} data-cy={sel('blocks.pricingTable.container')}>
|
|
57
|
+
<div className="container mx-auto max-w-7xl">
|
|
58
|
+
{/* Section Header */}
|
|
59
|
+
{(title || content) && (
|
|
60
|
+
<div className="mb-12 text-center">
|
|
61
|
+
{title && (
|
|
62
|
+
<h2 className="mb-4 text-4xl font-bold md:text-5xl">
|
|
63
|
+
{title}
|
|
64
|
+
</h2>
|
|
65
|
+
)}
|
|
66
|
+
{content && (
|
|
67
|
+
<p className="mx-auto max-w-2xl text-lg text-muted-foreground">
|
|
68
|
+
{content}
|
|
69
|
+
</p>
|
|
70
|
+
)}
|
|
71
|
+
</div>
|
|
72
|
+
)}
|
|
73
|
+
|
|
74
|
+
{/* Pricing Plans Grid */}
|
|
75
|
+
<div className={cn('grid gap-8', columnClasses[columns] || columnClasses['3'])}>
|
|
76
|
+
{safePlans.map((plan: PlanItem, index: number) => {
|
|
77
|
+
const features = parseFeatures(plan.features)
|
|
78
|
+
const isHighlighted = highlightPopular && plan.isPopular
|
|
79
|
+
|
|
80
|
+
return (
|
|
81
|
+
<Card
|
|
82
|
+
key={index}
|
|
83
|
+
className={cn(
|
|
84
|
+
'relative flex flex-col',
|
|
85
|
+
isHighlighted && 'border-primary shadow-lg scale-105',
|
|
86
|
+
plan.isDisabled && 'opacity-60'
|
|
87
|
+
)}
|
|
88
|
+
data-cy={sel('blocks.pricingTable.plan', { index: String(index) })}
|
|
89
|
+
>
|
|
90
|
+
{/* Popular Badge */}
|
|
91
|
+
{isHighlighted && (
|
|
92
|
+
<div className="absolute -top-3 left-1/2 -translate-x-1/2">
|
|
93
|
+
<span className="bg-primary text-primary-foreground text-xs font-semibold px-3 py-1 rounded-full">
|
|
94
|
+
Popular
|
|
95
|
+
</span>
|
|
96
|
+
</div>
|
|
97
|
+
)}
|
|
98
|
+
|
|
99
|
+
{/* Card Header */}
|
|
100
|
+
<CardHeader className="text-center pb-8">
|
|
101
|
+
<CardTitle className="text-2xl mb-2">{plan.name}</CardTitle>
|
|
102
|
+
<div className="flex items-baseline justify-center gap-1">
|
|
103
|
+
<span className="text-4xl font-bold">{plan.price}</span>
|
|
104
|
+
{plan.period && (
|
|
105
|
+
<span className="text-muted-foreground">{plan.period}</span>
|
|
106
|
+
)}
|
|
107
|
+
</div>
|
|
108
|
+
{plan.description && (
|
|
109
|
+
<CardDescription className="mt-2">{plan.description}</CardDescription>
|
|
110
|
+
)}
|
|
111
|
+
</CardHeader>
|
|
112
|
+
|
|
113
|
+
{/* Card Content */}
|
|
114
|
+
<CardContent className="flex-1 flex flex-col">
|
|
115
|
+
{/* Features List */}
|
|
116
|
+
{features.length > 0 && (
|
|
117
|
+
<ul className="space-y-3 mb-6 flex-1" data-cy={sel('blocks.pricingTable.features')}>
|
|
118
|
+
{features.map((feature: string, i: number) => (
|
|
119
|
+
<li key={i} className="flex items-start gap-2">
|
|
120
|
+
<Check className="h-5 w-5 text-primary shrink-0 mt-0.5" />
|
|
121
|
+
<span className="text-sm text-muted-foreground">{feature}</span>
|
|
122
|
+
</li>
|
|
123
|
+
))}
|
|
124
|
+
</ul>
|
|
125
|
+
)}
|
|
126
|
+
|
|
127
|
+
{/* CTA Button */}
|
|
128
|
+
{plan.ctaText && plan.ctaUrl && (
|
|
129
|
+
<Button
|
|
130
|
+
asChild
|
|
131
|
+
className="w-full"
|
|
132
|
+
variant={isHighlighted ? 'default' : 'outline'}
|
|
133
|
+
disabled={plan.isDisabled}
|
|
134
|
+
data-cy={sel('blocks.pricingTable.cta', { index: String(index) })}
|
|
135
|
+
>
|
|
136
|
+
<a href={plan.ctaUrl}>{plan.ctaText}</a>
|
|
137
|
+
</Button>
|
|
138
|
+
)}
|
|
139
|
+
|
|
140
|
+
{/* Disabled State Message */}
|
|
141
|
+
{plan.isDisabled && !plan.ctaText && (
|
|
142
|
+
<div className="text-center text-sm text-muted-foreground">
|
|
143
|
+
Coming Soon
|
|
144
|
+
</div>
|
|
145
|
+
)}
|
|
146
|
+
</CardContent>
|
|
147
|
+
</Card>
|
|
148
|
+
)
|
|
149
|
+
})}
|
|
150
|
+
</div>
|
|
151
|
+
</div>
|
|
152
|
+
</section>
|
|
153
|
+
)
|
|
154
|
+
}
|
|
@@ -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: 'pricing-table',
|
|
5
|
+
name: 'Pricing Table',
|
|
6
|
+
description: 'A pricing comparison table showing different plans with features list, price, CTA button, and optional "Popular" badge',
|
|
7
|
+
category: 'pricing',
|
|
8
|
+
icon: 'DollarSign',
|
|
9
|
+
thumbnail: '/theme/blocks/pricing-table/thumbnail.png',
|
|
10
|
+
scope: ['pages']
|
|
11
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import type { BlockExample } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
|
|
3
|
+
export const examples: BlockExample[] = [
|
|
4
|
+
{
|
|
5
|
+
name: 'Standard',
|
|
6
|
+
description: 'Three-tier pricing without highlight',
|
|
7
|
+
props: {
|
|
8
|
+
title: 'Simple, Transparent Pricing',
|
|
9
|
+
content: 'Choose the plan that fits your needs. All plans include 14-day free trial.',
|
|
10
|
+
backgroundColor: 'white',
|
|
11
|
+
columns: '3',
|
|
12
|
+
highlightPopular: false,
|
|
13
|
+
plans: [
|
|
14
|
+
{
|
|
15
|
+
name: 'Starter',
|
|
16
|
+
price: '$29',
|
|
17
|
+
period: 'per month',
|
|
18
|
+
description: 'Perfect for small teams',
|
|
19
|
+
features: 'Up to 5 team members\n10GB storage\nEmail support\nBasic analytics',
|
|
20
|
+
ctaText: 'Start Free Trial',
|
|
21
|
+
ctaUrl: '/signup?plan=starter',
|
|
22
|
+
isPopular: false,
|
|
23
|
+
isDisabled: false,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: 'Professional',
|
|
27
|
+
price: '$99',
|
|
28
|
+
period: 'per month',
|
|
29
|
+
description: 'For growing businesses',
|
|
30
|
+
features: 'Up to 25 team members\n100GB storage\nPriority support\nAdvanced analytics\nCustom integrations',
|
|
31
|
+
ctaText: 'Start Free Trial',
|
|
32
|
+
ctaUrl: '/signup?plan=pro',
|
|
33
|
+
isPopular: false,
|
|
34
|
+
isDisabled: false,
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
name: 'Enterprise',
|
|
38
|
+
price: 'Custom',
|
|
39
|
+
period: '',
|
|
40
|
+
description: 'For large organizations',
|
|
41
|
+
features: 'Unlimited team members\nUnlimited storage\n24/7 dedicated support\nCustom analytics\nAPI access\nSSO & SAML',
|
|
42
|
+
ctaText: 'Contact Sales',
|
|
43
|
+
ctaUrl: '/contact',
|
|
44
|
+
isPopular: false,
|
|
45
|
+
isDisabled: false,
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'With Highlight',
|
|
52
|
+
description: 'Pricing with highlighted popular plan',
|
|
53
|
+
props: {
|
|
54
|
+
title: 'Pricing That Grows With You',
|
|
55
|
+
content: 'Start free, upgrade when you need more',
|
|
56
|
+
backgroundColor: 'gray-50',
|
|
57
|
+
columns: '3',
|
|
58
|
+
highlightPopular: true,
|
|
59
|
+
plans: [
|
|
60
|
+
{
|
|
61
|
+
name: 'Basic',
|
|
62
|
+
price: '$0',
|
|
63
|
+
period: 'forever free',
|
|
64
|
+
description: 'Get started at no cost',
|
|
65
|
+
features: 'Up to 3 team members\n5GB storage\nCommunity support\nBasic features',
|
|
66
|
+
ctaText: 'Get Started',
|
|
67
|
+
ctaUrl: '/signup?plan=basic',
|
|
68
|
+
isPopular: false,
|
|
69
|
+
isDisabled: false,
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
name: 'Pro',
|
|
73
|
+
price: '$49',
|
|
74
|
+
period: 'per month',
|
|
75
|
+
description: 'Most popular choice',
|
|
76
|
+
features: 'Up to 15 team members\n50GB storage\nPriority support\nAll features\nAdvanced analytics\nIntegrations',
|
|
77
|
+
ctaText: 'Start Free Trial',
|
|
78
|
+
ctaUrl: '/signup?plan=pro',
|
|
79
|
+
isPopular: true,
|
|
80
|
+
isDisabled: false,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'Business',
|
|
84
|
+
price: '$199',
|
|
85
|
+
period: 'per month',
|
|
86
|
+
description: 'For serious teams',
|
|
87
|
+
features: 'Unlimited team members\n500GB storage\n24/7 support\nAll Pro features\nCustom workflows\nDedicated manager',
|
|
88
|
+
ctaText: 'Start Free Trial',
|
|
89
|
+
ctaUrl: '/signup?plan=business',
|
|
90
|
+
isPopular: false,
|
|
91
|
+
isDisabled: false,
|
|
92
|
+
},
|
|
93
|
+
],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
]
|
|
@@ -0,0 +1,161 @@
|
|
|
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
|
+
* Pricing Table Block Field Definitions
|
|
10
|
+
*
|
|
11
|
+
* Organized into 3 tabs:
|
|
12
|
+
* - Content: title, content (from base) + plans array
|
|
13
|
+
* - Design: backgroundColor (from base) + columns + highlightPopular
|
|
14
|
+
* - Advanced: className, id (from base)
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
// Pricing-specific content fields
|
|
18
|
+
const pricingContentFields: FieldDefinition[] = [
|
|
19
|
+
{
|
|
20
|
+
name: 'plans',
|
|
21
|
+
label: 'Pricing Plans',
|
|
22
|
+
type: 'array',
|
|
23
|
+
tab: 'content',
|
|
24
|
+
required: true,
|
|
25
|
+
description: 'List of pricing plans to display',
|
|
26
|
+
helpText: 'Add up to 4 pricing plans with features and CTA',
|
|
27
|
+
minItems: 1,
|
|
28
|
+
maxItems: 4,
|
|
29
|
+
itemFields: [
|
|
30
|
+
{
|
|
31
|
+
name: 'name',
|
|
32
|
+
label: 'Plan Name',
|
|
33
|
+
type: 'text',
|
|
34
|
+
tab: 'content',
|
|
35
|
+
required: true,
|
|
36
|
+
placeholder: 'Starter',
|
|
37
|
+
maxLength: 50,
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
name: 'price',
|
|
41
|
+
label: 'Price',
|
|
42
|
+
type: 'text',
|
|
43
|
+
tab: 'content',
|
|
44
|
+
required: true,
|
|
45
|
+
placeholder: '$29',
|
|
46
|
+
maxLength: 50,
|
|
47
|
+
helpText: 'Price display (e.g., "$29", "Free", "$99")',
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
name: 'period',
|
|
51
|
+
label: 'Billing Period',
|
|
52
|
+
type: 'text',
|
|
53
|
+
tab: 'content',
|
|
54
|
+
required: false,
|
|
55
|
+
placeholder: '/month',
|
|
56
|
+
maxLength: 50,
|
|
57
|
+
helpText: 'Billing period (e.g., "/month", "/year", "one-time")',
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
name: 'description',
|
|
61
|
+
label: 'Plan Description',
|
|
62
|
+
type: 'text',
|
|
63
|
+
tab: 'content',
|
|
64
|
+
required: false,
|
|
65
|
+
placeholder: 'Perfect for getting started',
|
|
66
|
+
maxLength: 200,
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
name: 'features',
|
|
70
|
+
label: 'Features (one per line)',
|
|
71
|
+
type: 'textarea',
|
|
72
|
+
tab: 'content',
|
|
73
|
+
required: false,
|
|
74
|
+
placeholder: 'Unlimited projects\n24/7 support\nAPI access',
|
|
75
|
+
rows: 4,
|
|
76
|
+
helpText: 'Enter each feature on a new line',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
name: 'ctaText',
|
|
80
|
+
label: 'Button Text',
|
|
81
|
+
type: 'text',
|
|
82
|
+
tab: 'content',
|
|
83
|
+
required: false,
|
|
84
|
+
placeholder: 'Get Started',
|
|
85
|
+
maxLength: 50,
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
name: 'ctaUrl',
|
|
89
|
+
label: 'Button Link',
|
|
90
|
+
type: 'url',
|
|
91
|
+
tab: 'content',
|
|
92
|
+
required: false,
|
|
93
|
+
placeholder: '/signup',
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
name: 'isPopular',
|
|
97
|
+
label: 'Mark as "Popular"',
|
|
98
|
+
type: 'checkbox',
|
|
99
|
+
tab: 'content',
|
|
100
|
+
required: false,
|
|
101
|
+
default: false,
|
|
102
|
+
helpText: 'Show "Popular" badge on this plan',
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
name: 'isDisabled',
|
|
106
|
+
label: 'Disable this plan',
|
|
107
|
+
type: 'checkbox',
|
|
108
|
+
tab: 'content',
|
|
109
|
+
required: false,
|
|
110
|
+
default: false,
|
|
111
|
+
helpText: 'Gray out this plan (coming soon, unavailable)',
|
|
112
|
+
},
|
|
113
|
+
],
|
|
114
|
+
},
|
|
115
|
+
]
|
|
116
|
+
|
|
117
|
+
// Pricing-specific design fields
|
|
118
|
+
const pricingDesignFields: FieldDefinition[] = [
|
|
119
|
+
{
|
|
120
|
+
name: 'columns',
|
|
121
|
+
label: 'Grid Columns',
|
|
122
|
+
type: 'select',
|
|
123
|
+
tab: 'design',
|
|
124
|
+
required: false,
|
|
125
|
+
default: '3',
|
|
126
|
+
description: 'Number of columns in the pricing table',
|
|
127
|
+
options: [
|
|
128
|
+
{ label: '2 Columns', value: '2' },
|
|
129
|
+
{ label: '3 Columns', value: '3' },
|
|
130
|
+
{ label: '4 Columns', value: '4' },
|
|
131
|
+
],
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
name: 'highlightPopular',
|
|
135
|
+
label: 'Highlight Popular Plan',
|
|
136
|
+
type: 'checkbox',
|
|
137
|
+
tab: 'design',
|
|
138
|
+
required: false,
|
|
139
|
+
default: true,
|
|
140
|
+
description: 'Add border and shadow to popular plan',
|
|
141
|
+
},
|
|
142
|
+
]
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Complete field definitions organized by tab
|
|
146
|
+
*/
|
|
147
|
+
export const fieldDefinitions: FieldDefinition[] = [
|
|
148
|
+
// Content tab: base fields + pricing-specific
|
|
149
|
+
...baseContentFields,
|
|
150
|
+
...pricingContentFields,
|
|
151
|
+
|
|
152
|
+
// Design tab: base fields + pricing-specific
|
|
153
|
+
...baseDesignFields,
|
|
154
|
+
...pricingDesignFields,
|
|
155
|
+
|
|
156
|
+
// Advanced tab: base fields only
|
|
157
|
+
...baseAdvancedFields,
|
|
158
|
+
]
|
|
159
|
+
|
|
160
|
+
// Alias for compatibility
|
|
161
|
+
export const fields = fieldDefinitions
|