add drag and drop builder
This commit is contained in:
105
frontend/src/app/core/models/component.ts
Normal file
105
frontend/src/app/core/models/component.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
export type ComponentType =
|
||||
| 'HEADING' | 'TEXT' | 'IMAGE' | 'BUTTON' | 'DIVIDER'
|
||||
| 'GALLERY' | 'VIDEO' | 'CONTACT_FORM' | 'MAP' | 'CUSTOM_HTML';
|
||||
|
||||
export interface ComponentItem {
|
||||
id: string;
|
||||
pageId?: string;
|
||||
type: ComponentType;
|
||||
config: Record<string, unknown>;
|
||||
styles: Record<string, unknown>;
|
||||
orderIndex: number;
|
||||
}
|
||||
|
||||
export interface ComponentResponse {
|
||||
id: string;
|
||||
pageId: string;
|
||||
type: ComponentType;
|
||||
config: Record<string, unknown>;
|
||||
styles: Record<string, unknown>;
|
||||
orderIndex: number;
|
||||
}
|
||||
|
||||
export interface PageWithComponentsResponse {
|
||||
id: string;
|
||||
siteId: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
seoTitle: string;
|
||||
seoDescription: string;
|
||||
orderIndex: number;
|
||||
createdAt: string;
|
||||
components: ComponentResponse[];
|
||||
}
|
||||
|
||||
export interface SaveComponentsRequest {
|
||||
components: {
|
||||
id?: string;
|
||||
type: ComponentType;
|
||||
config: Record<string, unknown>;
|
||||
styles: Record<string, unknown>;
|
||||
orderIndex: number;
|
||||
}[];
|
||||
}
|
||||
|
||||
export function getDefaultConfig(type: ComponentType): Record<string, unknown> {
|
||||
switch (type) {
|
||||
case 'HEADING': return { text: 'Heading', level: 'h2' };
|
||||
case 'TEXT': return { content: 'Text content here...' };
|
||||
case 'IMAGE': return { src: '', alt: 'Image', linkTo: '' };
|
||||
case 'BUTTON': return { text: 'Click Me', link: '#', variant: 'filled' };
|
||||
case 'DIVIDER': return { style: 'solid' };
|
||||
case 'GALLERY': return { images: [] };
|
||||
case 'VIDEO': return { src: '', autoplay: false, controls: true };
|
||||
case 'CONTACT_FORM': return { fields: ['name', 'email', 'message'], submitText: 'Send', emailTo: '' };
|
||||
case 'MAP': return { address: 'New York, NY', zoom: 14 };
|
||||
case 'CUSTOM_HTML': return { html: '<p>Custom HTML</p>' };
|
||||
}
|
||||
}
|
||||
|
||||
export function getDefaultStyles(type: ComponentType): Record<string, unknown> {
|
||||
switch (type) {
|
||||
case 'HEADING': return { color: '#1a1a1a', fontSize: '2rem', fontWeight: '700', textAlign: 'left', margin: '0 0 1rem' };
|
||||
case 'TEXT': return { color: '#4a4a4a', fontSize: '1rem', lineHeight: '1.6', textAlign: 'left' };
|
||||
case 'IMAGE': return { width: '100%', height: 'auto', borderRadius: '0', objectFit: 'cover' };
|
||||
case 'BUTTON': return { backgroundColor: '#1976d2', color: '#ffffff', borderRadius: '4px', padding: '0.75rem 1.5rem' };
|
||||
case 'DIVIDER': return { color: '#e0e0e0', thickness: '1px', margin: '1.5rem 0' };
|
||||
case 'GALLERY': return { columns: '3', gap: '8px', borderRadius: '4px' };
|
||||
case 'VIDEO': return { width: '100%', maxWidth: '800px', borderRadius: '4px' };
|
||||
case 'CONTACT_FORM': return { backgroundColor: '#f5f5f5', padding: '2rem', borderRadius: '8px' };
|
||||
case 'MAP': return { width: '100%', height: '400px', borderRadius: '4px' };
|
||||
case 'CUSTOM_HTML': return { padding: '0', margin: '0' };
|
||||
}
|
||||
}
|
||||
|
||||
export function getComponentLabel(type: ComponentType): string {
|
||||
const labels: Record<ComponentType, string> = {
|
||||
HEADING: 'Heading',
|
||||
TEXT: 'Text',
|
||||
IMAGE: 'Image',
|
||||
BUTTON: 'Button',
|
||||
DIVIDER: 'Divider',
|
||||
GALLERY: 'Gallery',
|
||||
VIDEO: 'Video',
|
||||
CONTACT_FORM: 'Contact Form',
|
||||
MAP: 'Map',
|
||||
CUSTOM_HTML: 'Custom HTML',
|
||||
};
|
||||
return labels[type];
|
||||
}
|
||||
|
||||
export function getComponentIcon(type: ComponentType): string {
|
||||
const icons: Record<ComponentType, string> = {
|
||||
HEADING: 'title',
|
||||
TEXT: 'text_fields',
|
||||
IMAGE: 'image',
|
||||
BUTTON: 'smart_button',
|
||||
DIVIDER: 'horizontal_rule',
|
||||
GALLERY: 'photo_library',
|
||||
VIDEO: 'videocam',
|
||||
CONTACT_FORM: 'contact_mail',
|
||||
MAP: 'map',
|
||||
CUSTOM_HTML: 'code',
|
||||
};
|
||||
return icons[type];
|
||||
}
|
||||
Reference in New Issue
Block a user