| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8"> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> |
| <title>Photo Gallery Manager</title> |
| <script src="https://cdn.tailwindcss.com"></script> |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> |
| <style> |
| .dropzone { |
| border: 2px dashed #cbd5e0; |
| transition: all 0.3s ease; |
| } |
| .dropzone.active { |
| border-color: #4299e1; |
| background-color: #ebf8ff; |
| } |
| .image-grid { |
| display: grid; |
| grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); |
| gap: 1rem; |
| } |
| .image-card { |
| transition: transform 0.2s ease; |
| } |
| .image-card:hover { |
| transform: scale(1.02); |
| } |
| .sidebar { |
| transition: all 0.3s ease; |
| } |
| @media (max-width: 768px) { |
| .sidebar { |
| transform: translateX(-100%); |
| } |
| .sidebar.open { |
| transform: translateX(0); |
| } |
| } |
| </style> |
| </head> |
| <body class="bg-gray-50 font-sans"> |
| |
| <div id="authModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> |
| <div class="bg-white rounded-lg p-8 w-full max-w-md"> |
| <h2 class="text-2xl font-bold mb-6 text-center">Sign In</h2> |
| <button id="azureLogin" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded flex items-center justify-center"> |
| <i class="fab fa-microsoft mr-2"></i> Sign in with Microsoft |
| </button> |
| <div class="mt-4 text-center text-sm text-gray-600"> |
| By signing in, you agree to our Terms of Service and Privacy Policy |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="flex h-screen overflow-hidden"> |
| |
| <div class="sidebar bg-white w-64 border-r border-gray-200 flex flex-col fixed h-full z-40"> |
| <div class="p-4 border-b border-gray-200"> |
| <h1 class="text-xl font-bold text-blue-600 flex items-center"> |
| <i class="fas fa-camera mr-2"></i> Photo Gallery |
| </h1> |
| </div> |
| <div class="p-4"> |
| <button id="createAlbumBtn" class="w-full bg-blue-600 hover:bg-blue-700 text-white py-2 px-4 rounded flex items-center justify-center mb-4"> |
| <i class="fas fa-plus mr-2"></i> New Album |
| </button> |
| <div class="space-y-1"> |
| <button class="w-full text-left px-3 py-2 rounded hover:bg-gray-100 flex items-center"> |
| <i class="fas fa-images mr-2 text-gray-500"></i> All Photos |
| </button> |
| <button class="w-full text-left px-3 py-2 rounded hover:bg-gray-100 flex items-center"> |
| <i class="fas fa-tags mr-2 text-gray-500"></i> Tags |
| </button> |
| <button class="w-full text-left px-3 py-2 rounded hover:bg-gray-100 flex items-center"> |
| <i class="fas fa-calendar-alt mr-2 text-gray-500"></i> Timeline |
| </button> |
| <button class="w-full text-left px-3 py-2 rounded hover:bg-gray-100 flex items-center"> |
| <i class="fas fa-share-alt mr-2 text-gray-500"></i> Shared |
| </button> |
| </div> |
| </div> |
| <div class="p-4 border-t border-gray-200 mt-auto"> |
| <div class="flex items-center"> |
| <img src="https://via.placeholder.com/40" alt="User" class="rounded-full w-8 h-8"> |
| <div class="ml-2"> |
| <div class="text-sm font-medium">John Doe</div> |
| <div class="text-xs text-gray-500">john.doe@example.com</div> |
| </div> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <button id="sidebarToggle" class="md:hidden fixed top-4 left-4 z-50 bg-white p-2 rounded shadow"> |
| <i class="fas fa-bars"></i> |
| </button> |
|
|
| |
| <div class="flex-1 flex flex-col overflow-hidden md:ml-64"> |
| |
| <header class="bg-white border-b border-gray-200 p-4"> |
| <div class="flex justify-between items-center"> |
| <h2 class="text-xl font-semibold">My Albums</h2> |
| <div class="relative"> |
| <input type="text" placeholder="Search photos..." class="border border-gray-300 rounded-full py-2 px-4 pl-10 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 w-64"> |
| <i class="fas fa-search absolute left-3 top-3 text-gray-400"></i> |
| </div> |
| </div> |
| </header> |
|
|
| |
| <main class="flex-1 overflow-y-auto p-6"> |
| |
| <div class="image-grid"> |
| |
| <div class="image-card bg-white rounded-lg overflow-hidden shadow"> |
| <div class="relative pb-[100%]"> |
| <img src="https://via.placeholder.com/300" alt="Album cover" class="absolute h-full w-full object-cover"> |
| <div class="absolute inset-0 bg-gradient-to-t from-black to-transparent opacity-50"></div> |
| <div class="absolute bottom-0 left-0 p-4 text-white"> |
| <h3 class="font-bold">Vacation 2023</h3> |
| <p class="text-sm">24 photos</p> |
| </div> |
| <div class="absolute top-2 right-2"> |
| <button class="bg-white bg-opacity-80 rounded-full p-2 hover:bg-opacity-100"> |
| <i class="fas fa-ellipsis-v text-gray-700"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="image-card bg-white rounded-lg overflow-hidden shadow"> |
| <div class="relative pb-[100%]"> |
| <img src="https://via.placeholder.com/300" alt="Album cover" class="absolute h-full w-full object-cover"> |
| <div class="absolute inset-0 bg-gradient-to-t from-black to-transparent opacity-50"></div> |
| <div class="absolute bottom-0 left-0 p-4 text-white"> |
| <h3 class="font-bold">Family Reunion</h3> |
| <p class="text-sm">56 photos</p> |
| </div> |
| <div class="absolute top-2 right-2"> |
| <button class="bg-white bg-opacity-80 rounded-full p-2 hover:bg-opacity-100"> |
| <i class="fas fa-ellipsis-v text-gray-700"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="image-card bg-white rounded-lg overflow-hidden shadow"> |
| <div class="relative pb-[100%]"> |
| <img src="https://via.placeholder.com/300" alt="Album cover" class="absolute h-full w-full object-cover"> |
| <div class="absolute inset-0 bg-gradient-to-t from-black to-transparent opacity-50"></div> |
| <div class="absolute bottom-0 left-0 p-4 text-white"> |
| <h3 class="font-bold">Work Project</h3> |
| <p class="text-sm">12 photos</p> |
| </div> |
| <div class="absolute top-2 right-2"> |
| <button class="bg-white bg-opacity-80 rounded-full p-2 hover:bg-opacity-100"> |
| <i class="fas fa-ellipsis-v text-gray-700"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div class="image-card bg-gray-100 rounded-lg overflow-hidden shadow flex items-center justify-center cursor-pointer hover:bg-gray-200 transition"> |
| <div class="p-8 text-center"> |
| <i class="fas fa-plus text-4xl text-gray-400 mb-2"></i> |
| <p class="text-gray-600">Create new album</p> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="dropzone" class="dropzone mt-8 p-12 rounded-lg text-center cursor-pointer"> |
| <i class="fas fa-cloud-upload-alt text-4xl text-gray-400 mb-4"></i> |
| <p class="text-lg font-medium text-gray-700">Drag & drop photos here</p> |
| <p class="text-gray-500">or click to browse files</p> |
| <input type="file" id="fileInput" class="hidden" multiple accept="image/*"> |
| </div> |
| </main> |
| </div> |
| </div> |
|
|
| |
| <div id="albumModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden"> |
| <div class="bg-white rounded-lg p-6 w-full max-w-4xl max-h-[90vh] overflow-y-auto"> |
| <div class="flex justify-between items-center mb-6"> |
| <h2 class="text-2xl font-bold">Album Details</h2> |
| <button id="closeAlbumModal" class="text-gray-500 hover:text-gray-700"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| |
| <div class="mb-6"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Album Name</label> |
| <input type="text" class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" value="Vacation 2023"> |
| </div> |
| |
| <div class="mb-6"> |
| <label class="block text-sm font-medium text-gray-700 mb-1">Description</label> |
| <textarea class="w-full border border-gray-300 rounded-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500" rows="3">Our summer vacation in Hawaii</textarea> |
| </div> |
| |
| <div class="mb-6"> |
| <label class="block text-sm font-medium text-gray-700 mb-2">Permissions</label> |
| <div class="flex items-center mb-2"> |
| <input type="text" placeholder="Add user by email" class="border border-gray-300 rounded-l-md px-3 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500 flex-1"> |
| <button class="bg-blue-600 text-white px-4 py-2 rounded-r-md hover:bg-blue-700"> |
| <i class="fas fa-plus"></i> Add |
| </button> |
| </div> |
| <div class="space-y-2"> |
| <div class="flex items-center justify-between bg-gray-50 p-2 rounded"> |
| <div class="flex items-center"> |
| <img src="https://via.placeholder.com/40" alt="User" class="rounded-full w-6 h-6 mr-2"> |
| <span>jane.doe@example.com</span> |
| </div> |
| <select class="border border-gray-300 rounded px-2 py-1 text-sm"> |
| <option>View</option> |
| <option>Edit</option> |
| <option>Remove</option> |
| </select> |
| </div> |
| </div> |
| </div> |
| |
| <div class="mb-6"> |
| <label class="block text-sm font-medium text-gray-700 mb-2">Tags</label> |
| <div class="flex flex-wrap gap-2"> |
| <span class="bg-blue-100 text-blue-800 text-xs px-2 py-1 rounded-full flex items-center"> |
| #beach |
| <button class="ml-1 text-blue-600 hover:text-blue-800"> |
| <i class="fas fa-times text-xs"></i> |
| </button> |
| </span> |
| <span class="bg-green-100 text-green-800 text-xs px-2 py-1 rounded-full flex items-center"> |
| #vacation |
| <button class="ml-1 text-green-600 hover:text-green-800"> |
| <i class="fas fa-times text-xs"></i> |
| </button> |
| </span> |
| <button class="text-blue-600 hover:text-blue-800 text-sm flex items-center"> |
| <i class="fas fa-plus mr-1"></i> Add tag |
| </button> |
| </div> |
| </div> |
| |
| <div class="flex justify-end space-x-3"> |
| <button class="px-4 py-2 border border-gray-300 rounded-md hover:bg-gray-50">Cancel</button> |
| <button class="px-4 py-2 bg-blue-600 text-white rounded-md hover:bg-blue-700">Save Changes</button> |
| </div> |
| </div> |
| </div> |
|
|
| |
| <div id="imageViewer" class="fixed inset-0 bg-black bg-opacity-90 flex items-center justify-center z-50 hidden"> |
| <div class="absolute top-4 right-4"> |
| <button id="closeImageViewer" class="text-white hover:text-gray-300 text-2xl"> |
| <i class="fas fa-times"></i> |
| </button> |
| </div> |
| <div class="absolute top-4 left-4 text-white"> |
| <h2 class="text-xl font-bold">Vacation 2023</h2> |
| <p class="text-sm">June 15, 2023</p> |
| </div> |
| <div class="relative w-full h-full flex items-center justify-center"> |
| <img id="viewedImage" src="https://via.placeholder.com/800" alt="Full size" class="max-w-full max-h-full object-contain"> |
| </div> |
| <div class="absolute bottom-4 left-0 right-0 flex justify-center"> |
| <div class="bg-black bg-opacity-50 rounded-full px-4 py-2 flex items-center space-x-4"> |
| <button class="text-white hover:text-gray-300"> |
| <i class="fas fa-chevron-left"></i> |
| </button> |
| <div class="flex space-x-2"> |
| <button class="text-white hover:text-gray-300"> |
| <i class="fas fa-download"></i> |
| </button> |
| <button class="text-white hover:text-gray-300"> |
| <i class="fas fa-share-alt"></i> |
| </button> |
| <button class="text-white hover:text-gray-300"> |
| <i class="fas fa-tag"></i> |
| </button> |
| <button class="text-white hover:text-gray-300"> |
| <i class="fas fa-trash"></i> |
| </button> |
| </div> |
| <button class="text-white hover:text-gray-300"> |
| <i class="fas fa-chevron-right"></i> |
| </button> |
| </div> |
| </div> |
| </div> |
|
|
| <script> |
| |
| const authModal = document.getElementById('authModal'); |
| const azureLogin = document.getElementById('azureLogin'); |
| const sidebar = document.querySelector('.sidebar'); |
| const sidebarToggle = document.getElementById('sidebarToggle'); |
| const createAlbumBtn = document.getElementById('createAlbumBtn'); |
| const albumModal = document.getElementById('albumModal'); |
| const closeAlbumModal = document.getElementById('closeAlbumModal'); |
| const dropzone = document.getElementById('dropzone'); |
| const fileInput = document.getElementById('fileInput'); |
| const imageViewer = document.getElementById('imageViewer'); |
| const closeImageViewer = document.getElementById('closeImageViewer'); |
| const viewedImage = document.getElementById('viewedImage'); |
| |
| |
| window.addEventListener('DOMContentLoaded', () => { |
| authModal.classList.remove('hidden'); |
| }); |
| |
| |
| azureLogin.addEventListener('click', () => { |
| |
| console.log('Redirecting to Azure AD login...'); |
| |
| setTimeout(() => { |
| authModal.classList.add('hidden'); |
| }, 1000); |
| }); |
| |
| |
| sidebarToggle.addEventListener('click', () => { |
| sidebar.classList.toggle('open'); |
| }); |
| |
| |
| createAlbumBtn.addEventListener('click', () => { |
| albumModal.classList.remove('hidden'); |
| }); |
| |
| closeAlbumModal.addEventListener('click', () => { |
| albumModal.classList.add('hidden'); |
| }); |
| |
| |
| ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { |
| dropzone.addEventListener(eventName, preventDefaults, false); |
| }); |
| |
| function preventDefaults(e) { |
| e.preventDefault(); |
| e.stopPropagation(); |
| } |
| |
| ['dragenter', 'dragover'].forEach(eventName => { |
| dropzone.addEventListener(eventName, highlight, false); |
| }); |
| |
| ['dragleave', 'drop'].forEach(eventName => { |
| dropzone.addEventListener(eventName, unhighlight, false); |
| }); |
| |
| function highlight() { |
| dropzone.classList.add('active'); |
| } |
| |
| function unhighlight() { |
| dropzone.classList.remove('active'); |
| } |
| |
| dropzone.addEventListener('drop', handleDrop, false); |
| dropzone.addEventListener('click', () => fileInput.click()); |
| |
| fileInput.addEventListener('change', handleFiles); |
| |
| function handleDrop(e) { |
| const dt = e.dataTransfer; |
| const files = dt.files; |
| handleFiles({ target: { files } }); |
| } |
| |
| function handleFiles(e) { |
| const files = e.target.files; |
| console.log('Files to upload:', files); |
| |
| alert(`${files.length} files selected for upload`); |
| } |
| |
| |
| document.querySelectorAll('.image-card img').forEach(img => { |
| img.addEventListener('click', () => { |
| viewedImage.src = img.src; |
| imageViewer.classList.remove('hidden'); |
| }); |
| }); |
| |
| closeImageViewer.addEventListener('click', () => { |
| imageViewer.classList.add('hidden'); |
| }); |
| </script> |
| <p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=tungdoan/deepsite" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body> |
| </html> |