awesome-chatgpt-prompts/embed-script.js

700 lines
29 KiB
JavaScript
Raw Normal View History

2025-06-16 16:07:02 +03:00
class EmbedDesigner {
constructor() {
this.params = this.parseURLParams();
this.config = this.getInitialConfig();
this.initDesignerMode();
}
parseURLParams() {
const urlParams = new URLSearchParams(window.location.search);
const params = {};
for (const [key, value] of urlParams.entries()) {
params[key] = decodeURIComponent(value);
}
return params;
}
getInitialConfig() {
2025-06-16 23:33:48 +03:00
// Check if we have URL parameters
const hasUrlParams = Object.keys(this.params).length > 0;
// If URL params exist, prioritize them over saved config
if (hasUrlParams) {
// Start with defaults, then apply saved config, then override with URL params
const savedConfig = this.loadFromLocalStorage() || {};
return {
prompt: this.params.prompt || savedConfig.prompt || '',
context: this.params.context ? this.params.context.split(',').map(c => c.trim()) : (savedConfig.context || []),
model: this.params.model || savedConfig.model || 'gpt-4o',
mode: this.params.agentMode || savedConfig.mode || 'chat',
thinking: this.params.thinking === 'true' ? true : (this.params.thinking === 'false' ? false : (savedConfig.thinking || false)),
max: this.params.max === 'true' ? true : (this.params.max === 'false' ? false : (savedConfig.max || false)),
lightColor: this.params.lightColor || savedConfig.lightColor || '#3b82f6',
darkColor: this.params.darkColor || savedConfig.darkColor || '#60a5fa',
height: this.params.height || savedConfig.height || '400',
2025-06-17 19:41:56 +03:00
themeMode: this.params.themeMode || savedConfig.themeMode || 'auto',
2025-06-18 16:21:53 +03:00
filetree: this.params.filetree ? decodeURIComponent(this.params.filetree).split('\n').filter(f => f.trim()) : (savedConfig.filetree || []),
showFiletree: savedConfig.showFiletree !== undefined ? savedConfig.showFiletree : true
2025-06-16 23:33:48 +03:00
};
}
// Otherwise, try to load from localStorage
2025-06-16 16:07:02 +03:00
const savedConfig = this.loadFromLocalStorage();
if (savedConfig) {
return savedConfig;
}
2025-06-16 23:33:48 +03:00
// Fall back to defaults
2025-06-16 16:07:02 +03:00
return {
2025-06-16 23:33:48 +03:00
prompt: '',
context: [],
model: 'gpt-4o',
mode: 'chat',
thinking: false,
max: false,
lightColor: '#3b82f6',
darkColor: '#60a5fa',
height: '400',
2025-06-17 19:41:56 +03:00
themeMode: 'auto',
2025-06-18 16:21:53 +03:00
filetree: [],
showFiletree: true
2025-06-16 16:07:02 +03:00
};
}
loadFromLocalStorage() {
try {
const saved = localStorage.getItem('embedDesignerConfig');
if (saved) {
const config = JSON.parse(saved);
// Validate the loaded config has all required fields
if (config && typeof config === 'object') {
2025-06-17 19:41:56 +03:00
// Ensure all properties have defaults
return {
prompt: config.prompt || '',
context: config.context || [],
model: config.model || 'gpt-4o',
mode: config.mode || 'chat',
thinking: config.thinking || false,
max: config.max || false,
lightColor: config.lightColor || '#3b82f6',
darkColor: config.darkColor || '#60a5fa',
height: config.height || '400',
themeMode: config.themeMode || 'auto',
2025-06-18 16:21:53 +03:00
filetree: config.filetree || [],
showFiletree: config.showFiletree !== undefined ? config.showFiletree : true
2025-06-17 19:41:56 +03:00
};
2025-06-16 16:07:02 +03:00
}
}
} catch (e) {
console.error('Error loading from localStorage:', e);
}
return null;
}
saveToLocalStorage() {
try {
localStorage.setItem('embedDesignerConfig', JSON.stringify(this.config));
// Auto-save is silent - no notification
} catch (e) {
console.error('Error saving to localStorage:', e);
}
}
clearLocalStorage() {
try {
localStorage.removeItem('embedDesignerConfig');
this.showNotification('Settings cleared!');
} catch (e) {
console.error('Error clearing localStorage:', e);
}
}
initDesignerMode() {
this.setupDesignerElements();
this.setupDesignerEvents();
this.setupDesignerColors();
this.updatePreview();
2025-06-16 16:24:18 +03:00
this.updateIframeSnippet();
2025-06-16 16:07:02 +03:00
}
setupDesignerElements() {
// Populate form with current config
document.getElementById('designer-prompt').value = this.config.prompt;
document.getElementById('designer-context').value = this.config.context.join(', ');
2025-06-17 19:41:56 +03:00
document.getElementById('designer-filetree').value = this.config.filetree.join('\n');
2025-06-16 16:07:02 +03:00
// Handle model selection
const modelSelect = document.getElementById('designer-model');
const customModelInput = document.getElementById('designer-custom-model');
// Check if model is one of the predefined options
const isPredefinedModel = Array.from(modelSelect.options).some(opt => opt.value === this.config.model);
if (isPredefinedModel) {
modelSelect.value = this.config.model;
customModelInput.classList.add('hidden');
} else {
// It's a custom model
modelSelect.value = 'custom';
customModelInput.value = this.config.model;
customModelInput.classList.remove('hidden');
}
document.getElementById('designer-mode-select').value = this.config.mode;
document.getElementById('designer-thinking').checked = this.config.thinking;
document.getElementById('designer-max').checked = this.config.max;
2025-06-18 16:21:53 +03:00
// Set show filetree checkbox (default to true if not set)
const showFiletreeCheckbox = document.getElementById('designer-show-filetree');
if (showFiletreeCheckbox) {
showFiletreeCheckbox.checked = this.config.showFiletree !== false;
}
2025-06-16 16:07:02 +03:00
// Set height slider
const heightSlider = document.getElementById('designer-height');
const heightValue = document.getElementById('height-value');
if (heightSlider) {
heightSlider.value = this.config.height;
if (heightValue) {
heightValue.textContent = this.config.height;
}
}
// Set theme mode buttons
this.updateThemeModeButtons();
// Set color values
const lightColorPicker = document.getElementById('designer-light-color');
const lightColorText = document.getElementById('designer-light-color-text');
const darkColorPicker = document.getElementById('designer-dark-color');
const darkColorText = document.getElementById('designer-dark-color-text');
if (lightColorPicker) {
lightColorPicker.value = this.config.lightColor;
lightColorText.value = this.config.lightColor;
}
if (darkColorPicker) {
darkColorPicker.value = this.config.darkColor;
darkColorText.value = this.config.darkColor;
}
}
updateThemeModeButtons() {
// Update theme mode button states
document.querySelectorAll('.theme-mode-btn').forEach(btn => {
btn.classList.remove('bg-dynamic-primary', 'text-white');
btn.classList.add('bg-dynamic-background', 'text-dynamic-foreground');
});
const activeButton = document.getElementById(`theme-${this.config.themeMode}`);
if (activeButton) {
activeButton.classList.remove('bg-dynamic-background', 'text-dynamic-foreground');
activeButton.classList.add('bg-dynamic-primary', 'text-white');
}
}
setupDesignerEvents() {
// Form changes update preview
2025-06-18 16:21:53 +03:00
['designer-prompt', 'designer-context', 'designer-mode-select', 'designer-thinking', 'designer-max', 'designer-filetree', 'designer-show-filetree'].forEach(id => {
2025-06-16 16:07:02 +03:00
const element = document.getElementById(id);
2025-06-18 16:21:53 +03:00
if (element) {
element.addEventListener('input', () => this.updateConfigFromForm());
element.addEventListener('change', () => this.updateConfigFromForm());
}
2025-06-16 16:07:02 +03:00
});
// Theme mode buttons
document.querySelectorAll('.theme-mode-btn').forEach(btn => {
btn.addEventListener('click', (e) => {
const mode = e.target.id.replace('theme-', '');
this.config.themeMode = mode;
this.updateThemeModeButtons();
this.updatePreview();
this.saveToLocalStorage();
});
});
// Color preset buttons
document.querySelectorAll('.color-preset').forEach(btn => {
btn.addEventListener('click', (e) => {
const lightColor = e.currentTarget.getAttribute('data-light');
const darkColor = e.currentTarget.getAttribute('data-dark');
// Update color pickers and text inputs
const lightColorPicker = document.getElementById('designer-light-color');
const lightColorText = document.getElementById('designer-light-color-text');
const darkColorPicker = document.getElementById('designer-dark-color');
const darkColorText = document.getElementById('designer-dark-color-text');
if (lightColorPicker && lightColor) {
lightColorPicker.value = lightColor;
lightColorText.value = lightColor;
}
if (darkColorPicker && darkColor) {
darkColorPicker.value = darkColor;
darkColorText.value = darkColor;
}
this.updateConfigFromForm();
});
});
// Model dropdown special handling
const modelSelect = document.getElementById('designer-model');
const customModelInput = document.getElementById('designer-custom-model');
modelSelect.addEventListener('change', () => {
if (modelSelect.value === 'custom') {
customModelInput.classList.remove('hidden');
customModelInput.focus();
} else {
customModelInput.classList.add('hidden');
}
this.updateConfigFromForm();
});
// Custom model input
customModelInput.addEventListener('input', () => this.updateConfigFromForm());
// Height slider
const heightSlider = document.getElementById('designer-height');
const heightValue = document.getElementById('height-value');
if (heightSlider) {
heightSlider.addEventListener('input', (e) => {
if (heightValue) {
heightValue.textContent = e.target.value;
}
this.updateConfigFromForm();
});
}
// Color pickers
const lightColorPicker = document.getElementById('designer-light-color');
const lightColorText = document.getElementById('designer-light-color-text');
const darkColorPicker = document.getElementById('designer-dark-color');
const darkColorText = document.getElementById('designer-dark-color-text');
if (lightColorPicker) {
lightColorPicker.addEventListener('input', (e) => {
lightColorText.value = e.target.value;
this.updateConfigFromForm();
});
}
if (lightColorText) {
lightColorText.addEventListener('input', (e) => {
if (/^#[0-9A-Fa-f]{6}$/.test(e.target.value)) {
lightColorPicker.value = e.target.value;
this.updateConfigFromForm();
}
});
}
if (darkColorPicker) {
darkColorPicker.addEventListener('input', (e) => {
darkColorText.value = e.target.value;
this.updateConfigFromForm();
});
}
if (darkColorText) {
darkColorText.addEventListener('input', (e) => {
if (/^#[0-9A-Fa-f]{6}$/.test(e.target.value)) {
darkColorPicker.value = e.target.value;
this.updateConfigFromForm();
}
});
}
// Generate embed button
document.getElementById('generate-embed').addEventListener('click', () => this.showEmbedModal());
2025-06-16 16:24:18 +03:00
// Iframe snippet click to copy
document.getElementById('iframe-snippet').addEventListener('click', () => this.copyIframeCode());
2025-06-16 16:07:02 +03:00
// Reset settings button
document.getElementById('reset-settings').addEventListener('click', () => {
if (confirm('Are you sure you want to reset all settings to defaults?')) {
this.clearLocalStorage();
// Reset to default config
this.config = {
prompt: '',
context: [],
model: 'gpt-4o',
mode: 'chat',
thinking: false,
max: false,
lightColor: '#3b82f6',
darkColor: '#60a5fa',
height: '400',
2025-06-17 19:41:56 +03:00
themeMode: 'auto',
2025-06-18 16:21:53 +03:00
filetree: [],
showFiletree: true
2025-06-16 16:07:02 +03:00
};
// Update UI to reflect defaults
this.setupDesignerElements();
this.updatePreview();
2025-06-16 16:24:18 +03:00
this.updateIframeSnippet();
2025-06-16 16:07:02 +03:00
}
});
2025-06-18 16:21:53 +03:00
// Example buttons
document.getElementById('vibe-example').addEventListener('click', () => {
this.loadVibeExample();
});
document.getElementById('chat-example').addEventListener('click', () => {
this.loadChatExample();
2025-06-16 16:24:18 +03:00
});
2025-06-16 16:07:02 +03:00
// Modal events
document.getElementById('close-modal').addEventListener('click', () => this.hideEmbedModal());
document.getElementById('copy-embed-code').addEventListener('click', () => this.copyEmbedCode());
document.getElementById('copy-share-url').addEventListener('click', () => this.copyShareURL());
// Close modal on backdrop click
document.getElementById('embed-modal').addEventListener('click', (e) => {
if (e.target.id === 'embed-modal') this.hideEmbedModal();
});
}
updateConfigFromForm() {
const heightSlider = document.getElementById('designer-height');
const modelSelect = document.getElementById('designer-model');
const customModelInput = document.getElementById('designer-custom-model');
const lightColorText = document.getElementById('designer-light-color-text');
const darkColorText = document.getElementById('designer-dark-color-text');
// Get model value
let modelValue = modelSelect.value;
if (modelValue === 'custom') {
modelValue = customModelInput.value || 'Custom Model';
}
this.config = {
prompt: document.getElementById('designer-prompt').value,
context: document.getElementById('designer-context').value.split(',').map(c => c.trim()).filter(c => c),
model: modelValue,
mode: document.getElementById('designer-mode-select').value,
thinking: document.getElementById('designer-thinking').checked,
max: document.getElementById('designer-max').checked,
lightColor: lightColorText ? lightColorText.value : '#3b82f6',
darkColor: darkColorText ? darkColorText.value : '#60a5fa',
height: heightSlider ? heightSlider.value : '400',
2025-06-17 19:41:56 +03:00
themeMode: this.config.themeMode || 'auto',
2025-06-18 16:21:53 +03:00
filetree: document.getElementById('designer-filetree').value.split('\n').map(f => f.trim()).filter(f => f),
showFiletree: document.getElementById('designer-show-filetree').checked
2025-06-16 16:07:02 +03:00
};
this.updatePreview();
this.saveToLocalStorage();
2025-06-16 16:24:18 +03:00
this.updateIframeSnippet();
}
updateIframeSnippet() {
const snippet = document.getElementById('iframe-snippet');
if (!snippet) return;
const code = this.generateEmbedCode();
// Show a shortened version in the snippet
const shortCode = code.replace(/\n/g, ' ').replace(/\s+/g, ' ');
snippet.textContent = shortCode;
2025-06-16 16:07:02 +03:00
}
setupDesignerColors() {
// Set up fixed designer colors - always use default blue theme in light mode
const root = document.documentElement;
// Always use default blue colors for designer
root.style.setProperty('--primary', '59 130 246'); // Blue-500
root.style.setProperty('--background', '255 255 255');
root.style.setProperty('--foreground', '15 23 42');
root.style.setProperty('--muted', '248 250 252');
root.style.setProperty('--muted-foreground', '100 116 139');
root.style.setProperty('--border', '226 232 240');
root.style.setProperty('--accent', '16 185 129');
}
updateDesignerColors() {
// Deprecated - no longer update designer colors
// Designer maintains fixed color scheme
}
updatePreview() {
const previewContainer = document.getElementById('preview-container');
const previewWrapper = document.getElementById('preview-wrapper');
if (!previewContainer) return;
// Update preview wrapper height
if (previewWrapper) {
previewWrapper.style.height = `${this.config.height}px`;
}
// Generate preview URL with parameters
const previewUrl = this.generatePreviewURL();
// Update iframe src
let iframe = previewContainer.querySelector('iframe');
if (!iframe) {
iframe = document.createElement('iframe');
iframe.className = 'w-full h-full border-0 rounded-lg';
previewContainer.innerHTML = '';
previewContainer.appendChild(iframe);
}
iframe.src = previewUrl;
}
generatePreviewURL() {
const params = new URLSearchParams();
if (this.config.prompt) params.set('prompt', this.config.prompt);
if (this.config.context.length > 0) params.set('context', this.config.context.join(','));
if (this.config.model !== 'gpt-4o') params.set('model', this.config.model);
if (this.config.mode !== 'chat') params.set('agentMode', this.config.mode);
if (this.config.thinking) params.set('thinking', 'true');
if (this.config.max) params.set('max', 'true');
if (this.config.lightColor !== '#3b82f6') params.set('lightColor', this.config.lightColor);
if (this.config.darkColor !== '#60a5fa') params.set('darkColor', this.config.darkColor);
if (this.config.themeMode !== 'auto') params.set('themeMode', this.config.themeMode);
2025-06-18 16:21:53 +03:00
if (this.config.showFiletree && this.config.filetree && this.config.filetree.length > 0) params.set('filetree', encodeURIComponent(this.config.filetree.join('\n')));
2025-06-16 16:07:02 +03:00
params.set('preview', 'true');
return `/embed-preview/?${params.toString()}`;
}
generateShareURL() {
const params = new URLSearchParams();
if (this.config.prompt) params.set('prompt', this.config.prompt);
if (this.config.context.length > 0) params.set('context', this.config.context.join(','));
if (this.config.model !== 'gpt-4o') params.set('model', this.config.model);
if (this.config.mode !== 'chat') params.set('agentMode', this.config.mode);
if (this.config.thinking) params.set('thinking', 'true');
if (this.config.max) params.set('max', 'true');
if (this.config.lightColor !== '#3b82f6') params.set('lightColor', this.config.lightColor);
if (this.config.darkColor !== '#60a5fa') params.set('darkColor', this.config.darkColor);
if (this.config.themeMode !== 'auto') params.set('themeMode', this.config.themeMode);
2025-06-18 16:21:53 +03:00
if (this.config.showFiletree && this.config.filetree && this.config.filetree.length > 0) params.set('filetree', encodeURIComponent(this.config.filetree.join('\n')));
2025-06-16 16:07:02 +03:00
return `${window.location.origin}/embed-preview/?${params.toString()}`;
}
generateEmbedCode() {
const url = this.generateShareURL();
return `<iframe
src="${url}"
width="100%"
height="${this.config.height}"
frameborder="0"
style="border-radius: 12px; border: 1px solid #e5e7eb;">
</iframe>`;
}
showEmbedModal() {
const modal = document.getElementById('embed-modal');
const embedCode = document.getElementById('embed-code');
const shareUrl = document.getElementById('share-url');
embedCode.value = this.generateEmbedCode();
shareUrl.value = this.generateShareURL();
modal.classList.remove('hidden');
}
hideEmbedModal() {
document.getElementById('embed-modal').classList.add('hidden');
}
async copyEmbedCode() {
const embedCode = document.getElementById('embed-code').value;
await this.copyToClipboard(embedCode);
this.showNotification('Embed code copied to clipboard!');
}
async copyShareURL() {
const shareUrl = this.generateShareURL();
await this.copyToClipboard(shareUrl);
this.showNotification('Share URL copied to clipboard!');
}
2025-06-16 16:24:18 +03:00
async copyIframeCode() {
const embedCode = this.generateEmbedCode();
await this.copyToClipboard(embedCode);
this.showNotification('Iframe code copied to clipboard!');
}
2025-06-16 16:07:02 +03:00
async copyToClipboard(text) {
if (navigator.clipboard && window.isSecureContext) {
await navigator.clipboard.writeText(text);
} else {
// Fallback
const textArea = document.createElement('textarea');
textArea.value = text;
textArea.style.position = 'fixed';
textArea.style.left = '-999999px';
textArea.style.top = '-999999px';
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
document.execCommand('copy');
textArea.remove();
}
}
showNotification(message, duration = 2000) {
const notification = document.getElementById('notification');
if (!notification) return;
notification.textContent = message;
notification.classList.remove('opacity-0');
notification.classList.add('opacity-100');
setTimeout(() => {
notification.classList.remove('opacity-100');
notification.classList.add('opacity-0');
}, duration);
}
2025-06-16 16:24:18 +03:00
2025-06-18 16:21:53 +03:00
loadVibeExample() {
// Set vibe coding example values
2025-06-17 19:41:56 +03:00
document.getElementById('designer-prompt').value =
2025-06-18 16:21:53 +03:00
`I'm working on a React e-commerce app. The current ProductList component is getting messy with too much logic.
2025-06-17 19:41:56 +03:00
2025-06-18 16:21:53 +03:00
Can you help me refactor it to:
1. Extract the filtering logic into a custom hook
2. Split the large component into smaller, reusable pieces
3. Add proper TypeScript types
4. Implement virtualization for better performance with large product lists
2025-06-17 19:41:56 +03:00
2025-06-18 16:21:53 +03:00
The component currently handles products display, filtering by category/price, sorting, and pagination all in one file. I want a cleaner architecture.`;
2025-06-17 19:41:56 +03:00
2025-06-18 16:21:53 +03:00
document.getElementById('designer-context').value = '@codebase, ProductList.tsx, components/, hooks/';
2025-06-17 19:41:56 +03:00
document.getElementById('designer-filetree').value =
2025-06-18 16:21:53 +03:00
`src/
src/components/
src/components/ProductList.tsx*
src/components/ProductCard.tsx
src/components/ProductGrid.tsx
src/components/Filters/
src/components/Filters/CategoryFilter.tsx
src/components/Filters/PriceRangeFilter.tsx
src/components/Filters/index.tsx
src/hooks/
src/hooks/useProducts.ts
src/hooks/useFilters.ts
src/hooks/useInfiniteScroll.ts
src/types/
src/types/product.ts
src/api/
src/api/products.ts
src/utils/
src/utils/formatters.ts
2025-06-17 19:41:56 +03:00
package.json
2025-06-18 16:21:53 +03:00
tsconfig.json`;
2025-06-17 19:41:56 +03:00
2025-06-18 16:21:53 +03:00
// Set vibe coding settings
document.getElementById('designer-model').value = 'Claude 4 Opus';
2025-06-17 19:41:56 +03:00
document.getElementById('designer-mode-select').value = 'agent';
document.getElementById('designer-thinking').checked = true;
2025-06-18 16:21:53 +03:00
document.getElementById('designer-max').checked = true;
document.getElementById('designer-show-filetree').checked = true;
2025-06-18 16:30:39 +03:00
// Set height and colors for coding example
const heightSlider = document.getElementById('designer-height');
const heightValue = document.getElementById('height-value');
if (heightSlider) {
heightSlider.value = '500';
if (heightValue) {
heightValue.textContent = '500';
}
}
// Set developer-friendly color scheme (purple/violet)
document.getElementById('designer-light-color').value = '#8b5cf6';
document.getElementById('designer-light-color-text').value = '#8b5cf6';
document.getElementById('designer-dark-color').value = '#a78bfa';
document.getElementById('designer-dark-color-text').value = '#a78bfa';
// Set dark theme mode for coding
this.config.themeMode = 'dark';
this.updateThemeModeButtons();
2025-06-18 16:21:53 +03:00
// Update config from form
this.updateConfigFromForm();
this.showNotification('Vibe coding example loaded!');
}
loadChatExample() {
// Set chat example values
document.getElementById('designer-prompt').value =
`I'm planning a dinner party for 8 people this weekend. One person is vegetarian, another is gluten-free, and I want to make something impressive but not too complicated.
Can you suggest a menu with appetizers, main course, and dessert that would work for everyone? I have about 4 hours to prepare everything and a moderate cooking skill level.`;
document.getElementById('designer-context').value = '#Screenshot Kitchen Layout.png, Recipes Collection.pdf';
document.getElementById('designer-filetree').value = '';
// Set chat settings
document.getElementById('designer-model').value = 'GPT 4o';
document.getElementById('designer-mode-select').value = 'chat';
document.getElementById('designer-thinking').checked = false;
document.getElementById('designer-max').checked = false;
document.getElementById('designer-show-filetree').checked = false;
2025-06-17 19:41:56 +03:00
2025-06-18 16:30:39 +03:00
// Set height and colors for chat example
const heightSlider = document.getElementById('designer-height');
const heightValue = document.getElementById('height-value');
if (heightSlider) {
heightSlider.value = '350';
if (heightValue) {
heightValue.textContent = '350';
}
}
// Set friendly color scheme (green)
document.getElementById('designer-light-color').value = '#10b981';
document.getElementById('designer-light-color-text').value = '#10b981';
document.getElementById('designer-dark-color').value = '#34d399';
document.getElementById('designer-dark-color-text').value = '#34d399';
// Set light theme mode for chat
this.config.themeMode = 'light';
this.updateThemeModeButtons();
2025-06-17 19:41:56 +03:00
// Update config from form
this.updateConfigFromForm();
2025-06-16 16:24:18 +03:00
2025-06-18 16:21:53 +03:00
this.showNotification('Chat example loaded!');
2025-06-16 16:24:18 +03:00
}
2025-06-16 16:07:02 +03:00
}
// Dark mode toggle function
function toggleDarkMode() {
const body = document.body;
const isDark = body.classList.contains('dark-mode');
if (isDark) {
body.classList.remove('dark-mode');
localStorage.setItem('darkMode', 'false');
document.querySelector('.dark-mode-toggle .sun-icon').style.display = 'block';
document.querySelector('.dark-mode-toggle .moon-icon').style.display = 'none';
} else {
body.classList.add('dark-mode');
localStorage.setItem('darkMode', 'true');
document.querySelector('.dark-mode-toggle .sun-icon').style.display = 'none';
document.querySelector('.dark-mode-toggle .moon-icon').style.display = 'block';
}
}
// Initialize when DOM is ready
document.addEventListener('DOMContentLoaded', () => {
window.embedDesigner = new EmbedDesigner();
// Initialize dark mode from localStorage
const darkMode = localStorage.getItem('darkMode');
if (darkMode === 'true') {
document.body.classList.add('dark-mode');
document.querySelector('.dark-mode-toggle .sun-icon').style.display = 'none';
document.querySelector('.dark-mode-toggle .moon-icon').style.display = 'block';
}
});