@duongthiu/onex-core 0.1.0

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.
@@ -0,0 +1,2961 @@
1
+ import React$1 from 'react';
2
+
3
+ /**
4
+ * Base Entity Interface
5
+ * Common fields for all entities in the system
6
+ * All entities should extend this for consistency
7
+ */
8
+ interface BaseEntity {
9
+ /** Unique identifier */
10
+ id: string;
11
+ /** Creation timestamp (ISO 8601) */
12
+ createdAt?: string;
13
+ /** Last update timestamp (ISO 8601) */
14
+ updatedAt?: string;
15
+ }
16
+
17
+ /**
18
+ * Website Settings Types
19
+ * Type definitions for dynamic website settings including social connections,
20
+ * hotline connections, tracking analytics, and contact information.
21
+ */
22
+ /**
23
+ * Icon definition for various settings items
24
+ */
25
+ interface SettingsIcon {
26
+ /** Icon filename */
27
+ name: string;
28
+ /** Icon URL or data URI */
29
+ url: string;
30
+ }
31
+ /**
32
+ * Social media platform types
33
+ */
34
+ type SocialPlatform = "facebook" | "instagram" | "tiktok" | "linkedin" | "zalo" | "discord" | "github" | "twitter" | "youtube" | "pinterest" | string;
35
+ /**
36
+ * Social media connection configuration
37
+ */
38
+ interface SocialConnection {
39
+ /** Unique identifier for this social connection */
40
+ id: string;
41
+ /** Display name of the platform */
42
+ name: string;
43
+ /** Platform icon */
44
+ icon: SettingsIcon;
45
+ /** URL link to the social media profile */
46
+ link: string;
47
+ /** Platform identifier */
48
+ platform: SocialPlatform;
49
+ /** Whether this connection is enabled and should be displayed */
50
+ enabled: boolean;
51
+ /** Display order (lower numbers appear first) */
52
+ order: string;
53
+ }
54
+ /**
55
+ * Hotline connection types
56
+ */
57
+ type HotlineType = "phone" | "email" | "whatsapp" | "telegram" | string;
58
+ /**
59
+ * Hotline contact configuration
60
+ */
61
+ interface HotlineConnection {
62
+ /** Unique identifier for this hotline */
63
+ id: string;
64
+ /** Display name of the contact method */
65
+ name: string;
66
+ /** Contact method icon */
67
+ icon: SettingsIcon;
68
+ /** Type of contact method */
69
+ type: HotlineType;
70
+ /** Contact value (phone number, email address, etc.) */
71
+ value: string;
72
+ /** Whether this hotline is enabled */
73
+ enabled: boolean;
74
+ /** Display order */
75
+ order: string;
76
+ }
77
+ /**
78
+ * Analytics tracking platform types
79
+ */
80
+ type TrackingPlatform = "google_analytics" | "meta_pixel" | "google_tag_manager" | "tiktok_pixel" | string;
81
+ /**
82
+ * Tracking analytics configuration
83
+ */
84
+ interface TrackingAnalytics {
85
+ /** Unique identifier for this tracking integration */
86
+ id: string;
87
+ /** Display name of the analytics platform */
88
+ name: string;
89
+ /** Platform icon */
90
+ icon: SettingsIcon;
91
+ /** Platform identifier */
92
+ platform: TrackingPlatform;
93
+ /** Tracking/Measurement ID */
94
+ tracking_id: string;
95
+ /** Whether this tracking is enabled */
96
+ enabled: boolean;
97
+ /** Display order */
98
+ order: string;
99
+ }
100
+ /**
101
+ * Contact email configuration
102
+ */
103
+ interface ContactEmail {
104
+ /** Email address for contact */
105
+ email: string;
106
+ /** Whether contact email is enabled */
107
+ enabled: boolean;
108
+ }
109
+ /**
110
+ * Company information configuration
111
+ */
112
+ interface CompanyInfo {
113
+ /** Company name */
114
+ name: string;
115
+ /** Company tagline/slogan */
116
+ tagline?: string;
117
+ /** Company description */
118
+ description?: string;
119
+ /** Company logo URL */
120
+ logo_url?: string;
121
+ /** Theme ID for this company */
122
+ themeId?: string;
123
+ }
124
+ /**
125
+ * Complete website settings structure
126
+ */
127
+ interface WebsiteSettings {
128
+ /** Social media connection configurations */
129
+ social_connections?: SocialConnection[];
130
+ /** Hotline contact configurations */
131
+ hotline_connections?: HotlineConnection[];
132
+ /** Tracking analytics configurations */
133
+ tracking_analytics?: TrackingAnalytics[];
134
+ /** Contact email configuration */
135
+ contact_email?: ContactEmail;
136
+ /** Company information */
137
+ company_info?: CompanyInfo;
138
+ /** Additional dynamic settings */
139
+ [key: string]: unknown;
140
+ }
141
+ /**
142
+ * Helper type to get only enabled items from an array
143
+ */
144
+ type EnabledItems<T extends {
145
+ enabled: boolean;
146
+ }> = T[];
147
+ /**
148
+ * Sorted and filtered social connections (enabled only)
149
+ */
150
+ type ActiveSocialConnections = SocialConnection[];
151
+ /**
152
+ * Sorted and filtered hotline connections (enabled only)
153
+ */
154
+ type ActiveHotlineConnections = HotlineConnection[];
155
+ /**
156
+ * Sorted and filtered tracking analytics (enabled only)
157
+ */
158
+ type ActiveTrackingAnalytics = TrackingAnalytics[];
159
+
160
+ /**
161
+ * Field Definition Types
162
+ * Used for defining customizable settings in sections, blocks, and themes
163
+ */
164
+
165
+ /**
166
+ * Field types - all available field types for component settings
167
+ */
168
+ declare const FIELD_TYPES: {
169
+ readonly TEXT: "text";
170
+ readonly TEXTAREA: "textarea";
171
+ readonly NUMBER: "number";
172
+ readonly CHECKBOX: "checkbox";
173
+ readonly BOOLEAN: "boolean";
174
+ readonly SELECT: "select";
175
+ readonly RADIO: "radio";
176
+ readonly RANGE: "range";
177
+ readonly URL: "url";
178
+ readonly RICHTEXT: "richtext";
179
+ readonly COLOR: "color";
180
+ readonly COLOR_BACKGROUND: "color_background";
181
+ readonly IMAGE: "image";
182
+ readonly IMAGE_PICKER: "image_picker";
183
+ readonly VIDEO: "video";
184
+ readonly VIDEO_URL: "video_url";
185
+ readonly FONT: "font";
186
+ readonly FONT_PICKER: "font_picker";
187
+ readonly INLINE_RICHTEXT: "inline_richtext";
188
+ readonly TEXT_ALIGNMENT: "text_alignment";
189
+ readonly HTML: "html";
190
+ readonly ARRAY: "array";
191
+ readonly REPEATER: "repeater";
192
+ readonly COLLECTION: "collection";
193
+ readonly PRODUCT: "product";
194
+ readonly BLOG: "blog";
195
+ readonly ARTICLE: "article";
196
+ readonly PAGE: "page";
197
+ };
198
+ type FieldType = (typeof FIELD_TYPES)[keyof typeof FIELD_TYPES];
199
+ interface BaseFieldDefinition {
200
+ /** Unique identifier for the field */
201
+ id: string;
202
+ /** Field type */
203
+ type: FieldType;
204
+ /** Display label */
205
+ label: string;
206
+ /** Help text or description */
207
+ info?: string;
208
+ /** Whether the field is required */
209
+ required?: boolean;
210
+ /** Placeholder text */
211
+ placeholder?: string;
212
+ }
213
+ interface TextFieldDefinition extends BaseFieldDefinition {
214
+ type: "text";
215
+ default?: string;
216
+ maxLength?: number;
217
+ }
218
+ interface TextareaFieldDefinition extends BaseFieldDefinition {
219
+ type: "textarea";
220
+ default?: string;
221
+ maxLength?: number;
222
+ rows?: number;
223
+ }
224
+ interface NumberFieldDefinition extends BaseFieldDefinition {
225
+ type: "number";
226
+ default?: number;
227
+ min?: number;
228
+ max?: number;
229
+ step?: number;
230
+ unit?: string;
231
+ }
232
+ interface RangeFieldDefinition extends BaseFieldDefinition {
233
+ type: "range";
234
+ default?: number;
235
+ min: number;
236
+ max: number;
237
+ step?: number;
238
+ unit?: string;
239
+ }
240
+ interface ColorFieldDefinition extends BaseFieldDefinition {
241
+ type: "color";
242
+ default?: string;
243
+ }
244
+ interface ImageFieldDefinition extends BaseFieldDefinition {
245
+ type: "image";
246
+ default?: string;
247
+ accept?: string[];
248
+ }
249
+ interface SelectFieldDefinition extends BaseFieldDefinition {
250
+ type: "select";
251
+ default?: string;
252
+ options: Array<{
253
+ label: string;
254
+ value: string;
255
+ }>;
256
+ }
257
+ interface CheckboxFieldDefinition extends BaseFieldDefinition {
258
+ type: "checkbox";
259
+ default?: boolean;
260
+ }
261
+ interface BooleanFieldDefinition extends BaseFieldDefinition {
262
+ type: "boolean";
263
+ default?: boolean;
264
+ }
265
+ interface RadioFieldDefinition extends BaseFieldDefinition {
266
+ type: "radio";
267
+ default?: string;
268
+ options: Array<{
269
+ label: string;
270
+ value: string;
271
+ }>;
272
+ }
273
+ interface UrlFieldDefinition extends BaseFieldDefinition {
274
+ type: "url";
275
+ default?: string;
276
+ }
277
+ interface RichTextFieldDefinition extends BaseFieldDefinition {
278
+ type: "richtext";
279
+ default?: string;
280
+ }
281
+ interface VideoFieldDefinition extends BaseFieldDefinition {
282
+ type: "video";
283
+ default?: string;
284
+ accept?: string[];
285
+ }
286
+ interface FontFieldDefinition extends BaseFieldDefinition {
287
+ type: "font";
288
+ default?: string;
289
+ }
290
+ interface ArrayFieldDefinition extends BaseFieldDefinition {
291
+ type: "array";
292
+ default?: unknown[];
293
+ itemSchema?: Record<string, unknown>;
294
+ }
295
+ interface CollectionFieldDefinition extends BaseFieldDefinition {
296
+ type: "collection";
297
+ default?: string;
298
+ }
299
+ interface ProductFieldDefinition extends BaseFieldDefinition {
300
+ type: "product";
301
+ default?: string;
302
+ }
303
+ interface BlogFieldDefinition extends BaseFieldDefinition {
304
+ type: "blog";
305
+ default?: string;
306
+ }
307
+ interface ArticleFieldDefinition extends BaseFieldDefinition {
308
+ type: "article";
309
+ default?: string;
310
+ }
311
+ interface PageFieldDefinition extends BaseFieldDefinition {
312
+ type: "page";
313
+ default?: string;
314
+ }
315
+ interface RepeaterFieldDefinition extends BaseFieldDefinition {
316
+ type: "repeater";
317
+ default?: unknown[];
318
+ itemFields?: FieldDefinition[];
319
+ }
320
+ interface TextAlignmentFieldDefinition extends BaseFieldDefinition {
321
+ type: "text_alignment";
322
+ default?: "left" | "center" | "right";
323
+ }
324
+ interface InlineRichTextFieldDefinition extends BaseFieldDefinition {
325
+ type: "inline_richtext";
326
+ default?: string;
327
+ maxLength?: number;
328
+ }
329
+ interface VideoUrlFieldDefinition extends BaseFieldDefinition {
330
+ type: "video_url";
331
+ default?: string;
332
+ accept?: ("youtube" | "vimeo")[];
333
+ }
334
+ interface HtmlFieldDefinition extends BaseFieldDefinition {
335
+ type: "html";
336
+ default?: string;
337
+ }
338
+ interface ColorBackgroundFieldDefinition extends BaseFieldDefinition {
339
+ type: "color_background";
340
+ default?: string;
341
+ supportsGradient?: boolean;
342
+ }
343
+ interface FontPickerFieldDefinition extends BaseFieldDefinition {
344
+ type: "font_picker";
345
+ default?: string;
346
+ }
347
+ interface ImagePickerFieldDefinition extends BaseFieldDefinition {
348
+ type: "image_picker";
349
+ default?: string;
350
+ accept?: string[];
351
+ }
352
+ /**
353
+ * Union type of all field definitions
354
+ */
355
+ type FieldDefinition = TextFieldDefinition | TextareaFieldDefinition | NumberFieldDefinition | RangeFieldDefinition | ColorFieldDefinition | ImageFieldDefinition | SelectFieldDefinition | CheckboxFieldDefinition | BooleanFieldDefinition | RadioFieldDefinition | UrlFieldDefinition | RichTextFieldDefinition | VideoFieldDefinition | FontFieldDefinition | ArrayFieldDefinition | RepeaterFieldDefinition | CollectionFieldDefinition | ProductFieldDefinition | BlogFieldDefinition | ArticleFieldDefinition | PageFieldDefinition | TextAlignmentFieldDefinition | InlineRichTextFieldDefinition | VideoUrlFieldDefinition | HtmlFieldDefinition | ColorBackgroundFieldDefinition | FontPickerFieldDefinition | ImagePickerFieldDefinition;
356
+ /**
357
+ * Setting Value Types
358
+ */
359
+ type SettingValue = string | number | boolean | string[] | unknown[] | undefined;
360
+ /**
361
+ * Settings object - maps field IDs to their values
362
+ * Extended with WebsiteSettings for dynamic website configuration
363
+ */
364
+ interface Settings extends WebsiteSettings {
365
+ [key: string]: SettingValue | unknown;
366
+ }
367
+
368
+ /**
369
+ * Animation Type Definitions
370
+ * Defines animation settings for components
371
+ */
372
+
373
+ /**
374
+ * Animation Types
375
+ */
376
+ type AnimationType = "fadeIn" | "fadeInUp" | "fadeInDown" | "fadeInLeft" | "fadeInRight" | "slideInUp" | "slideInDown" | "slideInLeft" | "slideInRight" | "scaleIn" | "scaleInUp" | "rotate" | "rotateIn" | "bounce" | "pulse" | "shake" | "flip" | "none";
377
+ /**
378
+ * Animation Easing Functions
379
+ */
380
+ type AnimationEasing = "linear" | "easeIn" | "easeOut" | "easeInOut" | "easeInBack" | "easeOutBack" | "easeInOutBack" | "easeInElastic" | "easeOutElastic" | "easeInOutElastic";
381
+ /**
382
+ * Animation Trigger
383
+ */
384
+ type AnimationTrigger = "onLoad" | "onScroll" | "onHover" | "onClick";
385
+ /**
386
+ * Animation Settings
387
+ */
388
+ interface AnimationSettings {
389
+ /** Animation type */
390
+ type: AnimationType;
391
+ /** Duration in seconds */
392
+ duration: number;
393
+ /** Delay in seconds */
394
+ delay: number;
395
+ /** Easing function */
396
+ easing: AnimationEasing;
397
+ /** When to trigger the animation */
398
+ trigger?: AnimationTrigger;
399
+ /** Repeat infinitely */
400
+ infinite?: boolean;
401
+ /** Number of iterations (if not infinite) */
402
+ iterations?: number;
403
+ /** Stagger animation for child elements */
404
+ stagger?: boolean;
405
+ /** Stagger delay between children (seconds) */
406
+ staggerDelay?: number;
407
+ }
408
+ /**
409
+ * Animation Field Definitions
410
+ * Use these in component schemas to add animation settings
411
+ */
412
+ declare const animationFieldDefinitions: FieldDefinition[];
413
+ /**
414
+ * Default animation settings
415
+ */
416
+ declare const defaultAnimationSettings: AnimationSettings;
417
+
418
+ /**
419
+ * Component Type Definitions
420
+ * Types for the component registry system
421
+ */
422
+
423
+ /**
424
+ * Responsive breakpoints
425
+ */
426
+ type Breakpoint = "mobile" | "tablet" | "desktop";
427
+ /**
428
+ * Style Settings
429
+ * Supports basic and advanced CSS properties
430
+ */
431
+ interface StyleSettings {
432
+ margin?: string;
433
+ marginTop?: string;
434
+ marginRight?: string;
435
+ marginBottom?: string;
436
+ marginLeft?: string;
437
+ padding?: string;
438
+ paddingTop?: string;
439
+ paddingRight?: string;
440
+ paddingBottom?: string;
441
+ paddingLeft?: string;
442
+ width?: string;
443
+ height?: string;
444
+ maxWidth?: string;
445
+ minWidth?: string;
446
+ minHeight?: string;
447
+ backgroundColor?: string;
448
+ color?: string;
449
+ borderColor?: string;
450
+ fontSize?: string;
451
+ fontWeight?: string;
452
+ lineHeight?: string;
453
+ textAlign?: "left" | "center" | "right" | "justify";
454
+ letterSpacing?: string;
455
+ textTransform?: string;
456
+ borderWidth?: string;
457
+ borderRadius?: string;
458
+ borderStyle?: "solid" | "dashed" | "dotted" | "none";
459
+ display?: string;
460
+ flexDirection?: string;
461
+ justifyContent?: string;
462
+ alignItems?: string;
463
+ gap?: string;
464
+ gridTemplateColumns?: string;
465
+ gridTemplateRows?: string;
466
+ position?: string;
467
+ top?: string;
468
+ right?: string;
469
+ bottom?: string;
470
+ left?: string;
471
+ zIndex?: string;
472
+ opacity?: string;
473
+ transform?: string;
474
+ transition?: string;
475
+ boxShadow?: string;
476
+ cursor?: string;
477
+ overflow?: string;
478
+ objectFit?: string;
479
+ aspectRatio?: string;
480
+ customClasses?: string;
481
+ [key: string]: SettingValue;
482
+ }
483
+ /**
484
+ * Responsive style settings
485
+ */
486
+ interface ResponsiveStyles {
487
+ mobile?: Partial<StyleSettings>;
488
+ tablet?: Partial<StyleSettings>;
489
+ desktop?: Partial<StyleSettings>;
490
+ }
491
+ /**
492
+ * Component Definition - Blueprint for a component type
493
+ */
494
+ interface ComponentDefinition {
495
+ /** Unique type identifier (e.g., 'heading', 'button') */
496
+ type: ComponentType;
497
+ /** Display name */
498
+ name: string;
499
+ /** Description */
500
+ description?: string;
501
+ /** Icon identifier */
502
+ icon?: string;
503
+ /** Category (text, media, interactive, layout) */
504
+ category: ComponentCategory;
505
+ /** Content settings (text, url, etc.) */
506
+ contentSettings: FieldDefinition[];
507
+ /** Style settings - Basic styles shown by default */
508
+ basicStyleSettings: FieldDefinition[];
509
+ /** Advanced style settings - Shown when user toggles advanced mode */
510
+ advancedStyleSettings: FieldDefinition[];
511
+ /** Default content values */
512
+ contentDefaults: Settings;
513
+ /** Default style values */
514
+ styleDefaults: StyleSettings;
515
+ /** Whether this component supports responsive styles */
516
+ supportsResponsive: boolean;
517
+ /** Tags for search */
518
+ tags?: string[];
519
+ }
520
+ /**
521
+ * Component Instance - Actual component in a section
522
+ */
523
+ interface ComponentInstance extends BaseEntity {
524
+ /** Component type reference */
525
+ type: ComponentType;
526
+ /** Content settings (text, url, image src, etc.) */
527
+ content: Settings;
528
+ /** Style settings */
529
+ style: StyleSettings;
530
+ /** Style mode - basic uses presets, advanced uses custom values */
531
+ styleMode?: "basic" | "advanced";
532
+ /** Responsive style overrides */
533
+ responsiveStyle?: ResponsiveStyles;
534
+ /** Display order */
535
+ order: number;
536
+ /** Whether enabled */
537
+ enabled?: boolean;
538
+ }
539
+ /**
540
+ * Component Registration - Runtime info
541
+ */
542
+ interface ComponentRegistration {
543
+ /** Component definition */
544
+ definition: ComponentDefinition;
545
+ /** React component */
546
+ component: React.ComponentType<ComponentProps>;
547
+ /** Registration timestamp */
548
+ registeredAt: Date;
549
+ /** Category */
550
+ category: ComponentCategory;
551
+ /** Tags */
552
+ tags: string[];
553
+ }
554
+ /**
555
+ * Props passed to component React components
556
+ */
557
+ interface ComponentProps {
558
+ /** Component instance data */
559
+ component: ComponentInstance;
560
+ /** Component definition */
561
+ definition: ComponentDefinition;
562
+ /** Section ID (for component detection) */
563
+ sectionId?: string;
564
+ /** Whether in edit mode */
565
+ isEditing?: boolean;
566
+ /** Additional data (e.g., website settings) */
567
+ data?: Record<string, unknown>;
568
+ /** Callback when content changes */
569
+ onContentChange?: (content: Settings) => void;
570
+ /** Callback when style changes */
571
+ onStyleChange?: (style: StyleSettings, breakpoint?: Breakpoint) => void;
572
+ /** Callback when component should be removed */
573
+ onRemove?: () => void;
574
+ /** Additional classes */
575
+ className?: string;
576
+ /** Children for container components */
577
+ children?: React.ReactNode;
578
+ }
579
+ /**
580
+ * Component categories
581
+ */
582
+ declare const COMPONENT_CATEGORIES: {
583
+ readonly TEXT: "text";
584
+ readonly MEDIA: "media";
585
+ readonly INTERACTIVE: "interactive";
586
+ readonly FORM: "form";
587
+ readonly LAYOUT: "layout";
588
+ readonly ADVANCED: "advanced";
589
+ };
590
+ type ComponentCategory = (typeof COMPONENT_CATEGORIES)[keyof typeof COMPONENT_CATEGORIES];
591
+ /**
592
+ * Component types - all available component types
593
+ */
594
+ declare const COMPONENT_TYPES: {
595
+ readonly INPUT: "input";
596
+ readonly TEXTAREA: "textarea";
597
+ readonly SELECT: "select";
598
+ readonly CHECKBOX: "checkbox";
599
+ readonly HEADING: "heading";
600
+ readonly PARAGRAPH: "paragraph";
601
+ readonly QUOTE: "quote";
602
+ readonly BADGE: "badge";
603
+ readonly COMPANY_INFO: "company-info";
604
+ readonly IMAGE: "image";
605
+ readonly VIDEO: "video";
606
+ readonly ICON: "icon";
607
+ readonly GALLERY: "gallery";
608
+ readonly BUTTON: "button";
609
+ readonly LINK: "link";
610
+ readonly RATING: "rating";
611
+ readonly SOCIAL_LINKS: "social-links";
612
+ readonly HOTLINE_CONTACTS: "hotline-contacts";
613
+ readonly GRID: "grid";
614
+ readonly COLUMNS: "columns";
615
+ readonly CARD: "card";
616
+ readonly CONTAINER: "container";
617
+ readonly DIVIDER: "divider";
618
+ readonly SPACER: "spacer";
619
+ readonly MAP: "map";
620
+ readonly PROGRESS: "progress";
621
+ readonly ALERT: "alert";
622
+ readonly CODE: "code";
623
+ readonly TIMER: "timer";
624
+ readonly ACCORDION: "accordion";
625
+ readonly TABS: "tabs";
626
+ readonly TABLE: "table";
627
+ readonly LIST: "list";
628
+ readonly FEATURE_CARD: "feature-card";
629
+ readonly PRODUCT_CARD: "product-card";
630
+ readonly BLOG_CARD: "blog-card";
631
+ };
632
+ type ComponentType = (typeof COMPONENT_TYPES)[keyof typeof COMPONENT_TYPES];
633
+ /**
634
+ * Apply scope - when changing component settings
635
+ */
636
+ type ApplyScope = "instance" | "all";
637
+ /**
638
+ * Apply scope dialog result
639
+ */
640
+ interface ApplyScopeResult {
641
+ scope: ApplyScope;
642
+ componentType: ComponentType;
643
+ }
644
+
645
+ /**
646
+ * Block Type Definitions
647
+ * Blocks are repeatable content units within sections
648
+ */
649
+
650
+ /**
651
+ * Block Definition - Schema for a type of block
652
+ */
653
+ interface BlockDefinition {
654
+ /** Unique type identifier (e.g., "testimonial-item") */
655
+ type: string;
656
+ /** Display name */
657
+ name: string;
658
+ /** Description of the block */
659
+ description?: string;
660
+ /** Icon identifier for UI */
661
+ icon?: string;
662
+ /** Category for organization */
663
+ category?: string;
664
+ /** Customizable settings */
665
+ settings: FieldDefinition[];
666
+ /** Default settings values */
667
+ defaults: Settings;
668
+ /** Maximum number of instances allowed in a section */
669
+ limit?: number;
670
+ /** Minimum number of instances required */
671
+ min?: number;
672
+ /** Whether this block type can be reordered */
673
+ sortable?: boolean;
674
+ /** Theme ID if this is a theme-specific block (undefined = shared) */
675
+ themeId?: string;
676
+ /** If true, this block overrides a shared block */
677
+ inherited?: boolean;
678
+ /** Reference to base block type if this is an override */
679
+ baseType?: string;
680
+ }
681
+ /**
682
+ * Data source types for blocks
683
+ */
684
+ type BlockDataSourceType = "manual" | "api" | "query" | "parent";
685
+ /**
686
+ * Data source configuration for blocks
687
+ * Enables blocks to fetch data from various sources
688
+ */
689
+ interface BlockDataSource {
690
+ /** Type of data source */
691
+ type: BlockDataSourceType;
692
+ /** API endpoint (e.g., "/api/products") */
693
+ endpoint?: string;
694
+ /** HTTP method */
695
+ method?: "GET" | "POST";
696
+ /** Query parameters or request body */
697
+ params?: Record<string, unknown>;
698
+ /** Custom headers */
699
+ headers?: Record<string, string>;
700
+ /** Collection/table name */
701
+ collection?: string;
702
+ /** Filter criteria */
703
+ filter?: object;
704
+ /** Sort order */
705
+ sort?: object;
706
+ /** Result limit */
707
+ limit?: number;
708
+ /** Key to read from parent block/section */
709
+ parentKey?: string;
710
+ /** Function name to transform fetched data */
711
+ transform?: string;
712
+ /** Cache configuration */
713
+ cache?: {
714
+ enabled: boolean;
715
+ duration: number;
716
+ key?: string;
717
+ };
718
+ }
719
+ /**
720
+ * Block Instance - Actual block data in a section
721
+ * Supports recursive nesting: blocks can contain components AND other blocks
722
+ * Supports API data sources for dynamic content
723
+ */
724
+ interface BlockInstance extends BaseEntity {
725
+ /** Block type reference */
726
+ type: string;
727
+ /** Current settings values */
728
+ settings?: Settings;
729
+ /** Block content (alternative to settings) */
730
+ content?: Record<string, unknown>;
731
+ /** Display order */
732
+ order: number;
733
+ /** Whether the block is currently enabled/visible */
734
+ enabled?: boolean;
735
+ /** Custom name for this instance (optional) */
736
+ customName?: string;
737
+ /** Custom style */
738
+ style?: Record<string, unknown>;
739
+ /** Animation settings */
740
+ animation?: Record<string, unknown>;
741
+ /** Optional theme context for this block instance */
742
+ themeContext?: string;
743
+ /** Data source configuration (manual, API, query, etc.) */
744
+ dataSource?: BlockDataSource;
745
+ /** Runtime data populated from data source (server-side) */
746
+ data?: Record<string, unknown>;
747
+ /** Loading state (for async data fetching) */
748
+ loading?: boolean;
749
+ /** Error state */
750
+ error?: string | null;
751
+ /** Components within this block */
752
+ components?: ComponentInstance[];
753
+ /** Nested blocks within this block (recursive!) */
754
+ blocks?: BlockInstance[];
755
+ }
756
+ /**
757
+ * Block Registration - Runtime registration info
758
+ */
759
+ interface BlockRegistration {
760
+ /** Block definition */
761
+ definition: BlockDefinition;
762
+ /** React component for rendering */
763
+ component: React.ComponentType<BlockComponentProps>;
764
+ /** Registration timestamp */
765
+ registeredAt: Date;
766
+ /** Tags for searching/filtering */
767
+ tags?: string[];
768
+ }
769
+ /**
770
+ * Props passed to block components
771
+ */
772
+ interface BlockComponentProps {
773
+ /** Block instance data */
774
+ block: BlockInstance;
775
+ /** Block definition */
776
+ definition: BlockDefinition;
777
+ /** Whether in edit mode */
778
+ isEditing?: boolean;
779
+ /** Section ID for nested block detection */
780
+ sectionId?: string;
781
+ /** Additional data (e.g., website settings) */
782
+ data?: Record<string, unknown>;
783
+ /** Callback when settings change */
784
+ onSettingsChange?: (settings: Settings) => void;
785
+ /** Callback when block is removed */
786
+ onRemove?: () => void;
787
+ /** Additional class names */
788
+ className?: string;
789
+ }
790
+
791
+ /**
792
+ * Section Type Definitions
793
+ * Sections are the main building blocks of pages
794
+ */
795
+
796
+ /**
797
+ * Template Definition - A variant layout for a section type
798
+ */
799
+ interface TemplateDefinition {
800
+ /** Unique template identifier (e.g., "default", "minimal", "split") */
801
+ id: string;
802
+ /** Display name */
803
+ name: string;
804
+ /** Description of this template variant */
805
+ description?: string;
806
+ /** Preview image URL */
807
+ preview?: string;
808
+ /** Template-specific settings (overrides section settings) */
809
+ settings?: FieldDefinition[];
810
+ /** Default settings for this template */
811
+ defaults?: Settings;
812
+ /** Whether this is the default template */
813
+ isDefault?: boolean;
814
+ }
815
+ /**
816
+ * Section Schema - Blueprint for a section type
817
+ */
818
+ interface SectionSchema {
819
+ /** Unique section type identifier (e.g., "hero", "features") */
820
+ type: string;
821
+ /** Display name */
822
+ name: string;
823
+ /** Description */
824
+ description?: string;
825
+ /** Category for organization (e.g., "headers", "content", "footers") */
826
+ category: string;
827
+ /** Icon identifier for UI */
828
+ icon?: string;
829
+ /** Available templates for this section */
830
+ templates: TemplateDefinition[];
831
+ /** Base settings (applied to all templates) */
832
+ settings: FieldDefinition[];
833
+ /** Default settings values */
834
+ defaults: Settings;
835
+ /** Block types that can be added to this section */
836
+ blocks?: BlockDefinition[];
837
+ /** Maximum number of blocks allowed */
838
+ maxBlocks?: number;
839
+ /** Whether blocks are sortable */
840
+ sortableBlocks?: boolean;
841
+ /** Whether this section is a global section (e.g., header, footer) */
842
+ global?: boolean;
843
+ /** Tags for searching/filtering */
844
+ tags?: string[];
845
+ /** Whether this section can be disabled */
846
+ disableable?: boolean;
847
+ }
848
+ /**
849
+ * Component Instance - Individual UI element with own settings
850
+ * Simplified version for sections - uses single settings object
851
+ * For detailed component instances, see ComponentInstance in component.ts
852
+ */
853
+ interface SectionComponentInstance extends BaseEntity {
854
+ /** Component type (e.g., "heading", "button", "image") */
855
+ type: string;
856
+ /** Component settings values (legacy - prefer content/style split) */
857
+ settings?: Settings;
858
+ /** Content settings (text, url, image src, etc.) */
859
+ content?: Settings;
860
+ /** Style settings */
861
+ style?: Settings;
862
+ /** Style mode - basic uses presets, advanced uses custom values */
863
+ styleMode?: "basic" | "advanced";
864
+ /** Display order in the section */
865
+ order: number;
866
+ /** Whether the component is enabled/visible */
867
+ enabled?: boolean;
868
+ }
869
+ /**
870
+ * Section Instance - Actual section data in a page
871
+ */
872
+ interface SectionInstance extends BaseEntity {
873
+ /** Section type reference */
874
+ type: string;
875
+ /** Selected template ID */
876
+ template: string;
877
+ /** Custom name for this instance */
878
+ name?: string;
879
+ /** Current settings values */
880
+ settings: Settings;
881
+ /** Component instances in this section (individual UI elements) */
882
+ components?: SectionComponentInstance[];
883
+ /** Block instances in this section */
884
+ blocks?: BlockInstance[];
885
+ /** Display order on the page */
886
+ order: number;
887
+ /** Whether the section is enabled/visible */
888
+ enabled?: boolean;
889
+ }
890
+ /**
891
+ * Section Registration - Runtime registration info
892
+ */
893
+ interface SectionRegistration<TProps = SectionComponentProps> {
894
+ /** Section schema */
895
+ schema: SectionSchema;
896
+ /** Base component (may be overridden by template) */
897
+ component: React.ComponentType<TProps>;
898
+ /** Template-specific components */
899
+ templateComponents: Map<string, React.ComponentType<SectionComponentProps>>;
900
+ /** Registration timestamp */
901
+ registeredAt: Date;
902
+ /** Category */
903
+ category: string;
904
+ /** Tags for searching */
905
+ tags: string[];
906
+ /** Lazy load function */
907
+ lazyLoad?: () => Promise<React.ComponentType<TProps>>;
908
+ }
909
+ /**
910
+ * Props passed to section components
911
+ */
912
+ interface SectionComponentProps {
913
+ /** Section instance data */
914
+ section: SectionInstance;
915
+ /** Section schema */
916
+ schema: SectionSchema;
917
+ /** Selected template definition */
918
+ template: TemplateDefinition;
919
+ /** Whether in edit mode */
920
+ isEditing?: boolean;
921
+ /** Optional data for sections (e.g., API data in view mode) */
922
+ data?: Record<string, unknown>;
923
+ /** Callback when settings change */
924
+ onSettingsChange?: (settings: Settings) => void;
925
+ /** Callback when component is added */
926
+ onComponentAdd?: (componentType: string) => void;
927
+ /** Callback when component is updated */
928
+ onComponentUpdate?: (componentId: string, updates: Partial<SectionComponentInstance>) => void;
929
+ /** Callback when component is removed */
930
+ onComponentRemove?: (componentId: string) => void;
931
+ /** Callback when components are reordered */
932
+ onComponentsReorder?: (componentIds: string[]) => void;
933
+ /** Callback when block is added */
934
+ onBlockAdd?: (blockType: string) => void;
935
+ /** Callback when block is updated */
936
+ onBlockUpdate?: (blockId: string, settings: Settings) => void;
937
+ /** Callback when block is removed */
938
+ onBlockRemove?: (blockId: string) => void;
939
+ /** Callback when blocks are reordered */
940
+ onBlocksReorder?: (blockIds: string[]) => void;
941
+ /** Additional class names */
942
+ className?: string;
943
+ }
944
+ /**
945
+ * Section category definitions
946
+ */
947
+ declare const SECTION_CATEGORIES: {
948
+ readonly HEADER: "header";
949
+ readonly HERO: "hero";
950
+ readonly CONTENT: "content";
951
+ readonly FEATURES: "features";
952
+ readonly TESTIMONIALS: "testimonials";
953
+ readonly CTA: "cta";
954
+ readonly GALLERY: "gallery";
955
+ readonly PRICING: "pricing";
956
+ readonly FAQ: "faq";
957
+ readonly TEAM: "team";
958
+ readonly CONTACT: "contact";
959
+ readonly FOOTER: "footer";
960
+ };
961
+ type SectionCategory = (typeof SECTION_CATEGORIES)[keyof typeof SECTION_CATEGORIES];
962
+
963
+ /**
964
+ * Theme Type Definitions
965
+ * Themes define the global design system and styling
966
+ */
967
+
968
+ /**
969
+ * Design Token - Single design value (color, spacing, etc.)
970
+ */
971
+ interface DesignToken {
972
+ /** Token name (e.g., "primary", "spacing-md") */
973
+ name: string;
974
+ /** Token value (e.g., "#3b82f6", "1rem") */
975
+ value: string;
976
+ /** CSS variable name (e.g., "--color-primary") */
977
+ variable: string;
978
+ /** Description */
979
+ description?: string;
980
+ /** Category for organization */
981
+ category: string;
982
+ }
983
+ /**
984
+ * Color Palette
985
+ */
986
+ interface ColorPalette {
987
+ /** Primary brand color */
988
+ primary: string;
989
+ /** Secondary brand color */
990
+ secondary?: string;
991
+ /** Accent color */
992
+ accent?: string;
993
+ /** Background color */
994
+ background: string;
995
+ /** Foreground/text color */
996
+ foreground: string;
997
+ /** Muted background color */
998
+ muted: string;
999
+ /** Muted foreground color */
1000
+ mutedForeground: string;
1001
+ /** Card background color */
1002
+ card: string;
1003
+ /** Card foreground color */
1004
+ cardForeground: string;
1005
+ /** Popover background color */
1006
+ popover: string;
1007
+ /** Popover foreground color */
1008
+ popoverForeground: string;
1009
+ /** Border color */
1010
+ border: string;
1011
+ /** Input border color */
1012
+ input: string;
1013
+ /** Ring color (focus outlines) */
1014
+ ring: string;
1015
+ /** Success color */
1016
+ success?: string;
1017
+ /** Warning color */
1018
+ warning?: string;
1019
+ /** Error/destructive color */
1020
+ destructive?: string;
1021
+ /** Info color */
1022
+ info?: string;
1023
+ }
1024
+ /**
1025
+ * Typography Settings
1026
+ */
1027
+ interface Typography {
1028
+ /** Font family for headings */
1029
+ fontFamily: {
1030
+ heading: string;
1031
+ body: string;
1032
+ mono?: string;
1033
+ };
1034
+ /** Font sizes */
1035
+ fontSize: {
1036
+ xs: string;
1037
+ sm: string;
1038
+ base: string;
1039
+ lg: string;
1040
+ xl: string;
1041
+ "2xl": string;
1042
+ "3xl": string;
1043
+ "4xl": string;
1044
+ "5xl": string;
1045
+ };
1046
+ /** Font weights */
1047
+ fontWeight: {
1048
+ normal: number;
1049
+ medium: number;
1050
+ semibold: number;
1051
+ bold: number;
1052
+ };
1053
+ /** Line heights */
1054
+ lineHeight: {
1055
+ tight: number;
1056
+ normal: number;
1057
+ relaxed: number;
1058
+ };
1059
+ /** Letter spacing */
1060
+ letterSpacing?: {
1061
+ tight: string;
1062
+ normal: string;
1063
+ wide: string;
1064
+ };
1065
+ }
1066
+ /**
1067
+ * Spacing Scale
1068
+ */
1069
+ interface Spacing {
1070
+ xs: string;
1071
+ sm: string;
1072
+ md: string;
1073
+ lg: string;
1074
+ xl: string;
1075
+ "2xl": string;
1076
+ "3xl": string;
1077
+ "4xl": string;
1078
+ }
1079
+ /**
1080
+ * Border Radius Scale
1081
+ */
1082
+ interface BorderRadius {
1083
+ none: string;
1084
+ sm: string;
1085
+ md: string;
1086
+ lg: string;
1087
+ xl: string;
1088
+ "2xl": string;
1089
+ full: string;
1090
+ }
1091
+ /**
1092
+ * Breakpoints for responsive design
1093
+ */
1094
+ interface Breakpoints {
1095
+ sm: string;
1096
+ md: string;
1097
+ lg: string;
1098
+ xl: string;
1099
+ "2xl": string;
1100
+ }
1101
+ /**
1102
+ * Theme Configuration
1103
+ */
1104
+ interface ThemeConfig {
1105
+ /** Unique theme identifier */
1106
+ id: string;
1107
+ /** Theme name */
1108
+ name: string;
1109
+ /** Theme description */
1110
+ description?: string;
1111
+ /** Theme version */
1112
+ version: string;
1113
+ /** Theme author */
1114
+ author?: string;
1115
+ /** Color palette */
1116
+ colors: {
1117
+ light: ColorPalette;
1118
+ dark?: ColorPalette;
1119
+ };
1120
+ /** Typography settings */
1121
+ typography: Typography;
1122
+ /** Spacing scale */
1123
+ spacing: Spacing;
1124
+ /** Border radius scale */
1125
+ borderRadius: BorderRadius;
1126
+ /** Responsive breakpoints */
1127
+ breakpoints: Breakpoints;
1128
+ /** Design tokens */
1129
+ tokens?: DesignToken[];
1130
+ /** Customizable theme settings */
1131
+ settings?: FieldDefinition[];
1132
+ /** Current theme settings values */
1133
+ settingsValues?: Settings;
1134
+ /** Custom CSS */
1135
+ customCss?: string;
1136
+ /** Whether this is the active theme */
1137
+ active: boolean;
1138
+ /** Creation timestamp */
1139
+ createdAt: string;
1140
+ /** Last update timestamp */
1141
+ updatedAt: string;
1142
+ }
1143
+ /**
1144
+ * Theme Preset - Predefined theme configurations
1145
+ */
1146
+ interface ThemePreset {
1147
+ /** Preset identifier */
1148
+ id: string;
1149
+ /** Display name */
1150
+ name: string;
1151
+ /** Description */
1152
+ description?: string;
1153
+ /** Preview image */
1154
+ preview?: string;
1155
+ /** Theme configuration */
1156
+ config: Omit<ThemeConfig, "id" | "active" | "createdAt" | "updatedAt">;
1157
+ /** Tags for categorization */
1158
+ tags?: string[];
1159
+ }
1160
+ /**
1161
+ * Theme Export/Import Format
1162
+ */
1163
+ interface ThemeExport {
1164
+ /** Export format version */
1165
+ formatVersion: string;
1166
+ /** Exported theme data */
1167
+ theme: ThemeConfig;
1168
+ /** Export timestamp */
1169
+ exportedAt: string;
1170
+ /** Exporter info */
1171
+ exportedBy?: string;
1172
+ }
1173
+ /**
1174
+ * Theme Manifest - Metadata for third-party theme packages
1175
+ *
1176
+ * @public
1177
+ * This is the primary contract that theme developers must implement.
1178
+ * This interface defines what the platform expects from theme bundles.
1179
+ */
1180
+ interface ThemeManifest {
1181
+ /** Unique theme identifier (e.g., "my-awesome-theme") */
1182
+ id: string;
1183
+ /** Human-readable theme name */
1184
+ name: string;
1185
+ /** Semantic version (e.g., "1.0.0") */
1186
+ version: string;
1187
+ /** Theme description */
1188
+ description?: string;
1189
+ /** Theme author information */
1190
+ author: {
1191
+ name: string;
1192
+ email?: string;
1193
+ url?: string;
1194
+ };
1195
+ /** OneX engine version compatibility (e.g., "^1.0.0") */
1196
+ engine: string;
1197
+ /** Required peer dependencies */
1198
+ peerDependencies: {
1199
+ react: string;
1200
+ "react-dom": string;
1201
+ "@onex/core"?: string;
1202
+ };
1203
+ /** Available sections in this theme */
1204
+ sections: string[];
1205
+ /** Theme configuration (colors, typography, etc.) */
1206
+ config: ThemeConfig;
1207
+ /** Entry points for the theme bundle */
1208
+ exports: {
1209
+ /** Main entry point (ESM module) */
1210
+ main: string;
1211
+ /** Type declarations */
1212
+ types?: string;
1213
+ };
1214
+ /** Optional theme preview/screenshot */
1215
+ preview?: {
1216
+ thumbnail?: string;
1217
+ screenshots?: string[];
1218
+ };
1219
+ /** Optional license information */
1220
+ license?: string;
1221
+ /** Optional homepage/repository */
1222
+ repository?: string;
1223
+ /** Optional tags for categorization */
1224
+ tags?: string[];
1225
+ }
1226
+ /**
1227
+ * Theme Module Interface - What theme ESM bundles export
1228
+ *
1229
+ * @public
1230
+ * Theme bundles must export this structure from their main entry point.
1231
+ */
1232
+ interface ThemeModule {
1233
+ /** Theme manifest */
1234
+ manifest: ThemeManifest;
1235
+ /** Section components registry (sectionType -> React component) */
1236
+ sections: Record<string, React.ComponentType<SectionComponentProps>>;
1237
+ /** Theme configuration */
1238
+ config: ThemeConfig;
1239
+ /** Optional theme initialization function */
1240
+ init?: () => void | Promise<void>;
1241
+ }
1242
+ /**
1243
+ * Validation Result - Result of theme bundle validation
1244
+ *
1245
+ * @public
1246
+ * Returned when validating uploaded theme bundles.
1247
+ */
1248
+ interface ThemeValidationResult {
1249
+ /** Whether the theme passed validation */
1250
+ valid: boolean;
1251
+ /** Validation errors (if any) */
1252
+ errors?: ThemeValidationError[];
1253
+ /** Validation warnings (non-blocking) */
1254
+ warnings?: ThemeValidationWarning[];
1255
+ }
1256
+ /**
1257
+ * Theme Validation Error
1258
+ *
1259
+ * @public
1260
+ */
1261
+ interface ThemeValidationError {
1262
+ /** Error code (e.g., "INVALID_MANIFEST", "BUNDLE_TOO_LARGE") */
1263
+ code: string;
1264
+ /** Human-readable error message */
1265
+ message: string;
1266
+ /** Optional path to the problematic field */
1267
+ path?: string;
1268
+ }
1269
+ /**
1270
+ * Theme Validation Warning
1271
+ *
1272
+ * @public
1273
+ */
1274
+ interface ThemeValidationWarning {
1275
+ /** Warning code */
1276
+ code: string;
1277
+ /** Human-readable warning message */
1278
+ message: string;
1279
+ /** Optional path to the problematic field */
1280
+ path?: string;
1281
+ }
1282
+ /**
1283
+ * Theme Upload Metadata - Information about uploaded theme bundles
1284
+ *
1285
+ * @public
1286
+ * Stored in the database when a theme is uploaded.
1287
+ */
1288
+ interface ThemeUpload {
1289
+ /** Unique upload ID */
1290
+ id: string;
1291
+ /** Theme ID from manifest */
1292
+ themeId: string;
1293
+ /** Theme version from manifest */
1294
+ version: string;
1295
+ /** User who uploaded the theme */
1296
+ uploadedBy: string;
1297
+ /** Upload timestamp */
1298
+ uploadedAt: string;
1299
+ /** CDN URL for the theme bundle */
1300
+ bundleUrl: string;
1301
+ /** Bundle size in bytes */
1302
+ bundleSize: number;
1303
+ /** Upload status */
1304
+ status: "pending" | "validated" | "published" | "rejected";
1305
+ /** Validation result (if validated) */
1306
+ validation?: ThemeValidationResult;
1307
+ /** Rejection reason (if rejected) */
1308
+ rejectionReason?: string;
1309
+ }
1310
+
1311
+ /**
1312
+ * Page Type Definitions
1313
+ * Pages can be either component-based (static TSX) or section-based (composable)
1314
+ */
1315
+
1316
+ /**
1317
+ * Page Render Mode
1318
+ * Determines how the page is rendered
1319
+ */
1320
+ type PageRenderMode = "component" | "sections";
1321
+ /**
1322
+ * Page Type
1323
+ */
1324
+ type PageType = "home" | "about" | "contact" | "blog" | "product" | "products" | "cart" | "checkout" | "payment" | "order-success" | "order-failed" | "login" | "register" | "forgot-password" | "verify-code" | "reset-password" | "profile" | "static" | "utility" | "auth" | "custom";
1325
+ /**
1326
+ * Schema.org Type for Structured Data
1327
+ */
1328
+ type SchemaType = "WebSite" | "Organization" | "Article" | "BlogPosting" | "Product" | "LocalBusiness" | "FAQPage" | "HowTo" | "Person" | "Event";
1329
+ /**
1330
+ * Twitter Card Type
1331
+ */
1332
+ type TwitterCardType = "summary" | "summary_large_image" | "app" | "player";
1333
+ /**
1334
+ * Robots Directive
1335
+ */
1336
+ type RobotsDirective = "index" | "noindex" | "follow" | "nofollow" | "noarchive" | "nosnippet" | "noimageindex" | "notranslate";
1337
+ /**
1338
+ * Open Graph Metadata
1339
+ */
1340
+ interface OpenGraphMeta {
1341
+ /** OG Title (can differ from page title) */
1342
+ title?: string;
1343
+ /** OG Description */
1344
+ description?: string;
1345
+ /** OG Image URL (recommended: 1200x630px) */
1346
+ image?: string;
1347
+ /** OG Image Alt Text */
1348
+ imageAlt?: string;
1349
+ /** OG Type (website, article, product, etc.) */
1350
+ type?: string;
1351
+ /** OG URL (canonical URL for sharing) */
1352
+ url?: string;
1353
+ /** OG Site Name (brand name) */
1354
+ siteName?: string;
1355
+ /** OG Locale (e.g., en_US, vi_VN) */
1356
+ locale?: string;
1357
+ /** Article-specific: author */
1358
+ articleAuthor?: string;
1359
+ /** Article-specific: published time */
1360
+ articlePublishedTime?: string;
1361
+ /** Article-specific: modified time */
1362
+ articleModifiedTime?: string;
1363
+ /** Article-specific: section/category */
1364
+ articleSection?: string;
1365
+ /** Article-specific: tags */
1366
+ articleTags?: string[];
1367
+ }
1368
+ /**
1369
+ * Twitter Card Metadata
1370
+ */
1371
+ interface TwitterCardMeta {
1372
+ /** Card type */
1373
+ card?: TwitterCardType;
1374
+ /** Twitter site account (@username) */
1375
+ site?: string;
1376
+ /** Twitter creator account (@username) */
1377
+ creator?: string;
1378
+ /** Twitter title (can differ from OG title) */
1379
+ title?: string;
1380
+ /** Twitter description */
1381
+ description?: string;
1382
+ /** Twitter image URL */
1383
+ image?: string;
1384
+ /** Twitter image alt text */
1385
+ imageAlt?: string;
1386
+ }
1387
+ /**
1388
+ * FAQ Schema Item for FAQPage structured data
1389
+ */
1390
+ interface FAQSchemaItem {
1391
+ /** Question text */
1392
+ question: string;
1393
+ /** Answer text (supports HTML/markdown) */
1394
+ answer: string;
1395
+ /** Unique identifier */
1396
+ id?: string;
1397
+ }
1398
+ /**
1399
+ * Structured Data Configuration
1400
+ */
1401
+ interface StructuredDataConfig {
1402
+ /** Schema type */
1403
+ type?: SchemaType;
1404
+ /** Schema.org data as JSON-LD object */
1405
+ data?: Record<string, unknown>;
1406
+ }
1407
+ /**
1408
+ * Page SEO Settings - Comprehensive SEO & AEO Configuration
1409
+ */
1410
+ interface PageSEO {
1411
+ /** Page title (50-60 characters recommended) */
1412
+ title?: string;
1413
+ /** Meta description (150-160 characters recommended) */
1414
+ description?: string;
1415
+ /** Meta keywords */
1416
+ keywords?: string[];
1417
+ /** Featured image URL */
1418
+ image?: string;
1419
+ /** Image alt text for accessibility */
1420
+ imageAlt?: string;
1421
+ /** Open Graph metadata */
1422
+ openGraph?: OpenGraphMeta;
1423
+ /** Twitter Card metadata */
1424
+ twitter?: TwitterCardMeta;
1425
+ /** Structured data configuration */
1426
+ structuredData?: StructuredDataConfig;
1427
+ /** FAQ Schema items for FAQPage */
1428
+ faqs?: FAQSchemaItem[];
1429
+ /** Canonical URL */
1430
+ canonical?: string;
1431
+ /** Robots meta directives */
1432
+ robots?: RobotsDirective[] | string;
1433
+ /** Author name */
1434
+ author?: string;
1435
+ /** Published date (ISO 8601) */
1436
+ publishedTime?: string;
1437
+ /** Last modified date (ISO 8601) */
1438
+ modifiedTime?: string;
1439
+ /** Content locale (e.g., en_US, vi_VN) */
1440
+ locale?: string;
1441
+ /** Alternate locales for i18n */
1442
+ alternateLocales?: string[];
1443
+ /** Primary topic/focus keyword */
1444
+ focusKeyword?: string;
1445
+ /** Content type for AI optimization */
1446
+ contentType?: "article" | "guide" | "tutorial" | "product" | "faq" | "comparison";
1447
+ /** Target audience description */
1448
+ targetAudience?: string;
1449
+ /** Enhanced author information (E-E-A-T) */
1450
+ authors?: Array<{
1451
+ name: string;
1452
+ url?: string;
1453
+ image?: string;
1454
+ jobTitle?: string;
1455
+ bio?: string;
1456
+ sameAs?: string[];
1457
+ }>;
1458
+ /** Reviewer information (for review content) */
1459
+ reviewedBy?: {
1460
+ name: string;
1461
+ url?: string;
1462
+ credentials?: string;
1463
+ };
1464
+ /** Content freshness indicators */
1465
+ lastReviewed?: string;
1466
+ contentExpiry?: string;
1467
+ updateFrequency?: "daily" | "weekly" | "monthly" | "yearly" | "as-needed";
1468
+ /** Main entity of the page */
1469
+ mainEntity?: {
1470
+ type: string;
1471
+ name: string;
1472
+ description?: string;
1473
+ sameAs?: string[];
1474
+ };
1475
+ /** Breadcrumb navigation */
1476
+ breadcrumbs?: Array<{
1477
+ name: string;
1478
+ url: string;
1479
+ }>;
1480
+ /** Content classification for AI */
1481
+ contentPurpose?: "inform" | "educate" | "sell" | "entertain" | "compare";
1482
+ audienceExpertiseLevel?: "beginner" | "intermediate" | "expert" | "all";
1483
+ contentDepth?: "overview" | "detailed" | "comprehensive";
1484
+ /** Topic categorization */
1485
+ topics?: string[];
1486
+ /** Citation preferences */
1487
+ citationPreference?: {
1488
+ allowAICitation?: boolean;
1489
+ attributionRequired?: boolean;
1490
+ licensingInfo?: string;
1491
+ };
1492
+ /** AI crawler directives */
1493
+ aiRobots?: {
1494
+ allowGPTBot?: boolean;
1495
+ allowCCBot?: boolean;
1496
+ allowClaudeBot?: boolean;
1497
+ allowBingBot?: boolean;
1498
+ };
1499
+ /** Related content for AI context */
1500
+ relatedPages?: Array<{
1501
+ url: string;
1502
+ title: string;
1503
+ relationship: "prerequisite" | "related" | "next" | "parent";
1504
+ }>;
1505
+ /** Estimated reading/viewing time */
1506
+ estimatedTime?: {
1507
+ value: number;
1508
+ unit: "minutes" | "hours";
1509
+ };
1510
+ /** Additional custom meta tags */
1511
+ meta?: Array<{
1512
+ name?: string;
1513
+ property?: string;
1514
+ content: string;
1515
+ }>;
1516
+ }
1517
+ /**
1518
+ * Component Page Definition
1519
+ * For registering simple/static pages (pure React components)
1520
+ */
1521
+ interface ComponentPageDefinition {
1522
+ /** Unique page identifier */
1523
+ id: string;
1524
+ /** Display name */
1525
+ name: string;
1526
+ /** Description */
1527
+ description?: string;
1528
+ /** Page type */
1529
+ type: PageType;
1530
+ /** URL handle/slug */
1531
+ handle: string;
1532
+ /** The React component */
1533
+ component: React$1.ComponentType<Record<string, unknown>>;
1534
+ /** Preview thumbnail */
1535
+ preview?: string;
1536
+ /** Category for organization */
1537
+ category?: "utility" | "auth" | "content" | "custom";
1538
+ /** Tags for searching/filtering */
1539
+ tags?: string[];
1540
+ /** Whether this page can be customized */
1541
+ customizable?: boolean;
1542
+ /** Default SEO settings */
1543
+ defaultSeo?: PageSEO;
1544
+ }
1545
+ /**
1546
+ * Page Configuration
1547
+ */
1548
+ interface PageConfig extends BaseEntity {
1549
+ /** Page title */
1550
+ title: string;
1551
+ /** URL handle/slug (internal identifier) */
1552
+ handle: string;
1553
+ /**
1554
+ * Public URL path
1555
+ * If not specified, defaults to `/${handle}` (except home → "/")
1556
+ * Examples: "/", "/about", "/products/[id]", "/blog/[slug]"
1557
+ */
1558
+ path?: string;
1559
+ /**
1560
+ * Whether this is a dynamic route with parameters
1561
+ * True for paths like "/products/[id]" or "/blog/[slug]"
1562
+ */
1563
+ isDynamic?: boolean;
1564
+ /**
1565
+ * Dynamic route segments (parameter names)
1566
+ * Example: ["id"] for "/products/[id]", ["slug"] for "/blog/[slug]"
1567
+ */
1568
+ dynamicSegments?: string[];
1569
+ /**
1570
+ * Parent page handle (for building breadcrumbs and nested routes)
1571
+ * Example: "products" for a page at "/products/[id]"
1572
+ */
1573
+ parentHandle?: string;
1574
+ /** Page type */
1575
+ type: PageType;
1576
+ /** Render mode: determines how page is rendered */
1577
+ renderMode: PageRenderMode;
1578
+ /** Theme reference */
1579
+ themeId: string;
1580
+ /** For component pages: path to component or component ID */
1581
+ componentPath?: string;
1582
+ /** For section-based pages: sections array */
1583
+ sections?: SectionInstance[];
1584
+ /** Whether the page is editable in visual editor */
1585
+ editable: boolean;
1586
+ /** Page-specific settings */
1587
+ settings?: Settings;
1588
+ /** SEO settings */
1589
+ seo?: PageSEO;
1590
+ /** Whether the page is published */
1591
+ published: boolean;
1592
+ /** Publication date */
1593
+ publishedAt?: string;
1594
+ /** Author/creator */
1595
+ author?: string;
1596
+ /** Template layout (for custom pages) */
1597
+ layout?: string;
1598
+ /** Custom CSS for this page */
1599
+ customCss?: string;
1600
+ /** Custom JavaScript for this page */
1601
+ customJs?: string;
1602
+ /** Version number for change tracking */
1603
+ version?: number;
1604
+ }
1605
+ /**
1606
+ * Page Template - Predefined page structures
1607
+ */
1608
+ interface PageTemplate {
1609
+ /** Unique template identifier */
1610
+ id: string;
1611
+ /** Display name */
1612
+ name: string;
1613
+ /** Description */
1614
+ description?: string;
1615
+ /** Preview image */
1616
+ preview?: string;
1617
+ /** Page type this template is for */
1618
+ pageType: PageType;
1619
+ /** Render mode: determines if template is component or section-based */
1620
+ renderMode: PageRenderMode;
1621
+ /** For component-based templates: path to component */
1622
+ componentPath?: string;
1623
+ /** For section-based templates: pre-configured sections */
1624
+ sections?: Omit<SectionInstance, "id" | "createdAt" | "updatedAt">[];
1625
+ /** Default SEO settings */
1626
+ defaultSeo?: PageSEO;
1627
+ /** Tags for categorization */
1628
+ tags?: string[];
1629
+ }
1630
+ /**
1631
+ * Page List Item - Lightweight representation for page lists
1632
+ */
1633
+ interface PageListItem {
1634
+ id: string;
1635
+ title: string;
1636
+ handle: string;
1637
+ type: PageType;
1638
+ published: boolean;
1639
+ updatedAt: string;
1640
+ seo?: {
1641
+ title?: string;
1642
+ description?: string;
1643
+ };
1644
+ }
1645
+ /**
1646
+ * Page Navigation Item
1647
+ */
1648
+ interface PageNavItem {
1649
+ id: string;
1650
+ title: string;
1651
+ handle: string;
1652
+ /** Computed or explicit path for navigation */
1653
+ path?: string;
1654
+ /** Display order in navigation */
1655
+ order: number;
1656
+ /** Nested navigation items */
1657
+ children?: PageNavItem[];
1658
+ /** Whether to show in main navigation */
1659
+ showInNav?: boolean;
1660
+ /** Icon for navigation item */
1661
+ icon?: string;
1662
+ }
1663
+ /**
1664
+ * Theme Layout Configuration (Legacy)
1665
+ * Defines a theme with header, footer, and global settings
1666
+ * @deprecated Use ThemeConfig from './theme' for new implementations
1667
+ */
1668
+ interface ThemeLayoutConfig {
1669
+ /** Unique theme identifier */
1670
+ id: string;
1671
+ /** Display name */
1672
+ name: string;
1673
+ /** Theme version */
1674
+ version: string;
1675
+ /** Header sections to prepend to all pages */
1676
+ headerSections?: SectionInstance[];
1677
+ /** Footer sections to append to all pages */
1678
+ footerSections?: SectionInstance[];
1679
+ /** Global design settings/tokens */
1680
+ globalSettings?: {
1681
+ /** Primary brand color */
1682
+ primaryColor?: string;
1683
+ /** Secondary color */
1684
+ secondaryColor?: string;
1685
+ /** Font family */
1686
+ fontFamily?: string;
1687
+ /** Spacing scale */
1688
+ spacing?: string;
1689
+ /** Additional custom settings */
1690
+ [key: string]: unknown;
1691
+ };
1692
+ /** Creation timestamp */
1693
+ createdAt?: string;
1694
+ /** Last update timestamp */
1695
+ updatedAt?: string;
1696
+ }
1697
+
1698
+ /**
1699
+ * JSON-serializable value type
1700
+ */
1701
+ type JSONValue = string | number | boolean | null | JSONObject | JSONArray;
1702
+ interface JSONObject {
1703
+ [key: string]: JSONValue;
1704
+ }
1705
+ type JSONArray = JSONValue[];
1706
+ /**
1707
+ * Element Type Enumeration
1708
+ * Visual DOM element types that can be edited inline
1709
+ * (Different from FieldType which defines settings panel inputs)
1710
+ */
1711
+ type ElementType = "text" | "button" | "image" | "link" | "video" | "icon" | "form" | "richtext" | "chart" | "map" | "countdown";
1712
+ /**
1713
+ * Element Metadata
1714
+ * Information about a selected editable element
1715
+ */
1716
+ interface ElementMetadata {
1717
+ /** Component instance ID (if element is a component instance) */
1718
+ componentId?: string;
1719
+ /** Field ID from section/component schema */
1720
+ fieldId: string;
1721
+ /** Human-readable field label */
1722
+ fieldLabel: string;
1723
+ /** Type of visual element */
1724
+ elementType: ElementType;
1725
+ /** Parent section ID */
1726
+ sectionId: string;
1727
+ /** Parent block ID (if element is inside a block) */
1728
+ blockId?: string;
1729
+ /** Whether to show inline popover editor */
1730
+ isInline: boolean;
1731
+ /** Element's bounding rectangle */
1732
+ bounds: DOMRect;
1733
+ /** Current field value */
1734
+ currentValue: SettingValue;
1735
+ }
1736
+ /**
1737
+ * Detection Priority
1738
+ * Defines the order in which elements are detected
1739
+ */
1740
+ type DetectionPriority = "component" | "block" | "section";
1741
+ /**
1742
+ * Detection Strategy
1743
+ * Controls how the inspector overlay detects selectable items
1744
+ */
1745
+ interface DetectionStrategy {
1746
+ /** Priority order for detection (element → component → block → section) */
1747
+ priority: DetectionPriority[];
1748
+ /** Whether to stop at first match or continue traversing */
1749
+ stopAtFirstMatch: boolean;
1750
+ /** Maximum depth to traverse up the DOM tree */
1751
+ maxDepth?: number;
1752
+ }
1753
+ /**
1754
+ * Detection Result
1755
+ * Result of DOM traversal detection
1756
+ */
1757
+ type DetectionResult = {
1758
+ type: "component";
1759
+ sectionId: string;
1760
+ componentId: string;
1761
+ componentType: string;
1762
+ element: HTMLElement;
1763
+ } | {
1764
+ type: "block";
1765
+ sectionId: string;
1766
+ blockId: string;
1767
+ element: HTMLElement;
1768
+ } | {
1769
+ type: "section";
1770
+ sectionId: string;
1771
+ element: HTMLElement;
1772
+ } | {
1773
+ type: "none";
1774
+ };
1775
+ /**
1776
+ * Inline Editor State
1777
+ */
1778
+ interface InlineEditorState {
1779
+ /** Whether inline editor is visible */
1780
+ visible: boolean;
1781
+ /** Position for popover */
1782
+ position: {
1783
+ top: number;
1784
+ left: number;
1785
+ };
1786
+ /** Type of element being edited */
1787
+ elementType: ElementType;
1788
+ /** Current value */
1789
+ currentValue: SettingValue;
1790
+ /** Field definition from schema */
1791
+ fieldDefinition?: FieldDefinition;
1792
+ }
1793
+ /**
1794
+ * Props for inline editor components
1795
+ */
1796
+ interface InlineEditorProps {
1797
+ /** Selected element info */
1798
+ selectedElement: SelectedElement;
1799
+ /** Current field value */
1800
+ currentValue: SettingValue;
1801
+ /** Field definition from schema */
1802
+ fieldDefinition: FieldDefinition;
1803
+ /** Update callback */
1804
+ onUpdate: (value: SettingValue) => void;
1805
+ /** Close callback */
1806
+ onClose: () => void;
1807
+ /** Popover position */
1808
+ position?: {
1809
+ top: number;
1810
+ left: number;
1811
+ };
1812
+ }
1813
+ /**
1814
+ * Inspector Configuration
1815
+ */
1816
+ interface InspectorConfig {
1817
+ /** Detection strategy (element-first by default) */
1818
+ strategy: DetectionStrategy;
1819
+ /** Whether to show element outlines on hover */
1820
+ showElementOutlines: boolean;
1821
+ /** Whether to show element tooltips */
1822
+ showTooltips: boolean;
1823
+ /** Outline color for different types */
1824
+ outlineColors: {
1825
+ component: string;
1826
+ block: string;
1827
+ section: string;
1828
+ };
1829
+ }
1830
+ /**
1831
+ * Default Inspector Configuration
1832
+ * Detection priority: component → block → section
1833
+ */
1834
+ declare const DEFAULT_INSPECTOR_CONFIG: InspectorConfig;
1835
+ /**
1836
+ * Editor Mode
1837
+ */
1838
+ type EditorMode = "view" | "edit" | "preview";
1839
+ /**
1840
+ * Icon Sidebar View
1841
+ * Determines which panel is shown in the left sidebar
1842
+ */
1843
+ type IconSidebarView = "sections" | "page-seo" | "theme-settings";
1844
+ /**
1845
+ * Selected Element Type
1846
+ */
1847
+ type SelectedElementType = "section" | "block" | "component" | "none";
1848
+ /**
1849
+ * Selected Element Info
1850
+ */
1851
+ interface SelectedElement {
1852
+ /** Type of selected element */
1853
+ type: SelectedElementType;
1854
+ /** Element ID */
1855
+ id: string;
1856
+ /** Section ID (for section, component, block, and element selections) */
1857
+ sectionId: string;
1858
+ /** Component ID (only for component selections) */
1859
+ componentId?: string;
1860
+ /** Component type (only for component selections) */
1861
+ componentType?: string;
1862
+ /** Block ID (only for block selections) */
1863
+ blockId?: string;
1864
+ /** Block type (only for block selections) */
1865
+ blockType?: string;
1866
+ /** DOM element reference */
1867
+ element?: HTMLElement;
1868
+ /** Bounding rect for overlay positioning */
1869
+ rect?: DOMRect;
1870
+ }
1871
+ /**
1872
+ * Editor State
1873
+ */
1874
+ interface EditorState {
1875
+ /** Current editor mode */
1876
+ mode: EditorMode;
1877
+ /** Currently selected element */
1878
+ selected: SelectedElement | null;
1879
+ /** Whether the settings panel is open */
1880
+ settingsPanelOpen: boolean;
1881
+ /** Whether the sections panel is open */
1882
+ sectionsPanelOpen: boolean;
1883
+ /** Current page being edited */
1884
+ pageId: string | null;
1885
+ /** Whether there are unsaved changes */
1886
+ hasUnsavedChanges: boolean;
1887
+ /** Undo/redo stack depth */
1888
+ historyIndex: number;
1889
+ /** Total history entries */
1890
+ historyLength: number;
1891
+ /** Current icon sidebar view (sections or theme settings) */
1892
+ iconSidebarView: IconSidebarView;
1893
+ /** Current theme configuration */
1894
+ themeConfig: ThemeLayoutConfig | null;
1895
+ /** Left panel width (for persistence) */
1896
+ leftPanelWidth: number;
1897
+ /** Current company ID */
1898
+ companyId: string;
1899
+ /** Current theme ID */
1900
+ themeId: string;
1901
+ /** Available section schemas for the current theme */
1902
+ themeSchemas: SectionSchema[];
1903
+ /** Page SEO configuration */
1904
+ pageSeo: PageSEO | null;
1905
+ }
1906
+ /**
1907
+ * Editor Actions
1908
+ */
1909
+ interface EditorActions {
1910
+ /** Set editor mode */
1911
+ setMode: (mode: EditorMode) => void;
1912
+ /** Select an element */
1913
+ selectElement: (element: SelectedElement | null) => void;
1914
+ /** Toggle settings panel */
1915
+ toggleSettingsPanel: (open?: boolean) => void;
1916
+ /** Toggle sections panel */
1917
+ toggleSectionsPanel: (open?: boolean) => void;
1918
+ /** Update section settings */
1919
+ updateSectionSettings: (sectionId: string, settings: Settings) => void;
1920
+ /** Update component settings */
1921
+ updateComponentSettings: (sectionId: string, componentId: string, updates: Partial<{
1922
+ content: Settings;
1923
+ style: Settings;
1924
+ }>) => void;
1925
+ /** Update block settings */
1926
+ updateBlockSettings: (sectionId: string, blockId: string, settings: Settings) => void;
1927
+ /** Add section to page */
1928
+ addSection: (sectionType: string, templateId: string, order?: number) => void;
1929
+ /** Remove section from page */
1930
+ removeSection: (sectionId: string) => void;
1931
+ /** Reorder sections */
1932
+ reorderSections: (sectionIds: string[]) => void;
1933
+ /** Add component to section */
1934
+ addComponent: (sectionId: string, componentType: string) => void;
1935
+ /** Remove component from section */
1936
+ removeComponent: (sectionId: string, componentId: string) => void;
1937
+ /** Reorder components in section */
1938
+ reorderComponents: (sectionId: string, componentIds: string[]) => void;
1939
+ /** Add block to section */
1940
+ addBlock: (sectionId: string, blockType: string) => void;
1941
+ /** Remove block from section */
1942
+ removeBlock: (sectionId: string, blockId: string) => void;
1943
+ /** Reorder blocks in section */
1944
+ reorderBlocks: (sectionId: string, blockIds: string[]) => void;
1945
+ /** Duplicate section */
1946
+ duplicateSection: (sectionId: string) => void;
1947
+ /** Toggle section visibility */
1948
+ toggleSectionVisibility: (sectionId: string) => void;
1949
+ /** Change section template */
1950
+ changeSectionTemplate: (sectionId: string, templateId: string) => void;
1951
+ /** Replace all sections (used when switching page templates) */
1952
+ replaceAllSections: (newSections: SectionInstance[]) => void;
1953
+ /** Save changes */
1954
+ save: () => Promise<void>;
1955
+ /** Discard changes */
1956
+ discard: () => void;
1957
+ /** Undo last action */
1958
+ undo: () => void;
1959
+ /** Redo last undone action */
1960
+ redo: () => void;
1961
+ /** Check if can undo */
1962
+ canUndo: () => boolean;
1963
+ /** Check if can redo */
1964
+ canRedo: () => boolean;
1965
+ /** Set icon sidebar view */
1966
+ setIconSidebarView: (view: IconSidebarView) => void;
1967
+ /** Load theme configuration */
1968
+ loadThemeConfig: (themeId: string) => Promise<void>;
1969
+ /** Update theme global settings */
1970
+ updateThemeGlobalSettings: (settings: Record<string, unknown>) => void;
1971
+ /** Update theme metadata */
1972
+ updateThemeMetadata: (metadata: Partial<ThemeLayoutConfig>) => void;
1973
+ /** Save theme configuration */
1974
+ saveThemeConfig: () => Promise<void>;
1975
+ /** Add header section to theme */
1976
+ addHeaderSection: (sectionType: string, templateId: string) => void;
1977
+ /** Remove header section from theme */
1978
+ removeHeaderSection: (index: number) => void;
1979
+ /** Update header section in theme */
1980
+ updateHeaderSection: (index: number, updates: Record<string, unknown>) => void;
1981
+ /** Add footer section to theme */
1982
+ addFooterSection: (sectionType: string, templateId: string) => void;
1983
+ /** Remove footer section from theme */
1984
+ removeFooterSection: (index: number) => void;
1985
+ /** Update footer section in theme */
1986
+ updateFooterSection: (index: number, updates: Record<string, unknown>) => void;
1987
+ /** Set left panel width */
1988
+ setLeftPanelWidth: (width: number) => void;
1989
+ /** Update page SEO */
1990
+ updatePageSeo: (seo: Partial<PageSEO>) => void;
1991
+ }
1992
+ /**
1993
+ * Editor Context Value
1994
+ */
1995
+ interface EditorContextValue {
1996
+ /** Current state */
1997
+ state: EditorState;
1998
+ /** Available actions */
1999
+ actions: EditorActions;
2000
+ /** Current page sections */
2001
+ sections: SectionInstance[];
2002
+ }
2003
+ /**
2004
+ * Inspector Overlay State
2005
+ */
2006
+ interface InspectorOverlayState {
2007
+ /** Hovered element info */
2008
+ hovered: SelectedElement | null;
2009
+ /** Whether to show overlay */
2010
+ visible: boolean;
2011
+ }
2012
+ /**
2013
+ * Change History Entry
2014
+ */
2015
+ interface HistoryEntry {
2016
+ /** Unique entry ID */
2017
+ id: string;
2018
+ /** Action type */
2019
+ action: string;
2020
+ /** Previous state snapshot */
2021
+ before: JSONValue;
2022
+ /** New state snapshot */
2023
+ after: JSONValue;
2024
+ /** Timestamp */
2025
+ timestamp: Date;
2026
+ /** User-friendly description */
2027
+ description: string;
2028
+ }
2029
+ /**
2030
+ * Drag and Drop Context
2031
+ */
2032
+ interface DragDropContext {
2033
+ /** Item being dragged */
2034
+ draggedItem: {
2035
+ type: "section" | "component" | "block";
2036
+ id: string;
2037
+ data: SectionInstance | SectionComponentInstance | BlockInstance;
2038
+ } | null;
2039
+ /** Drop target info */
2040
+ dropTarget: {
2041
+ type: "section" | "component" | "block";
2042
+ id: string;
2043
+ position: "before" | "after" | "inside";
2044
+ } | null;
2045
+ /** Start dragging */
2046
+ startDrag: (item: DragDropContext["draggedItem"]) => void;
2047
+ /** Update drop target */
2048
+ updateDropTarget: (target: DragDropContext["dropTarget"]) => void;
2049
+ /** End dragging */
2050
+ endDrag: () => void;
2051
+ }
2052
+ /**
2053
+ * Keyboard Shortcuts
2054
+ */
2055
+ interface KeyboardShortcut {
2056
+ /** Shortcut key combination */
2057
+ keys: string[];
2058
+ /** Action to perform */
2059
+ action: () => void;
2060
+ /** Description */
2061
+ description: string;
2062
+ /** Whether enabled */
2063
+ enabled?: boolean;
2064
+ }
2065
+
2066
+ /**
2067
+ * Registry Type Definitions
2068
+ * Types for the section, block, and page registry system
2069
+ */
2070
+
2071
+ /**
2072
+ * Registry Configuration
2073
+ */
2074
+ interface RegistryConfig {
2075
+ /** Enable debug logging */
2076
+ debug?: boolean;
2077
+ /** Allow overriding existing registrations */
2078
+ allowOverride?: boolean;
2079
+ /** Maximum number of sections that can be registered */
2080
+ maxSections?: number;
2081
+ /** Maximum number of blocks that can be registered */
2082
+ maxBlocks?: number;
2083
+ }
2084
+ /**
2085
+ * Registry Event Types
2086
+ */
2087
+ type RegistryEventType = "section:registered" | "section:unregistered" | "block:registered" | "block:unregistered" | "template:registered" | "page:registered" | "page:unregistered" | "page-template:registered";
2088
+ /**
2089
+ * Registry Event Payload Union
2090
+ */
2091
+ type RegistryEventPayload = SectionRegisteredPayload | SectionUnregisteredPayload | TemplateRegisteredPayload | BlockRegisteredPayload | BlockUnregisteredPayload;
2092
+ /**
2093
+ * Registry Event
2094
+ */
2095
+ interface RegistryEvent<TPayload = RegistryEventPayload> {
2096
+ /** Event type */
2097
+ type: RegistryEventType;
2098
+ /** Event payload */
2099
+ payload: TPayload;
2100
+ /** Event timestamp */
2101
+ timestamp: Date;
2102
+ }
2103
+ /**
2104
+ * Section Registry Event Payloads
2105
+ */
2106
+ interface SectionRegisteredPayload {
2107
+ type: string;
2108
+ schema: SectionSchema;
2109
+ templates: TemplateDefinition[];
2110
+ }
2111
+ interface SectionUnregisteredPayload {
2112
+ type: string;
2113
+ }
2114
+ interface TemplateRegisteredPayload {
2115
+ sectionType: string;
2116
+ templateId: string;
2117
+ template: TemplateDefinition;
2118
+ }
2119
+ /**
2120
+ * Block Registry Event Payloads
2121
+ */
2122
+ interface BlockRegisteredPayload {
2123
+ type: string;
2124
+ definition: BlockDefinition;
2125
+ }
2126
+ interface BlockUnregisteredPayload {
2127
+ type: string;
2128
+ }
2129
+ /**
2130
+ * Registry Event Handler
2131
+ */
2132
+ type RegistryEventHandler<TPayload = RegistryEventPayload> = (event: RegistryEvent<TPayload>) => void;
2133
+ /**
2134
+ * Section Registry Interface
2135
+ */
2136
+ interface SectionRegistry {
2137
+ /**
2138
+ * Register a section type with its templates
2139
+ */
2140
+ register<T>(sectionType: string, schema: SectionSchema, component: React.ComponentType<T> | (() => Promise<React.ComponentType<T>>), options?: {
2141
+ templates?: Array<{
2142
+ definition: TemplateDefinition;
2143
+ component: React.ComponentType<SectionComponentProps>;
2144
+ }>;
2145
+ category?: string;
2146
+ tags?: string[];
2147
+ }): void;
2148
+ /**
2149
+ * Get a section registration
2150
+ */
2151
+ get<T>(sectionType: string): Promise<SectionRegistration<T> | undefined>;
2152
+ /**
2153
+ * Get just the schema without loading the component (server-safe)
2154
+ */
2155
+ getSchema(sectionType: string): SectionSchema | undefined;
2156
+ /**
2157
+ * Get a specific template for a section
2158
+ */
2159
+ getTemplate(sectionType: string, templateId: string): TemplateDefinition | undefined;
2160
+ /**
2161
+ * Get template component
2162
+ */
2163
+ getTemplateComponent(sectionType: string, templateId: string): React.ComponentType<SectionComponentProps> | undefined;
2164
+ /**
2165
+ * Check if a section is registered
2166
+ */
2167
+ has(sectionType: string): boolean;
2168
+ /**
2169
+ * Unregister a section
2170
+ */
2171
+ unregister(sectionType: string): boolean;
2172
+ /**
2173
+ * Get all registered sections
2174
+ */
2175
+ getAll(): Map<string, SectionRegistration>;
2176
+ /**
2177
+ * Search sections by category
2178
+ */
2179
+ getByCategory(category: string): SectionRegistration[];
2180
+ /**
2181
+ * Search sections by tags
2182
+ */
2183
+ getByTags(tags: string[]): SectionRegistration[];
2184
+ /**
2185
+ * Add event listener
2186
+ */
2187
+ on<TPayload = RegistryEventPayload>(eventType: RegistryEventType, handler: RegistryEventHandler<TPayload>): void;
2188
+ /**
2189
+ * Remove event listener
2190
+ */
2191
+ off<TPayload = RegistryEventPayload>(eventType: RegistryEventType, handler: RegistryEventHandler<TPayload>): void;
2192
+ /**
2193
+ * Clear all registrations
2194
+ */
2195
+ clear(): void;
2196
+ }
2197
+ /**
2198
+ * Block Registry Interface
2199
+ */
2200
+ interface BlockRegistry {
2201
+ /**
2202
+ * Register a block type
2203
+ */
2204
+ register<T>(blockType: string, definition: BlockDefinition, component: React.ComponentType<T>, options?: {
2205
+ category?: string;
2206
+ tags?: string[];
2207
+ }): void;
2208
+ /**
2209
+ * Get a block registration
2210
+ */
2211
+ get(blockType: string): BlockRegistration | undefined;
2212
+ /**
2213
+ * Check if a block is registered
2214
+ */
2215
+ has(blockType: string): boolean;
2216
+ /**
2217
+ * Unregister a block
2218
+ */
2219
+ unregister(blockType: string): boolean;
2220
+ /**
2221
+ * Get all registered blocks
2222
+ */
2223
+ getAll(): Map<string, BlockRegistration>;
2224
+ /**
2225
+ * Add event listener
2226
+ */
2227
+ on<TPayload = RegistryEventPayload>(eventType: RegistryEventType, handler: RegistryEventHandler<TPayload>): void;
2228
+ /**
2229
+ * Remove event listener
2230
+ */
2231
+ off<TPayload = RegistryEventPayload>(eventType: RegistryEventType, handler: RegistryEventHandler<TPayload>): void;
2232
+ /**
2233
+ * Clear all registrations
2234
+ */
2235
+ clear(): void;
2236
+ }
2237
+ /**
2238
+ * Detected Section Element Info
2239
+ */
2240
+ interface DetectedSection {
2241
+ /** Element ID from data-section-id */
2242
+ id: string;
2243
+ /** DOM element reference */
2244
+ element: HTMLElement;
2245
+ /** Section type from data-section */
2246
+ type: string;
2247
+ /** Template ID from data-section-template */
2248
+ template: string;
2249
+ /** Section name from data-section-name */
2250
+ name: string;
2251
+ /** Section category */
2252
+ category: string;
2253
+ /** Available settings for this section/template */
2254
+ settings: FieldDefinition[];
2255
+ }
2256
+ /**
2257
+ * Element Registry Interface (for DOM element tracking)
2258
+ */
2259
+ interface ElementRegistry {
2260
+ /**
2261
+ * Register a detected section element
2262
+ */
2263
+ register(info: DetectedSection): void;
2264
+ /**
2265
+ * Get section info by ID
2266
+ */
2267
+ get(id: string): DetectedSection | undefined;
2268
+ /**
2269
+ * Get section info by DOM element
2270
+ */
2271
+ getByElement(element: HTMLElement): DetectedSection | undefined;
2272
+ /**
2273
+ * Check if element is registered
2274
+ */
2275
+ has(element: HTMLElement): boolean;
2276
+ /**
2277
+ * Unregister by ID
2278
+ */
2279
+ unregister(id: string): void;
2280
+ /**
2281
+ * Get all detected sections
2282
+ */
2283
+ getAll(): DetectedSection[];
2284
+ /**
2285
+ * Clear all registrations
2286
+ */
2287
+ clear(): void;
2288
+ }
2289
+ /**
2290
+ * Page Registration (Component Pages)
2291
+ */
2292
+ interface PageRegistration {
2293
+ /** Page definition */
2294
+ definition: ComponentPageDefinition;
2295
+ /** React component */
2296
+ component: React.ComponentType<Record<string, unknown>>;
2297
+ /** Registration timestamp */
2298
+ registeredAt: Date;
2299
+ /** Category for organization */
2300
+ category: string;
2301
+ /** Tags for searching */
2302
+ tags: string[];
2303
+ }
2304
+ /**
2305
+ * Page Template Registration
2306
+ */
2307
+ interface PageTemplateRegistration {
2308
+ /** Template definition */
2309
+ template: PageTemplate;
2310
+ /** Registration timestamp */
2311
+ registeredAt: Date;
2312
+ /** Page type category */
2313
+ category: string;
2314
+ /** Tags for searching */
2315
+ tags: string[];
2316
+ }
2317
+ /**
2318
+ * Detected Editable Element Info
2319
+ * Tracks editable elements in the DOM
2320
+ */
2321
+ interface DetectedElement {
2322
+ /** Field ID from data-field-id attribute */
2323
+ fieldId: string;
2324
+ /** Element type from data-element-type attribute */
2325
+ elementType: ElementType;
2326
+ /** DOM element reference */
2327
+ element: HTMLElement;
2328
+ /** Parent section ID */
2329
+ sectionId: string;
2330
+ /** Parent block ID (if element is inside a block) */
2331
+ blockId?: string;
2332
+ /** Field label for display */
2333
+ fieldLabel: string;
2334
+ /** Whether inline editing is enabled for this element */
2335
+ isInline: boolean;
2336
+ /** Current value */
2337
+ currentValue: SettingValue;
2338
+ /** Field definition from schema */
2339
+ fieldDefinition: FieldDefinition;
2340
+ /** Last updated timestamp */
2341
+ lastUpdated?: Date;
2342
+ }
2343
+ /**
2344
+ * Editable Element Registry Interface
2345
+ * Runtime registry for tracking editable elements in the DOM
2346
+ */
2347
+ interface EditableElementRegistry {
2348
+ /**
2349
+ * Register an editable element
2350
+ */
2351
+ register(info: DetectedElement): void;
2352
+ /**
2353
+ * Get element info by field ID
2354
+ */
2355
+ get(sectionId: string, fieldId: string): DetectedElement | undefined;
2356
+ /**
2357
+ * Get element info by DOM element
2358
+ */
2359
+ getByElement(element: HTMLElement): DetectedElement | undefined;
2360
+ /**
2361
+ * Check if element is registered
2362
+ */
2363
+ has(element: HTMLElement): boolean;
2364
+ /**
2365
+ * Unregister by field ID
2366
+ */
2367
+ unregister(sectionId: string, fieldId: string): void;
2368
+ /**
2369
+ * Get all elements in a section
2370
+ */
2371
+ getBySectionId(sectionId: string): DetectedElement[];
2372
+ /**
2373
+ * Get all elements in a block
2374
+ */
2375
+ getByBlockId(sectionId: string, blockId: string): DetectedElement[];
2376
+ /**
2377
+ * Clear all registrations
2378
+ */
2379
+ clear(): void;
2380
+ /**
2381
+ * Get all registered elements
2382
+ */
2383
+ getAll(): DetectedElement[];
2384
+ }
2385
+
2386
+ /**
2387
+ * Product Type Definitions
2388
+ * Framework-agnostic product types for e-commerce themes
2389
+ */
2390
+ /**
2391
+ * Product Category Type
2392
+ * Can be extended with custom categories
2393
+ */
2394
+ type ProductCategory = string;
2395
+ /**
2396
+ * Product Tag - supports dynamic tags
2397
+ */
2398
+ type ProductTag = string;
2399
+ /**
2400
+ * Price Range for filtering
2401
+ */
2402
+ type PriceRange = "all" | "0-199k" | "200k-499k" | "500k-1m" | string;
2403
+ /**
2404
+ * Sort Options
2405
+ */
2406
+ type SortOption = "bestDeals" | "priceLowToHigh" | "priceHighToLow" | "newest" | "bestSelling";
2407
+ /**
2408
+ * Product Size
2409
+ */
2410
+ interface ProductSize {
2411
+ size: string;
2412
+ inStock: boolean;
2413
+ }
2414
+ /**
2415
+ * Product Price Group
2416
+ */
2417
+ interface ProductPriceGroup {
2418
+ id: string;
2419
+ name: string;
2420
+ }
2421
+ /**
2422
+ * Product Price
2423
+ */
2424
+ interface ProductPrice {
2425
+ price: number;
2426
+ price_group: ProductPriceGroup;
2427
+ }
2428
+ /**
2429
+ * Product Measurements
2430
+ */
2431
+ interface ProductMeasurements {
2432
+ weight_unit?: string;
2433
+ weight_value?: string;
2434
+ width_unit?: string;
2435
+ width_value?: string;
2436
+ length_unit?: string;
2437
+ length_value?: string;
2438
+ height_unit?: string;
2439
+ height_value?: string;
2440
+ }
2441
+ /**
2442
+ * Product Specifications
2443
+ */
2444
+ interface ProductSpecs {
2445
+ thickness?: string;
2446
+ lightTransmission?: string;
2447
+ reflection?: string;
2448
+ uvProtection?: string;
2449
+ irRejection?: string;
2450
+ warranty?: string;
2451
+ [key: string]: string | undefined;
2452
+ }
2453
+ /**
2454
+ * Product Option (e.g., Size, Color)
2455
+ */
2456
+ interface ProductOption {
2457
+ name: string;
2458
+ values: string[];
2459
+ }
2460
+ /**
2461
+ * Product Variant - Full variant with all options
2462
+ */
2463
+ interface ProductVariant {
2464
+ /** Variant ID */
2465
+ id: string;
2466
+ /** Variant name */
2467
+ name: string;
2468
+ /** Variant SKU */
2469
+ sku: string;
2470
+ /** Option 1 value (e.g., "0.5m×0.5m") */
2471
+ option1: string;
2472
+ /** Option 1 title (e.g., "Kích thước") */
2473
+ optionTitle1: string | null;
2474
+ /** Option 2 value (e.g., "Black") */
2475
+ option2: string;
2476
+ /** Option 2 title (e.g., "Màu sắc") */
2477
+ optionTitle2: string | null;
2478
+ /** Option 3 value */
2479
+ option3: string;
2480
+ /** Option 3 title */
2481
+ optionTitle3: string | null;
2482
+ /** Variant images */
2483
+ images: string[];
2484
+ /** Variant prices */
2485
+ prices: ProductPrice[];
2486
+ /** Variant inventories */
2487
+ inventories: unknown;
2488
+ /** Variant slug */
2489
+ slug: string;
2490
+ /** Variant measurements */
2491
+ measurements?: ProductMeasurements;
2492
+ /** Variant availability */
2493
+ inStock?: boolean;
2494
+ /** Variant price (simplified) */
2495
+ price?: number;
2496
+ /** Variant image (simplified) */
2497
+ image?: string;
2498
+ }
2499
+ /**
2500
+ * Product - Domain model for products
2501
+ * This is the transformed product data used throughout the application
2502
+ */
2503
+ interface Product {
2504
+ /** Product unique identifier */
2505
+ id: string;
2506
+ /** Product title/name */
2507
+ title: string;
2508
+ /** URL-friendly slug */
2509
+ slug?: string;
2510
+ /** Product category slug */
2511
+ category: string;
2512
+ /** Product category display name */
2513
+ categoryLabel: string;
2514
+ /** Primary product image URL */
2515
+ image: string;
2516
+ /** Additional product images */
2517
+ images?: string[];
2518
+ /** Selling price (RETAILS price group) */
2519
+ salePrice: number;
2520
+ /** Original/wholesale price (for discount calculation) */
2521
+ originalPrice: number;
2522
+ /** Discount percentage or string (calculated) */
2523
+ discount?: string | number;
2524
+ /** Product description */
2525
+ description?: string;
2526
+ /** Product tags */
2527
+ tags?: string[];
2528
+ /** Product sizes */
2529
+ sizes?: ProductSize[];
2530
+ /** Product badge */
2531
+ badge?: "hot" | "new" | "sale";
2532
+ /** Is best deal */
2533
+ isBestDeal?: boolean;
2534
+ /** Is new product */
2535
+ isNew?: boolean;
2536
+ /** Product availability */
2537
+ inStock?: boolean;
2538
+ /** Product rating (0-5) */
2539
+ rating?: number;
2540
+ /** Number of reviews */
2541
+ reviewCount?: number;
2542
+ /** Product variants (sizes, colors, etc.) */
2543
+ variants?: ProductVariant[];
2544
+ /** Product options */
2545
+ options?: ProductOption[];
2546
+ /** Product specifications */
2547
+ specs?: ProductSpecs;
2548
+ /** Product dimensions */
2549
+ dimensions?: string;
2550
+ /** Product measurements */
2551
+ measurements?: ProductMeasurements;
2552
+ /** Product metadata */
2553
+ metadata?: Record<string, unknown>;
2554
+ }
2555
+ /**
2556
+ * Product Filters
2557
+ */
2558
+ interface ProductFilters {
2559
+ category: ProductCategory;
2560
+ priceRange: PriceRange;
2561
+ tags: ProductTag[];
2562
+ sortBy: SortOption;
2563
+ }
2564
+ /**
2565
+ * Product List Item (lightweight for lists)
2566
+ */
2567
+ interface ProductListItem {
2568
+ id: string;
2569
+ title: string;
2570
+ slug: string;
2571
+ image: string;
2572
+ salePrice: number;
2573
+ originalPrice: number;
2574
+ discount?: number;
2575
+ category: string;
2576
+ }
2577
+ /**
2578
+ * Product Card Props
2579
+ */
2580
+ interface ProductCardProps extends Product {
2581
+ /** Click handler */
2582
+ onClick?: () => void;
2583
+ /** Show quick add button */
2584
+ showQuickAdd?: boolean;
2585
+ /** Custom class name */
2586
+ className?: string;
2587
+ }
2588
+
2589
+ /**
2590
+ * Blog Type Definitions
2591
+ * Framework-agnostic blog types for content themes
2592
+ */
2593
+ /**
2594
+ * Blog category type
2595
+ */
2596
+ type BlogCategory = string;
2597
+ /**
2598
+ * Blog image object from API
2599
+ */
2600
+ interface BlogImage {
2601
+ id: string;
2602
+ url: string;
2603
+ name: string;
2604
+ }
2605
+ /**
2606
+ * Blog author/user object from API
2607
+ */
2608
+ interface BlogUser {
2609
+ id: string;
2610
+ name_staff: string;
2611
+ name: string | null;
2612
+ picture: string;
2613
+ }
2614
+ /**
2615
+ * Blog category object from API
2616
+ */
2617
+ interface BlogCategoryData {
2618
+ id: string;
2619
+ name: string;
2620
+ slug: string;
2621
+ image: BlogImage | null;
2622
+ blog_total?: number;
2623
+ has_children?: boolean;
2624
+ locale?: string;
2625
+ description?: string | null;
2626
+ }
2627
+ /**
2628
+ * Blog SEO metadata
2629
+ */
2630
+ interface BlogMetaData {
2631
+ title?: string;
2632
+ description?: string;
2633
+ keywords?: string;
2634
+ author?: string | null;
2635
+ image?: string | null;
2636
+ url?: string | null;
2637
+ }
2638
+ /**
2639
+ * Response metadata for SEO
2640
+ */
2641
+ interface ResponseMetaData {
2642
+ title?: string;
2643
+ description?: string;
2644
+ keywords?: string[];
2645
+ author?: string;
2646
+ image?: string;
2647
+ }
2648
+ /**
2649
+ * Main Blog interface
2650
+ */
2651
+ interface Blog {
2652
+ /** Blog unique identifier */
2653
+ id: string;
2654
+ /** Blog title */
2655
+ title: string;
2656
+ /** URL-friendly slug */
2657
+ slug: string;
2658
+ /** Short description/summary */
2659
+ description: string;
2660
+ /** Short excerpt (alias for description, for backwards compatibility) */
2661
+ excerpt?: string;
2662
+ /** HTML content (only in detail view) */
2663
+ content?: string;
2664
+ /** Primary blog image */
2665
+ image: string;
2666
+ /** Cover image URL (only in detail view) */
2667
+ coverImage?: string;
2668
+ /** Category slug */
2669
+ category: string;
2670
+ /** Category display name */
2671
+ categoryLabel: string;
2672
+ /** Full category object */
2673
+ categoryData?: BlogCategoryData;
2674
+ /** Blog author */
2675
+ author?: BlogUser;
2676
+ /** Blog tags */
2677
+ tags?: string[];
2678
+ /** Whether published */
2679
+ publish?: boolean;
2680
+ /** Blog status */
2681
+ status?: "DRAFT" | "PUBLISHED" | "ARCHIVED";
2682
+ /** ISO date string when created */
2683
+ createdAt?: string;
2684
+ /** ISO date string when last updated */
2685
+ updatedAt?: string;
2686
+ /** ISO date string when published (alias for backwards compatibility) */
2687
+ publishedAt?: string;
2688
+ /** Locale */
2689
+ locale?: string;
2690
+ /** SEO metadata (only in detail view) */
2691
+ metaData?: BlogMetaData;
2692
+ /** Related blog IDs */
2693
+ relatedBlogIds?: string[];
2694
+ /** Total number of comments */
2695
+ totalComments?: number;
2696
+ /** Search relevance score */
2697
+ score?: number;
2698
+ /** Blog type */
2699
+ blogType?: string;
2700
+ }
2701
+ /**
2702
+ * Blog filters for client-side filtering
2703
+ */
2704
+ interface BlogFilters {
2705
+ category: BlogCategory;
2706
+ search?: string;
2707
+ }
2708
+ /**
2709
+ * Blog detail data from API
2710
+ */
2711
+ interface BlogDetailData {
2712
+ id: string;
2713
+ title: string;
2714
+ content: string;
2715
+ updated_at: string;
2716
+ locale: string;
2717
+ created_at: string;
2718
+ category: BlogCategoryData;
2719
+ meta_data?: ResponseMetaData;
2720
+ slug: string;
2721
+ image?: {
2722
+ url: string;
2723
+ };
2724
+ description?: string;
2725
+ }
2726
+ /**
2727
+ * Blog list data from API
2728
+ */
2729
+ interface BlogListData {
2730
+ items: BlogDetailData[];
2731
+ total: number;
2732
+ page: number;
2733
+ limit: number;
2734
+ }
2735
+ /**
2736
+ * Blog list item (lightweight for lists)
2737
+ */
2738
+ interface BlogListItem {
2739
+ id: string;
2740
+ title: string;
2741
+ slug: string;
2742
+ description: string;
2743
+ image: string;
2744
+ category: string;
2745
+ categoryLabel: string;
2746
+ createdAt: string;
2747
+ }
2748
+
2749
+ /**
2750
+ * Cart Type Definitions
2751
+ * Types for shopping cart functionality
2752
+ */
2753
+ interface CartItem {
2754
+ /** Unique cart item ID */
2755
+ id: string;
2756
+ /** Product ID */
2757
+ productId: string;
2758
+ /** Product slug for navigation */
2759
+ slug?: string;
2760
+ /** Product name */
2761
+ name: string;
2762
+ /** Product image URL */
2763
+ image: string;
2764
+ /** Selected size (optional - only if product has size option) */
2765
+ size?: string;
2766
+ /** Selected color (optional - only if product has color option) */
2767
+ color?: string;
2768
+ /** Label for size option (e.g., "Kích thước") */
2769
+ sizeLabel?: string;
2770
+ /** Label for color option (e.g., "Màu sắc") */
2771
+ colorLabel?: string;
2772
+ /** Unit price */
2773
+ price: number;
2774
+ /** Quantity */
2775
+ quantity: number;
2776
+ /** Variant ID (for products with variants) */
2777
+ variantId?: string;
2778
+ /** SKU */
2779
+ sku?: string;
2780
+ /** Location ID selected when adding to cart */
2781
+ locationId?: string | null;
2782
+ }
2783
+ interface CartSummary {
2784
+ /** Subtotal (sum of item prices) */
2785
+ subtotal: number;
2786
+ /** Shipping cost */
2787
+ shipping: number;
2788
+ /** Total amount */
2789
+ total: number;
2790
+ }
2791
+ interface CartContextType {
2792
+ /** Cart items */
2793
+ items: CartItem[];
2794
+ /** Add item to cart */
2795
+ addItem: (item: Omit<CartItem, "id" | "quantity">) => void;
2796
+ /** Remove item from cart */
2797
+ removeItem: (id: string) => void;
2798
+ /** Update item quantity */
2799
+ updateQuantity: (id: string, quantity: number) => void;
2800
+ /** Clear all items from cart */
2801
+ clearCart: () => void;
2802
+ /** Total number of items in cart */
2803
+ itemCount: number;
2804
+ /** Subtotal price */
2805
+ subtotal: number;
2806
+ }
2807
+
2808
+ /**
2809
+ * API Response Types
2810
+ * Generic types for API responses
2811
+ */
2812
+ /**
2813
+ * Generic API response wrapper
2814
+ */
2815
+ interface ApiResponse<T = unknown> {
2816
+ success: boolean;
2817
+ data?: T;
2818
+ message?: string;
2819
+ error?: {
2820
+ code: string;
2821
+ message: string;
2822
+ details?: unknown;
2823
+ };
2824
+ meta?: Record<string, unknown>;
2825
+ }
2826
+ /**
2827
+ * Paginated API response
2828
+ */
2829
+ interface PaginatedResponse<T = unknown> {
2830
+ items: T[];
2831
+ pagination: {
2832
+ page: number;
2833
+ limit: number;
2834
+ total: number;
2835
+ totalPages: number;
2836
+ hasNext: boolean;
2837
+ hasPrev: boolean;
2838
+ };
2839
+ }
2840
+ /**
2841
+ * Server fetcher response (used by server-side data fetchers)
2842
+ * Wraps data with success/error state and pagination
2843
+ */
2844
+ interface ServerFetcherResponse<T = unknown> {
2845
+ success: boolean;
2846
+ data: T[];
2847
+ pagination: {
2848
+ page: number;
2849
+ limit: number;
2850
+ total: number;
2851
+ totalPages: number;
2852
+ hasNext: boolean;
2853
+ hasPrev: boolean;
2854
+ };
2855
+ message?: string;
2856
+ }
2857
+ /**
2858
+ * API list response (with pagination)
2859
+ * Flat structure returned directly from the API
2860
+ */
2861
+ interface ApiListResponse<T = unknown> {
2862
+ items: T[];
2863
+ total: number;
2864
+ page: number;
2865
+ limit: number;
2866
+ }
2867
+ /**
2868
+ * Generic list query parameters
2869
+ */
2870
+ interface ListQueryParams {
2871
+ page?: number;
2872
+ limit?: number;
2873
+ sort?: string;
2874
+ order?: "asc" | "desc";
2875
+ search?: string;
2876
+ [key: string]: unknown;
2877
+ }
2878
+ /**
2879
+ * Location data structure
2880
+ */
2881
+ interface Location {
2882
+ id: string;
2883
+ name: string;
2884
+ address?: string;
2885
+ city?: string;
2886
+ state?: string;
2887
+ country?: string;
2888
+ zipCode?: string;
2889
+ phone?: string;
2890
+ email?: string;
2891
+ coordinates?: {
2892
+ lat: number;
2893
+ lng: number;
2894
+ };
2895
+ [key: string]: unknown;
2896
+ }
2897
+ /**
2898
+ * Location list response
2899
+ */
2900
+ type LocationListResponse = ApiResponse<Location[]>;
2901
+ /**
2902
+ * Price group data structure
2903
+ */
2904
+ interface ApiPriceGroup {
2905
+ price: number;
2906
+ price_group: {
2907
+ id: string;
2908
+ name: string;
2909
+ };
2910
+ }
2911
+ /**
2912
+ * Raw product data from API
2913
+ */
2914
+ interface ApiProductRaw {
2915
+ id: string;
2916
+ name: string;
2917
+ slug: string;
2918
+ price: number;
2919
+ description?: string;
2920
+ images?: Array<{
2921
+ url: string;
2922
+ alt?: string;
2923
+ }>;
2924
+ category?: {
2925
+ id: string;
2926
+ slug: string;
2927
+ name: string;
2928
+ };
2929
+ tags?: string;
2930
+ stock?: number;
2931
+ sku?: string;
2932
+ publish?: boolean;
2933
+ prices?: ApiPriceGroup[];
2934
+ variants?: Array<{
2935
+ prices?: ApiPriceGroup[];
2936
+ [key: string]: unknown;
2937
+ }>;
2938
+ [key: string]: unknown;
2939
+ }
2940
+ /**
2941
+ * Product filters query parameters
2942
+ */
2943
+ interface ProductFiltersParams extends ListQueryParams {
2944
+ category?: string;
2945
+ tags?: string[];
2946
+ minPrice?: number;
2947
+ maxPrice?: number;
2948
+ inStock?: boolean;
2949
+ }
2950
+ /**
2951
+ * Blog filters query parameters
2952
+ */
2953
+ interface BlogFiltersParams extends ListQueryParams {
2954
+ category?: string;
2955
+ tags?: string[];
2956
+ author?: string;
2957
+ dateFrom?: string;
2958
+ dateTo?: string;
2959
+ }
2960
+
2961
+ export { type ApplyScope as $, type AnimationType as A, type BaseEntity as B, type ColorFieldDefinition as C, type SectionInstance as D, type SectionComponentInstance as E, type FieldType as F, type SectionRegistration as G, type SectionComponentProps as H, type ImageFieldDefinition as I, type SectionCategory as J, SECTION_CATEGORIES as K, type ComponentType as L, type ComponentCategory as M, type NumberFieldDefinition as N, type ComponentDefinition as O, type ProductFieldDefinition as P, type ComponentInstance as Q, type RangeFieldDefinition as R, type SelectFieldDefinition as S, type TextFieldDefinition as T, type UrlFieldDefinition as U, type VideoFieldDefinition as V, type ComponentRegistration as W, type ComponentProps as X, type StyleSettings as Y, type Breakpoint as Z, type ResponsiveStyles as _, type AnimationEasing as a, type SettingsIcon as a$, type ApplyScopeResult as a0, COMPONENT_CATEGORIES as a1, COMPONENT_TYPES as a2, type PageType as a3, type PageSEO as a4, type PageConfig as a5, type PageTemplate as a6, type PageListItem as a7, type PageNavItem as a8, type PageRenderMode as a9, type SectionRegistry as aA, type BlockRegistry as aB, type DetectedSection as aC, type ElementRegistry as aD, type DetectedElement as aE, type EditableElementRegistry as aF, type PageRegistration as aG, type PageTemplateRegistration as aH, type EditorMode as aI, type SelectedElementType as aJ, type SelectedElement as aK, type EditorState as aL, type EditorActions as aM, type EditorContextValue as aN, type InspectorOverlayState as aO, type HistoryEntry as aP, type DragDropContext as aQ, type KeyboardShortcut as aR, type ElementType as aS, type ElementMetadata as aT, type DetectionPriority as aU, type DetectionStrategy as aV, type DetectionResult as aW, type InlineEditorState as aX, type InlineEditorProps as aY, type InspectorConfig as aZ, DEFAULT_INSPECTOR_CONFIG as a_, type ThemeLayoutConfig as aa, type ComponentPageDefinition as ab, type DesignToken as ac, type ColorPalette as ad, type Typography as ae, type Spacing as af, type BorderRadius as ag, type Breakpoints as ah, type ThemeConfig as ai, type ThemePreset as aj, type ThemeExport as ak, type ThemeManifest as al, type ThemeModule as am, type ThemeUpload as an, type ThemeValidationResult as ao, type ThemeValidationError as ap, type ThemeValidationWarning as aq, type RegistryConfig as ar, type RegistryEventType as as, type RegistryEvent as at, type SectionRegisteredPayload as au, type SectionUnregisteredPayload as av, type TemplateRegisteredPayload as aw, type BlockRegisteredPayload as ax, type BlockUnregisteredPayload as ay, type RegistryEventHandler as az, type AnimationTrigger as b, type SocialPlatform as b0, type SocialConnection as b1, type HotlineType as b2, type HotlineConnection as b3, type TrackingPlatform as b4, type TrackingAnalytics as b5, type ContactEmail as b6, type CompanyInfo as b7, type WebsiteSettings as b8, type EnabledItems as b9, type BlogDetailData as bA, type BlogListData as bB, type BlogListItem as bC, type CartItem as bD, type CartSummary as bE, type CartContextType as bF, type ApiResponse as bG, type PaginatedResponse as bH, type ServerFetcherResponse as bI, type ApiListResponse as bJ, type ListQueryParams as bK, type Location as bL, type LocationListResponse as bM, type ApiPriceGroup as bN, type ApiProductRaw as bO, type ProductFiltersParams as bP, type BlogFiltersParams as bQ, type ActiveSocialConnections as ba, type ActiveHotlineConnections as bb, type ActiveTrackingAnalytics as bc, type ProductCategory as bd, type ProductTag as be, type PriceRange as bf, type SortOption as bg, type ProductSize as bh, type ProductPriceGroup as bi, type ProductPrice as bj, type ProductMeasurements as bk, type ProductSpecs as bl, type ProductOption as bm, type ProductVariant as bn, type Product as bo, type ProductFilters as bp, type ProductListItem as bq, type ProductCardProps as br, type BlogCategory as bs, type BlogImage as bt, type BlogUser as bu, type BlogCategoryData as bv, type BlogMetaData as bw, type ResponseMetaData as bx, type Blog as by, type BlogFilters as bz, type AnimationSettings as c, animationFieldDefinitions as d, defaultAnimationSettings as e, type BaseFieldDefinition as f, type TextareaFieldDefinition as g, type BooleanFieldDefinition as h, type CheckboxFieldDefinition as i, type RadioFieldDefinition as j, type RichTextFieldDefinition as k, type FontFieldDefinition as l, type CollectionFieldDefinition as m, type BlogFieldDefinition as n, type ArticleFieldDefinition as o, type PageFieldDefinition as p, type FieldDefinition as q, type SettingValue as r, type Settings as s, FIELD_TYPES as t, type BlockDefinition as u, type BlockInstance as v, type BlockRegistration as w, type BlockComponentProps as x, type TemplateDefinition as y, type SectionSchema as z };