/** * Image Manager Web Component * Centralized management of all image prompts and configurations * Provides a single source of truth for all image URLs in the application */ class ImageManager extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); this.config = null; this.imageCache = new Map(); } connectedCallback() { this.loadConfig(); this.render(); } loadConfig() { // Try to load from JSON config element const configElement = document.getElementById('imagePromptsConfig'); if (configElement) { try { this.config = JSON.parse(configElement.textContent); } catch (e) { console.error('Failed to parse image prompts config:', e); this.config = this.getDefaultConfig(); } } else { this.config = this.getDefaultConfig(); } // Store in global window object for easy access window.imagePrompts = this.config; } getDefaultConfig() { return { hero: "https://static.photos/medical/800x600/1", productImages: [ "https://static.photos/medical/400x300/101", "https://static.photos/medical/400x300/102", "https://static.photos/medical/400x300/103", "https://static.photos/medical/400x300/104" ], about: "https://static.photos/workspace/800x600/201", testimonials: [ "https://static.photos/people/48x48/301", "https://static.photos/people/48x48/302", "https://static.photos/people/48x48/303" ], categories: { medical: "medical", workspace: "workspace", people: "people", abstract: "abstract" }, placeholder: "https://static.photos/abstract/100x100", fallback: "https://static.photos/abstract/400x300" }; } render() { this.shadowRoot.innerHTML = `
Image Prompts Manager
Hero Image
${this.config?.hero ? this.config.hero.substring(0, 30) + '...' : ''}
Product Images (${this.config?.productImages?.length || 0})
${this.config?.productImages?.map((url, index) => `
Product ${index + 1}: ${url.substring(0, 25)}...
`).join('') || '
No product images configured
'}
Testimonial Images (${this.config?.testimonials?.length || 0})
${this.config?.testimonials?.map((url, index) => `
Testimonial ${index + 1}: ${url.substring(0, 25)}...
`).join('') || '
No testimonial images configured
'}
Configuration
Categories: ${this.config?.categories ? Object.keys(this.config.categories).join(', ') : ''}
`; this.addEventListeners(); } addEventListeners() { const toggleBtn = this.shadowRoot.querySelector('.image-manager-toggle'); const closeBtn = this.shadowRoot.querySelector('.image-manager-close'); const panel = this.shadowRoot.querySelector('.image-manager-panel'); const copyButtons = this.shadowRoot.querySelectorAll('.image-manager-copy'); if (toggleBtn && panel) { toggleBtn.addEventListener('click', () => { panel.classList.toggle('active'); }); } if (closeBtn && panel) { closeBtn.addEventListener('click', () => { panel.classList.remove('active'); }); } if (copyButtons) { copyButtons.forEach(btn => { btn.addEventListener('click', (e) => { const url = e.currentTarget.getAttribute('data-url'); this.copyToClipboard(url); // Show feedback const originalText = e.currentTarget.textContent; e.currentTarget.textContent = 'Copied!'; e.currentTarget.style.background = '#28a745'; setTimeout(() => { e.currentTarget.textContent = originalText; e.currentTarget.style.background = '#5d9245'; }, 1500); }); }); } } copyToClipboard(text) { navigator.clipboard.writeText(text).then(() => { console.log('Image URL copied to clipboard:', text); }).catch(err => { console.error('Failed to copy:', err); // Fallback method const textArea = document.createElement('textarea'); textArea.value = text; document.body.appendChild(textArea); textArea.select(); document.execCommand('copy'); document.body.removeChild(textArea); }); } // Public API methods getImage(category, index = 0) { if (!this.config) return this.config?.fallback || ''; switch(category) { case 'hero': return this.config.hero; case 'product': return this.config.productImages[index] || this.config.fallback; case 'testimonial': return this.config.testimonials[index] || this.config.fallback; case 'about': return this.config.about; case 'placeholder': return this.config.placeholder; default: return this.config.fallback; } } updateImage(category, value, index = 0) { if (!this.config) return false; switch(category) { case 'hero': this.config.hero = value; break; case 'product': if (this.config.productImages && index < this.config.productImages.length) { this.config.productImages[index] = value; } break; case 'testimonial': if (this.config.testimonials && index < this.config.testimonials.length) { this.config.testimonials[index] = value; } break; case 'about': this.config.about = value; break; default: return false; } // Update the JSON config element const configElement = document.getElementById('imagePromptsConfig'); if (configElement) { configElement.textContent = JSON.stringify(this.config, null, 2); } return true; } static get observedAttributes() { return ['config']; } attributeChangedCallback(name, oldValue, newValue) { if (name === 'config' && oldValue !== newValue) { this.loadConfig(); this.render(); } } } customElements.define('image-manager', ImageManager);