-- ============================================================================ -- EasyStream Template Builder Database Schema -- ============================================================================ -- This schema adds drag-and-drop template builder functionality to EasyStream -- Users can create custom page layouts using a visual drag-and-drop interface -- ============================================================================ -- Template Builder: Store custom user-created templates CREATE TABLE IF NOT EXISTS `db_templatebuilder_templates` ( `template_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` INT(11) UNSIGNED NOT NULL, `template_name` VARCHAR(255) NOT NULL, `template_slug` VARCHAR(255) NOT NULL, `template_type` ENUM('homepage', 'channel', 'browse', 'custom_page', 'landing') DEFAULT 'custom_page', `is_active` TINYINT(1) DEFAULT 0, `is_default` TINYINT(1) DEFAULT 0, `template_structure` LONGTEXT NOT NULL COMMENT 'JSON structure of template layout', `template_settings` TEXT COMMENT 'JSON settings (colors, fonts, spacing)', `custom_css` LONGTEXT COMMENT 'User custom CSS', `custom_js` TEXT COMMENT 'User custom JavaScript', `preview_image` VARCHAR(255) DEFAULT NULL, `views` INT(11) DEFAULT 0, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`template_id`), UNIQUE KEY `unique_slug` (`template_slug`), KEY `idx_user` (`user_id`), KEY `idx_type` (`template_type`), KEY `idx_active` (`is_active`), CONSTRAINT `fk_template_user` FOREIGN KEY (`user_id`) REFERENCES `db_accountuser` (`usr_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='User-created custom templates'; -- Template Builder: Component library (pre-built blocks users can drag) CREATE TABLE IF NOT EXISTS `db_templatebuilder_components` ( `component_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `component_name` VARCHAR(255) NOT NULL, `component_slug` VARCHAR(255) NOT NULL, `component_category` ENUM('header', 'hero', 'video_grid', 'video_list', 'sidebar', 'footer', 'text', 'image', 'custom') DEFAULT 'custom', `component_html` LONGTEXT NOT NULL COMMENT 'Smarty template HTML', `component_css` TEXT COMMENT 'Component-specific CSS', `component_settings_schema` TEXT COMMENT 'JSON schema for configurable settings', `is_system` TINYINT(1) DEFAULT 1 COMMENT 'System component (cannot be deleted)', `thumbnail` VARCHAR(255) DEFAULT NULL, `description` TEXT, `created_by` INT(11) UNSIGNED DEFAULT NULL, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`component_id`), UNIQUE KEY `unique_slug` (`component_slug`), KEY `idx_category` (`component_category`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Reusable template components'; -- Template Builder: Page assignments (which templates apply to which pages) CREATE TABLE IF NOT EXISTS `db_templatebuilder_assignments` ( `assignment_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `template_id` INT(11) UNSIGNED NOT NULL, `page_type` VARCHAR(100) NOT NULL COMMENT 'e.g., tpl_browse, tpl_view, tpl_index', `apply_to` ENUM('global', 'user_only', 'channel') DEFAULT 'user_only', `priority` INT(11) DEFAULT 0, `is_active` TINYINT(1) DEFAULT 1, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`assignment_id`), KEY `idx_template` (`template_id`), KEY `idx_page` (`page_type`), KEY `idx_active` (`is_active`), CONSTRAINT `fk_assignment_template` FOREIGN KEY (`template_id`) REFERENCES `db_templatebuilder_templates` (`template_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Template to page assignments'; -- Template Builder: Version history for templates CREATE TABLE IF NOT EXISTS `db_templatebuilder_versions` ( `version_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `template_id` INT(11) UNSIGNED NOT NULL, `version_number` INT(11) NOT NULL, `template_structure` LONGTEXT NOT NULL, `template_settings` TEXT, `custom_css` LONGTEXT, `custom_js` TEXT, `change_note` VARCHAR(500) DEFAULT NULL, `created_at` DATETIME DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`version_id`), KEY `idx_template` (`template_id`), KEY `idx_version` (`version_number`), CONSTRAINT `fk_version_template` FOREIGN KEY (`template_id`) REFERENCES `db_templatebuilder_templates` (`template_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='Template version history'; -- Template Builder: User preferences and settings CREATE TABLE IF NOT EXISTS `db_templatebuilder_user_prefs` ( `pref_id` INT(11) UNSIGNED NOT NULL AUTO_INCREMENT, `user_id` INT(11) UNSIGNED NOT NULL, `active_template_homepage` INT(11) UNSIGNED DEFAULT NULL, `active_template_channel` INT(11) UNSIGNED DEFAULT NULL, `active_template_browse` INT(11) UNSIGNED DEFAULT NULL, `builder_mode` ENUM('simple', 'advanced') DEFAULT 'simple', `auto_save` TINYINT(1) DEFAULT 1, `show_grid` TINYINT(1) DEFAULT 1, `preferences` TEXT COMMENT 'JSON additional preferences', `updated_at` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (`pref_id`), UNIQUE KEY `unique_user` (`user_id`), CONSTRAINT `fk_prefs_user` FOREIGN KEY (`user_id`) REFERENCES `db_accountuser` (`usr_id`) ON DELETE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='User template builder preferences'; -- ============================================================================ -- Insert Default System Components -- ============================================================================ -- Component: Video Grid (4 columns) INSERT INTO `db_templatebuilder_components` (`component_name`, `component_slug`, `component_category`, `component_html`, `component_css`, `component_settings_schema`, `is_system`, `description`) VALUES ('Video Grid - 4 Columns', 'video_grid_4col', 'video_grid', '
{{video_items}}
', '.component-video-grid .video-grid-container { display: grid; grid-template-columns: repeat({{columns}}, 1fr); gap: {{gap}}px; padding: {{padding}}px; }', '{"columns": {"type": "number", "default": 4, "min": 1, "max": 6}, "gap": {"type": "number", "default": 16}, "padding": {"type": "number", "default": 20}}', 1, 'Responsive video grid with configurable columns'); -- Component: Hero Section INSERT INTO `db_templatebuilder_components` (`component_name`, `component_slug`, `component_category`, `component_html`, `component_css`, `component_settings_schema`, `is_system`, `description`) VALUES ('Hero Banner', 'hero_banner', 'hero', '

{{title}}

{{subtitle}}

{if {{show_button}}} {{button_text}} {/if}
', '.component-hero { position: relative; height: {{height}}px; background-size: cover; background-position: center; display: flex; align-items: center; justify-content: center; } .hero-overlay { position: absolute; top: 0; left: 0; right: 0; bottom: 0; background: rgba(0,0,0,{{overlay_opacity}}); } .hero-content { position: relative; z-index: 1; text-align: center; color: white; }', '{"height": {"type": "number", "default": 400}, "overlay_opacity": {"type": "number", "default": 0.5, "min": 0, "max": 1, "step": 0.1}, "title": {"type": "text", "default": "Welcome"}, "subtitle": {"type": "text", "default": ""}, "button_text": {"type": "text", "default": "Get Started"}, "button_link": {"type": "text", "default": "#"}, "show_button": {"type": "boolean", "default": true}}', 1, 'Hero banner with background image and call-to-action'); -- Component: Video List (Horizontal) INSERT INTO `db_templatebuilder_components` (`component_name`, `component_slug`, `component_category`, `component_html`, `component_css`, `component_settings_schema`, `is_system`, `description`) VALUES ('Video Horizontal List', 'video_list_horizontal', 'video_list', '

{{title}}

{{video_items}}
', '.component-video-list-h .video-scroll-container { display: flex; overflow-x: auto; gap: {{gap}}px; padding: {{padding}}px 0; } .component-video-list-h .video-scroll-container::-webkit-scrollbar { height: 8px; }', '{"title": {"type": "text", "default": "Trending Videos"}, "gap": {"type": "number", "default": 16}, "padding": {"type": "number", "default": 10}}', 1, 'Horizontally scrolling video list'); -- Component: Sidebar Widget INSERT INTO `db_templatebuilder_components` (`component_name`, `component_slug`, `component_category`, `component_html`, `component_css`, `component_settings_schema`, `is_system`, `description`) VALUES ('Sidebar Widget', 'sidebar_widget', 'sidebar', '

{{widget_title}}

{{widget_content}}
', '.component-sidebar-widget { background: {{background_color}}; padding: {{padding}}px; border-radius: {{border_radius}}px; margin-bottom: 20px; } .component-sidebar-widget h3 { margin: 0 0 15px 0; font-size: {{title_size}}px; }', '{"widget_title": {"type": "text", "default": "Widget Title"}, "background_color": {"type": "color", "default": "#f5f5f5"}, "padding": {"type": "number", "default": 20}, "border_radius": {"type": "number", "default": 8}, "title_size": {"type": "number", "default": 18}}', 1, 'Configurable sidebar widget container'); -- Component: Text Block INSERT INTO `db_templatebuilder_components` (`component_name`, `component_slug`, `component_category`, `component_html`, `component_css`, `component_settings_schema`, `is_system`, `description`) VALUES ('Text Block', 'text_block', 'text', '
{if {{show_heading}}}

{{heading}}

{/if}
{{content}}
', '.component-text-block { padding: {{padding}}px; text-align: {{alignment}}; } .component-text-block h2 { color: {{heading_color}}; font-size: {{heading_size}}px; } .component-text-block .text-content { font-size: {{text_size}}px; line-height: {{line_height}}; color: {{text_color}}; }', '{"heading": {"type": "text", "default": "Heading"}, "show_heading": {"type": "boolean", "default": true}, "content": {"type": "textarea", "default": "Your content here..."}, "alignment": {"type": "select", "options": ["left", "center", "right"], "default": "left"}, "padding": {"type": "number", "default": 20}, "heading_size": {"type": "number", "default": 24}, "text_size": {"type": "number", "default": 16}, "line_height": {"type": "number", "default": 1.6, "step": 0.1}, "heading_color": {"type": "color", "default": "#333333"}, "text_color": {"type": "color", "default": "#666666"}}', 1, 'Customizable text block with heading'); -- Component: Image Block INSERT INTO `db_templatebuilder_components` (`component_name`, `component_slug`, `component_category`, `component_html`, `component_css`, `component_settings_schema`, `is_system`, `description`) VALUES ('Image Block', 'image_block', 'image', '
{{alt_text}} {if {{show_caption}}}

{{caption}}

{/if}
', '.component-image-block { text-align: {{alignment}}; padding: {{padding}}px; } .component-image-block img { max-width: {{max_width}}%; height: auto; border-radius: {{border_radius}}px; } .component-image-block .image-caption { margin-top: 10px; font-size: {{caption_size}}px; color: {{caption_color}}; }', '{"image_url": {"type": "image", "default": ""}, "alt_text": {"type": "text", "default": "Image"}, "caption": {"type": "text", "default": ""}, "show_caption": {"type": "boolean", "default": false}, "alignment": {"type": "select", "options": ["left", "center", "right"], "default": "center"}, "max_width": {"type": "number", "default": 100, "min": 10, "max": 100}, "border_radius": {"type": "number", "default": 0}, "padding": {"type": "number", "default": 20}, "caption_size": {"type": "number", "default": 14}, "caption_color": {"type": "color", "default": "#999999"}}', 1, 'Image block with optional caption'); -- Component: Custom HTML INSERT INTO `db_templatebuilder_components` (`component_name`, `component_slug`, `component_category`, `component_html`, `component_css`, `component_settings_schema`, `is_system`, `description`) VALUES ('Custom HTML', 'custom_html', 'custom', '
{{html_content}}
', '.component-custom-html { padding: {{padding}}px; }', '{"html_content": {"type": "code", "default": "

Your custom HTML here

"}, "padding": {"type": "number", "default": 0}}', 1, 'Custom HTML/Smarty code block'); -- ============================================================================ -- Add permissions for template builder (optional - if using permissions system) -- ============================================================================ -- Note: Adjust table name if your permissions table is different -- INSERT INTO `db_permissions` (`permission_name`, `permission_slug`, `description`) -- VALUES -- ('Template Builder Access', 'template_builder_access', 'Can access template builder'), -- ('Template Builder Advanced', 'template_builder_advanced', 'Can use advanced features like custom CSS/JS'), -- ('Template Builder Admin', 'template_builder_admin', 'Can manage system components and global templates'); -- ============================================================================ -- Indexes for performance -- ============================================================================ -- Additional indexes are already included in table definitions above -- ============================================================================ -- End of Template Builder Schema -- ============================================================================