Spaces:
Running
Running
Build a modern, minimalistic website that acts as a directory for AI-generated image prompt components and their corresponding output images.
c00d809
verified
| // Demo data for proof of concept | |
| const demoData = [ | |
| { | |
| prompt: "A futuristic cityscape at night with neon lights reflecting on wet streets, cyberpunk aesthetic, cinematic lighting, 8k resolution", | |
| image: "http://static.photos/cityscape/640x360/1", | |
| tags: ["cyberpunk", "futuristic", "night", "urban"] | |
| }, | |
| { | |
| prompt: "Minimalist interior design with clean lines, natural light, Scandinavian style, wooden furniture, plants, soft textures", | |
| image: "http://static.photos/interior/640x360/2", | |
| tags: ["minimalist", "scandinavian", "interior", "natural"] | |
| }, | |
| { | |
| prompt: "Abstract geometric patterns with vibrant colors, digital art, fractal designs, high detail, symmetrical composition", | |
| image: "http://static.photos/abstract/640x360/3", | |
| tags: ["abstract", "geometric", "digital", "vibrant"] | |
| }, | |
| { | |
| prompt: "Steampunk airship flying over Victorian-era city, brass and copper details, mechanical wings, cloudy sky, detailed machinery", | |
| image: "http://static.photos/technology/640x360/4", | |
| tags: ["steampunk", "victorian", "airship", "mechanical"] | |
| }, | |
| { | |
| prompt: "Underwater coral reef with bioluminescent creatures, deep sea colors, mysterious atmosphere, high detail, 4k resolution", | |
| image: "http://static.photos/nature/640x360/5", | |
| tags: ["underwater", "bioluminescent", "nature", "mysterious"] | |
| }, | |
| { | |
| prompt: "Space station orbiting a gas giant planet, futuristic architecture, stars in background, cinematic composition, NASA aesthetic", | |
| image: "http://static.photos/space/640x360/6", | |
| tags: ["space", "futuristic", "cinematic", "science"] | |
| }, | |
| { | |
| prompt: "Vintage film noir scene with detective in trench coat, rainy street, neon signs, dramatic shadows, black and white with selective color", | |
| image: "http://static.photos/cityscape/640x360/7", | |
| tags: ["noir", "vintage", "detective", "dramatic"] | |
| }, | |
| { | |
| prompt: "Fantasy forest with glowing mushrooms, magical creatures, ethereal lighting, detailed environment, concept art style", | |
| image: "http://static.photos/nature/640x360/8", | |
| tags: ["fantasy", "magical", "forest", "ethereal"] | |
| }, | |
| { | |
| prompt: "Industrial robot arm assembling circuit boards, factory setting, metallic textures, sparks, high-tech machinery, detailed mechanics", | |
| image: "http://static.photos/technology/640x360/9", | |
| tags: ["industrial", "robotic", "technology", "mechanical"] | |
| } | |
| ]; | |
| let allTags = []; | |
| let currentFilter = ''; | |
| let filteredData = [...demoData]; | |
| // Initialize the page | |
| document.addEventListener('DOMContentLoaded', () => { | |
| // Extract all unique tags | |
| demoData.forEach(item => { | |
| item.tags.forEach(tag => { | |
| if (!allTags.includes(tag)) { | |
| allTags.push(tag); | |
| } | |
| }); | |
| }); | |
| renderTagFilters(); | |
| renderPromptCards(); | |
| // Set up dark mode toggle | |
| const toggleButton = document.getElementById('toggleDarkMode'); | |
| toggleButton.addEventListener('click', () => { | |
| document.documentElement.classList.toggle('dark'); | |
| localStorage.setItem('darkMode', document.documentElement.classList.contains('dark')); | |
| feather.replace(); | |
| }); | |
| // Check for saved dark mode preference | |
| if (localStorage.getItem('darkMode') === 'true') { | |
| document.documentElement.classList.add('dark'); | |
| } | |
| // Add grid overlay | |
| const gridOverlay = document.createElement('div'); | |
| gridOverlay.className = 'grid-overlay'; | |
| document.body.appendChild(gridOverlay); | |
| }); | |
| // Render tag filter chips | |
| function renderTagFilters() { | |
| const container = document.getElementById('tagFilters'); | |
| container.innerHTML = '<button class="tag px-3 py-1 bg-gray-200 dark:bg-gray-700 rounded-full text-sm hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors" data-tag="">All</button>'; | |
| allTags.forEach(tag => { | |
| const tagButton = document.createElement('button'); | |
| tagButton.className = 'tag px-3 py-1 bg-gray-200 dark:bg-gray-700 rounded-full text-sm hover:bg-gray-300 dark:hover:bg-gray-600 transition-colors'; | |
| tagButton.textContent = tag; | |
| tagButton.dataset.tag = tag; | |
| tagButton.addEventListener('click', () => { | |
| document.querySelectorAll('.tag').forEach(btn => btn.classList.remove('bg-blue-500', 'dark:bg-blue-600', 'text-white')); | |
| tagButton.classList.add('bg-blue-500', 'dark:bg-blue-600', 'text-white'); | |
| currentFilter = tag; | |
| filterPrompts(); | |
| }); | |
| container.appendChild(tagButton); | |
| }); | |
| } | |
| // Render prompt cards | |
| function renderPromptCards() { | |
| const container = document.getElementById('promptGrid'); | |
| container.innerHTML = ''; | |
| filteredData.forEach(item => { | |
| const card = document.createElement('div'); | |
| card.className = 'prompt-card bg-white dark:bg-gray-800 rounded-xl overflow-hidden shadow-md hover:shadow-xl transition-shadow duration-300'; | |
| card.innerHTML = ` | |
| <div class="relative"> | |
| <img src="${item.image}" alt="AI-generated image" class="w-full h-48 object-cover"> | |
| <div class="prompt-overlay absolute inset-0 flex items-center justify-center opacity-0 hover:opacity-100 p-4"> | |
| <p class="text-white text-center text-sm">${item.prompt}</p> | |
| </div> | |
| <div class="absolute top-2 right-2"> | |
| <button class="copy-btn bg-white dark:bg-gray-700 p-2 rounded-full shadow-md" data-prompt="${item.prompt.replace(/"/g, '"')}"> | |
| <i data-feather="copy" class="w-4 h-4"></i> | |
| </button> | |
| </div> | |
| </div> | |
| <div class="p-4"> | |
| <div class="flex flex-wrap gap-2 mb-3"> | |
| ${item.tags.map(tag => `<span class="px-2 py-1 bg-gray-100 dark:bg-gray-700 text-xs rounded">${tag}</span>`).join('')} | |
| </div> | |
| <button class="copy-btn w-full py-2 bg-gray-100 dark:bg-gray-700 rounded-lg text-sm flex items-center justify-center gap-2 hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors" data-prompt="${item.prompt.replace(/"/g, '"')}"> | |
| <i data-feather="copy" class="w-4 h-4"></i> | |
| Copy Prompt | |
| </button> | |
| </div> | |
| `; | |
| container.appendChild(card); | |
| }); | |
| // Initialize feather icons | |
| feather.replace(); | |
| // Add event listeners to copy buttons | |
| document.querySelectorAll('.copy-btn').forEach(button => { | |
| button.addEventListener('click', (e) => { | |
| const prompt = e.currentTarget.dataset.prompt; | |
| navigator.clipboard.writeText(prompt).then(() => { | |
| // Show feedback | |
| const originalHTML = e.currentTarget.innerHTML; | |
| e.currentTarget.innerHTML = '<i data-feather="check" class="w-4 h-4"></i> Copied!'; | |
| feather.replace(); | |
| setTimeout(() => { | |
| e.currentTarget.innerHTML = originalHTML; | |
| feather.replace(); | |
| }, 2000); | |
| }); | |
| }); | |
| }); | |
| } | |
| // Filter prompts based on current filter | |
| function filterPrompts() { | |
| if (currentFilter === '') { | |
| filteredData = [...demoData]; | |
| } else { | |
| filteredData = demoData.filter(item => | |
| item.tags.includes(currentFilter) | |
| ); | |
| } | |
| renderPromptCards(); | |
| } | |
| // Search functionality (to be implemented with real search bar) | |
| function searchPrompts(query) { | |
| if (!query) { | |
| filteredData = currentFilter ? demoData.filter(item => item.tags.includes(currentFilter)) : [...demoData]; | |
| } else { | |
| const lowerQuery = query.toLowerCase(); | |
| filteredData = demoData.filter(item => | |
| item.prompt.toLowerCase().includes(lowerQuery) || | |
| item.tags.some(tag => tag.toLowerCase().includes(lowerQuery)) | |
| ); | |
| // If we have a tag filter, apply it as well | |
| if (currentFilter) { | |
| filteredData = filteredData.filter(item => item.tags.includes(currentFilter)); | |
| } | |
| } | |
| renderPromptCards(); | |
| } |