akbit commited on
Commit
5897dc4
·
verified ·
1 Parent(s): dd16ae3

Add 2 files

Browse files
Files changed (2) hide show
  1. README.md +7 -5
  2. index.html +574 -19
README.md CHANGED
@@ -1,10 +1,12 @@
1
  ---
2
- title: Lumemgallery
3
- emoji: 🌖
4
- colorFrom: purple
5
- colorTo: blue
6
  sdk: static
7
  pinned: false
 
 
8
  ---
9
 
10
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
  ---
2
+ title: lumemgallery
3
+ emoji: 🐳
4
+ colorFrom: red
5
+ colorTo: yellow
6
  sdk: static
7
  pinned: false
8
+ tags:
9
+ - deepsite
10
  ---
11
 
12
+ Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
index.html CHANGED
@@ -1,19 +1,574 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Lumen Gallery | Premium Photo Experience</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <script>
10
+ tailwind.config = {
11
+ darkMode: 'class',
12
+ theme: {
13
+ extend: {
14
+ colors: {
15
+ primary: {
16
+ 50: '#f0f9ff',
17
+ 100: '#e0f2fe',
18
+ 200: '#bae6fd',
19
+ 300: '#7dd3fc',
20
+ 400: '#38bdf8',
21
+ 500: '#0ea5e9',
22
+ 600: '#0284c7',
23
+ 700: '#0369a1',
24
+ 800: '#075985',
25
+ 900: '#0c4a6e',
26
+ }
27
+ },
28
+ animation: {
29
+ 'fade-in': 'fadeIn 0.3s ease-in-out',
30
+ 'flip-in': 'flipIn 0.5s ease-out',
31
+ 'zoom-in': 'zoomIn 0.3s ease-out',
32
+ },
33
+ keyframes: {
34
+ fadeIn: {
35
+ '0%': { opacity: '0' },
36
+ '100%': { opacity: '1' },
37
+ },
38
+ flipIn: {
39
+ '0%': { transform: 'rotateY(90deg)', opacity: '0' },
40
+ '100%': { transform: 'rotateY(0)', opacity: '1' },
41
+ },
42
+ zoomIn: {
43
+ '0%': { transform: 'scale(0.95)', opacity: '0' },
44
+ '100%': { transform: 'scale(1)', opacity: '1' },
45
+ }
46
+ }
47
+ }
48
+ }
49
+ }
50
+ </script>
51
+ <style>
52
+ .album-thumbnail {
53
+ transition: all 0.3s ease;
54
+ transform-style: preserve-3d;
55
+ }
56
+ .album-thumbnail:hover {
57
+ transform: translateY(-5px) scale(1.02);
58
+ box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.1), 0 10px 10px -5px rgba(0, 0, 0, 0.04);
59
+ }
60
+ .flipbook {
61
+ perspective: 2000px;
62
+ }
63
+ .flipbook-page {
64
+ transform-style: preserve-3d;
65
+ backface-visibility: hidden;
66
+ transition: transform 0.8s;
67
+ }
68
+ .flipbook-page.flipped {
69
+ transform: rotateY(-180deg);
70
+ }
71
+ .flipbook-page-inner {
72
+ position: absolute;
73
+ width: 100%;
74
+ height: 100%;
75
+ backface-visibility: hidden;
76
+ }
77
+ .flipbook-page-back {
78
+ transform: rotateY(180deg);
79
+ }
80
+ .modal-overlay {
81
+ background-color: rgba(0, 0, 0, 0.85);
82
+ backdrop-filter: blur(8px);
83
+ }
84
+ .image-zoom {
85
+ transition: transform 0.3s ease;
86
+ }
87
+ .image-zoom:hover {
88
+ transform: scale(1.03);
89
+ }
90
+ .login-card {
91
+ box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
92
+ }
93
+ .private-badge {
94
+ position: absolute;
95
+ top: 10px;
96
+ right: 10px;
97
+ z-index: 10;
98
+ }
99
+ </style>
100
+ </head>
101
+ <body class="bg-gray-50 dark:bg-gray-900 text-gray-800 dark:text-gray-200 min-h-screen transition-colors duration-300">
102
+ <!-- Navigation -->
103
+ <nav class="bg-white dark:bg-gray-800 shadow-sm py-4 px-6 sticky top-0 z-50">
104
+ <div class="max-w-7xl mx-auto flex justify-between items-center">
105
+ <div class="flex items-center space-x-2">
106
+ <i class="fas fa-camera-retro text-2xl text-primary-600 dark:text-primary-400"></i>
107
+ <span class="text-xl font-bold text-primary-600 dark:text-primary-400">Lumen Gallery</span>
108
+ </div>
109
+ <div class="flex items-center space-x-6">
110
+ <a href="#" class="hover:text-primary-600 dark:hover:text-primary-400 transition-colors">Home</a>
111
+ <a href="#" class="hover:text-primary-600 dark:hover:text-primary-400 transition-colors">Public Albums</a>
112
+ <a href="#" id="login-link" class="hover:text-primary-600 dark:hover:text-primary-400 transition-colors">Login</a>
113
+ <button id="theme-toggle" class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">
114
+ <i class="fas fa-moon dark:hidden"></i>
115
+ <i class="fas fa-sun hidden dark:block"></i>
116
+ </button>
117
+ </div>
118
+ </div>
119
+ </nav>
120
+
121
+ <!-- Main Content -->
122
+ <main class="max-w-7xl mx-auto py-8 px-4 sm:px-6 lg:px-8">
123
+ <div class="text-center mb-12">
124
+ <h1 class="text-4xl font-bold mb-4">Your Visual Journey</h1>
125
+ <p class="text-lg text-gray-600 dark:text-gray-400 max-w-2xl mx-auto">
126
+ Explore stunning collections of photography in our premium gallery experience.
127
+ </p>
128
+ </div>
129
+
130
+ <!-- Album Grid -->
131
+ <div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-8" id="album-grid">
132
+ <!-- Albums will be dynamically inserted here -->
133
+ </div>
134
+ </main>
135
+
136
+ <!-- Login Modal -->
137
+ <div id="login-modal" class="fixed inset-0 z-50 flex items-center justify-center hidden">
138
+ <div class="modal-overlay absolute inset-0"></div>
139
+ <div class="login-card bg-white dark:bg-gray-800 rounded-xl p-8 relative z-10 w-full max-w-md animate-zoom-in">
140
+ <div class="text-center mb-8">
141
+ <h2 class="text-2xl font-bold mb-2">Welcome Back</h2>
142
+ <p class="text-gray-600 dark:text-gray-400">Sign in to access private albums</p>
143
+ </div>
144
+ <form id="login-form" class="space-y-6">
145
+ <div>
146
+ <label for="username" class="block text-sm font-medium mb-1">Username</label>
147
+ <input type="text" id="username" class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 focus:ring-2 focus:ring-primary-500 focus:border-primary-500 transition">
148
+ </div>
149
+ <div>
150
+ <label for="password" class="block text-sm font-medium mb-1">Password</label>
151
+ <input type="password" id="password" class="w-full px-4 py-2 rounded-lg border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-700 focus:ring-2 focus:ring-primary-500 focus:border-primary-500 transition">
152
+ </div>
153
+ <div class="flex items-center justify-between">
154
+ <div class="flex items-center">
155
+ <input type="checkbox" id="remember" class="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded">
156
+ <label for="remember" class="ml-2 block text-sm">Remember me</label>
157
+ </div>
158
+ <a href="#" class="text-sm text-primary-600 dark:text-primary-400 hover:underline">Forgot password?</a>
159
+ </div>
160
+ <button type="submit" class="w-full bg-primary-600 hover:bg-primary-700 text-white py-2 px-4 rounded-lg transition-colors duration-300">
161
+ Sign In
162
+ </button>
163
+ </form>
164
+ <button id="close-login" class="absolute top-4 right-4 p-2 text-gray-500 hover:text-gray-700 dark:hover:text-gray-300">
165
+ <i class="fas fa-times"></i>
166
+ </button>
167
+ </div>
168
+ </div>
169
+
170
+ <!-- Flipbook Viewer -->
171
+ <div id="flipbook-viewer" class="fixed inset-0 z-50 flex items-center justify-center hidden">
172
+ <div class="modal-overlay absolute inset-0"></div>
173
+ <div class="relative z-10 w-full max-w-6xl mx-4">
174
+ <button id="close-flipbook" class="absolute -top-12 right-0 p-2 text-white hover:text-primary-400 transition-colors">
175
+ <i class="fas fa-times text-2xl"></i>
176
+ </button>
177
+ <div class="flipbook bg-white dark:bg-gray-800 rounded-xl overflow-hidden shadow-2xl">
178
+ <div class="relative h-96 md:h-[32rem]">
179
+ <!-- Flipbook pages will be dynamically inserted here -->
180
+ </div>
181
+ <div class="flex justify-between items-center p-4 bg-gray-100 dark:bg-gray-700">
182
+ <button id="prev-page" class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors disabled:opacity-50 disabled:cursor-not-allowed">
183
+ <i class="fas fa-chevron-left text-xl"></i>
184
+ </button>
185
+ <span id="page-indicator" class="text-sm font-medium">Page 1 of 3</span>
186
+ <button id="next-page" class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-600 transition-colors">
187
+ <i class="fas fa-chevron-right text-xl"></i>
188
+ </button>
189
+ </div>
190
+ </div>
191
+ </div>
192
+ </div>
193
+
194
+ <!-- Image Modal -->
195
+ <div id="image-modal" class="fixed inset-0 z-50 flex items-center justify-center hidden">
196
+ <div class="modal-overlay absolute inset-0"></div>
197
+ <div class="relative z-10 w-full max-w-6xl mx-4">
198
+ <div class="flex justify-between items-center mb-4">
199
+ <div class="flex space-x-2">
200
+ <button id="zoom-out" class="p-2 rounded-full bg-gray-800 bg-opacity-50 text-white hover:bg-opacity-70 transition-colors">
201
+ <i class="fas fa-search-minus"></i>
202
+ </button>
203
+ <button id="download-image" class="p-2 rounded-full bg-gray-800 bg-opacity-50 text-white hover:bg-opacity-70 transition-colors">
204
+ <i class="fas fa-download"></i>
205
+ </button>
206
+ </div>
207
+ <button id="close-image" class="p-2 rounded-full bg-gray-800 bg-opacity-50 text-white hover:bg-opacity-70 transition-colors">
208
+ <i class="fas fa-times"></i>
209
+ </button>
210
+ </div>
211
+ <div class="bg-white dark:bg-gray-800 rounded-xl overflow-hidden shadow-2xl max-h-[90vh] flex items-center justify-center">
212
+ <img id="modal-image" src="" alt="" class="max-w-full max-h-[85vh] object-contain">
213
+ </div>
214
+ </div>
215
+ </div>
216
+
217
+ <!-- Upload Button (for admin) -->
218
+ <div id="upload-section" class="fixed bottom-8 right-8 hidden">
219
+ <button id="upload-btn" class="p-4 bg-primary-600 hover:bg-primary-700 text-white rounded-full shadow-lg transition-colors duration-300">
220
+ <i class="fas fa-plus text-xl"></i>
221
+ </button>
222
+ </div>
223
+
224
+ <script>
225
+ // Sample album data
226
+ const albums = [
227
+ {
228
+ id: 1,
229
+ title: "Mountain Escapes",
230
+ thumbnail: "https://source.unsplash.com/random/600x400/?mountain",
231
+ photoCount: 12,
232
+ isPublic: true,
233
+ photos: [
234
+ "https://source.unsplash.com/random/800x600/?mountain,1",
235
+ "https://source.unsplash.com/random/800x600/?mountain,2",
236
+ "https://source.unsplash.com/random/800x600/?mountain,3",
237
+ "https://source.unsplash.com/random/800x600/?mountain,4",
238
+ "https://source.unsplash.com/random/800x600/?mountain,5",
239
+ "https://source.unsplash.com/random/800x600/?mountain,6"
240
+ ]
241
+ },
242
+ {
243
+ id: 2,
244
+ title: "Urban Landscapes",
245
+ thumbnail: "https://source.unsplash.com/random/600x400/?city",
246
+ photoCount: 8,
247
+ isPublic: true,
248
+ photos: [
249
+ "https://source.unsplash.com/random/800x600/?city,1",
250
+ "https://source.unsplash.com/random/800x600/?city,2",
251
+ "https://source.unsplash.com/random/800x600/?city,3",
252
+ "https://source.unsplash.com/random/800x600/?city,4"
253
+ ]
254
+ },
255
+ {
256
+ id: 3,
257
+ title: "Ocean Wonders",
258
+ thumbnail: "https://source.unsplash.com/random/600x400/?ocean",
259
+ photoCount: 15,
260
+ isPublic: true,
261
+ photos: [
262
+ "https://source.unsplash.com/random/800x600/?ocean,1",
263
+ "https://source.unsplash.com/random/800x600/?ocean,2",
264
+ "https://source.unsplash.com/random/800x600/?ocean,3",
265
+ "https://source.unsplash.com/random/800x600/?ocean,4",
266
+ "https://source.unsplash.com/random/800x600/?ocean,5",
267
+ "https://source.unsplash.com/random/800x600/?ocean,6",
268
+ "https://source.unsplash.com/random/800x600/?ocean,7"
269
+ ]
270
+ },
271
+ {
272
+ id: 4,
273
+ title: "Family Memories",
274
+ thumbnail: "https://source.unsplash.com/random/600x400/?family",
275
+ photoCount: 20,
276
+ isPublic: false,
277
+ photos: [
278
+ "https://source.unsplash.com/random/800x600/?family,1",
279
+ "https://source.unsplash.com/random/800x600/?family,2",
280
+ "https://source.unsplash.com/random/800x600/?family,3",
281
+ "https://source.unsplash.com/random/800x600/?family,4",
282
+ "https://source.unsplash.com/random/800x600/?family,5",
283
+ "https://source.unsplash.com/random/800x600/?family,6",
284
+ "https://source.unsplash.com/random/800x600/?family,7",
285
+ "https://source.unsplash.com/random/800x600/?family,8",
286
+ "https://source.unsplash.com/random/800x600/?family,9",
287
+ "https://source.unsplash.com/random/800x600/?family,10"
288
+ ]
289
+ },
290
+ {
291
+ id: 5,
292
+ title: "Wildlife Adventures",
293
+ thumbnail: "https://source.unsplash.com/random/600x400/?wildlife",
294
+ photoCount: 18,
295
+ isPublic: true,
296
+ photos: [
297
+ "https://source.unsplash.com/random/800x600/?wildlife,1",
298
+ "https://source.unsplash.com/random/800x600/?wildlife,2",
299
+ "https://source.unsplash.com/random/800x600/?wildlife,3",
300
+ "https://source.unsplash.com/random/800x600/?wildlife,4",
301
+ "https://source.unsplash.com/random/800x600/?wildlife,5",
302
+ "https://source.unsplash.com/random/800x600/?wildlife,6",
303
+ "https://source.unsplash.com/random/800x600/?wildlife,7",
304
+ "https://source.unsplash.com/random/800x600/?wildlife,8",
305
+ "https://source.unsplash.com/random/800x600/?wildlife,9"
306
+ ]
307
+ },
308
+ {
309
+ id: 6,
310
+ title: "Architectural Marvels",
311
+ thumbnail: "https://source.unsplash.com/random/600x400/?architecture",
312
+ photoCount: 14,
313
+ isPublic: true,
314
+ photos: [
315
+ "https://source.unsplash.com/random/800x600/?architecture,1",
316
+ "https://source.unsplash.com/random/800x600/?architecture,2",
317
+ "https://source.unsplash.com/random/800x600/?architecture,3",
318
+ "https://source.unsplash.com/random/800x600/?architecture,4",
319
+ "https://source.unsplash.com/random/800x600/?architecture,5",
320
+ "https://source.unsplash.com/random/800x600/?architecture,6",
321
+ "https://source.unsplash.com/random/800x600/?architecture,7"
322
+ ]
323
+ }
324
+ ];
325
+
326
+ // State variables
327
+ let currentUser = null;
328
+ let currentAlbum = null;
329
+ let currentPage = 0;
330
+ let totalPages = 0;
331
+ let isLoggedIn = false;
332
+
333
+ // DOM elements
334
+ const albumGrid = document.getElementById('album-grid');
335
+ const loginModal = document.getElementById('login-modal');
336
+ const loginLink = document.getElementById('login-link');
337
+ const closeLogin = document.getElementById('close-login');
338
+ const loginForm = document.getElementById('login-form');
339
+ const flipbookViewer = document.getElementById('flipbook-viewer');
340
+ const closeFlipbook = document.getElementById('close-flipbook');
341
+ const prevPageBtn = document.getElementById('prev-page');
342
+ const nextPageBtn = document.getElementById('next-page');
343
+ const pageIndicator = document.getElementById('page-indicator');
344
+ const imageModal = document.getElementById('image-modal');
345
+ const modalImage = document.getElementById('modal-image');
346
+ const closeImage = document.getElementById('close-image');
347
+ const zoomOutBtn = document.getElementById('zoom-out');
348
+ const downloadImageBtn = document.getElementById('download-image');
349
+ const themeToggle = document.getElementById('theme-toggle');
350
+ const uploadSection = document.getElementById('upload-section');
351
+ const uploadBtn = document.getElementById('upload-btn');
352
+
353
+ // Initialize the gallery
354
+ function initGallery() {
355
+ renderAlbums();
356
+ setupEventListeners();
357
+ checkDarkModePreference();
358
+ }
359
+
360
+ // Render albums to the grid
361
+ function renderAlbums() {
362
+ albumGrid.innerHTML = '';
363
+
364
+ const filteredAlbums = albums.filter(album => {
365
+ return album.isPublic || isLoggedIn;
366
+ });
367
+
368
+ filteredAlbums.forEach(album => {
369
+ const albumElement = document.createElement('div');
370
+ albumElement.className = 'album-thumbnail bg-white dark:bg-gray-800 rounded-xl overflow-hidden shadow-lg cursor-pointer relative';
371
+ albumElement.innerHTML = `
372
+ <div class="relative h-48 overflow-hidden">
373
+ <img src="${album.thumbnail}" alt="${album.title}" class="w-full h-full object-cover transition-transform duration-300 hover:scale-105">
374
+ ${!album.isPublic ? '<span class="private-badge bg-primary-600 text-white text-xs px-2 py-1 rounded-full">Private</span>' : ''}
375
+ </div>
376
+ <div class="p-4">
377
+ <h3 class="font-semibold text-lg mb-1">${album.title}</h3>
378
+ <p class="text-sm text-gray-600 dark:text-gray-400">${album.photoCount} photos</p>
379
+ </div>
380
+ `;
381
+ albumElement.addEventListener('click', () => openAlbum(album));
382
+ albumGrid.appendChild(albumElement);
383
+ });
384
+ }
385
+
386
+ // Open an album in the flipbook viewer
387
+ function openAlbum(album) {
388
+ if (!album.isPublic && !isLoggedIn) {
389
+ openLoginModal();
390
+ return;
391
+ }
392
+
393
+ currentAlbum = album;
394
+ currentPage = 0;
395
+ totalPages = Math.ceil(album.photos.length / 2);
396
+
397
+ renderFlipbook();
398
+ flipbookViewer.classList.remove('hidden');
399
+ document.body.style.overflow = 'hidden';
400
+ }
401
+
402
+ // Render the flipbook pages
403
+ function renderFlipbook() {
404
+ const flipbookContainer = flipbookViewer.querySelector('.flipbook > div');
405
+ flipbookContainer.innerHTML = '';
406
+
407
+ // Create pages with 2 photos each
408
+ for (let i = 0; i < currentAlbum.photos.length; i += 2) {
409
+ const page = document.createElement('div');
410
+ page.className = 'flipbook-page absolute inset-0 w-full h-full';
411
+ page.style.transform = i === 0 ? 'rotateY(0)' : 'rotateY(180deg)';
412
+ page.style.display = i === 0 ? 'block' : 'none';
413
+
414
+ const front = document.createElement('div');
415
+ front.className = 'flipbook-page-inner flex';
416
+
417
+ const photo1 = document.createElement('div');
418
+ photo1.className = 'w-1/2 p-4 flex items-center justify-center';
419
+ photo1.innerHTML = `<img src="${currentAlbum.photos[i]}" alt="Photo ${i+1}" class="max-h-full max-w-full rounded-lg shadow-md cursor-pointer image-zoom">`;
420
+ photo1.querySelector('img').addEventListener('click', () => openImageModal(currentAlbum.photos[i]));
421
+
422
+ const photo2 = document.createElement('div');
423
+ photo2.className = 'w-1/2 p-4 flex items-center justify-center';
424
+
425
+ if (i + 1 < currentAlbum.photos.length) {
426
+ photo2.innerHTML = `<img src="${currentAlbum.photos[i+1]}" alt="Photo ${i+2}" class="max-h-full max-w-full rounded-lg shadow-md cursor-pointer image-zoom">`;
427
+ photo2.querySelector('img').addEventListener('click', () => openImageModal(currentAlbum.photos[i+1]));
428
+ } else {
429
+ photo2.innerHTML = '<div class="w-full h-full flex items-center justify-center bg-gray-100 dark:bg-gray-700 rounded-lg"><p class="text-gray-500 dark:text-gray-400">No photo</p></div>';
430
+ }
431
+
432
+ front.appendChild(photo1);
433
+ front.appendChild(photo2);
434
+ page.appendChild(front);
435
+
436
+ // For a real flipbook effect, we'd have back sides too, but we'll keep it simple
437
+ flipbookContainer.appendChild(page);
438
+ }
439
+
440
+ updatePageControls();
441
+ }
442
+
443
+ // Update flipbook page controls
444
+ function updatePageControls() {
445
+ pageIndicator.textContent = `Page ${currentPage + 1} of ${totalPages}`;
446
+ prevPageBtn.disabled = currentPage === 0;
447
+ nextPageBtn.disabled = currentPage === totalPages - 1;
448
+
449
+ // Show/hide pages
450
+ const pages = flipbookViewer.querySelectorAll('.flipbook-page');
451
+ pages.forEach((page, index) => {
452
+ page.style.display = index === currentPage ? 'block' : 'none';
453
+ });
454
+ }
455
+
456
+ // Open image modal
457
+ function openImageModal(imageUrl) {
458
+ modalImage.src = imageUrl;
459
+ modalImage.alt = "Enlarged photo";
460
+ imageModal.classList.remove('hidden');
461
+ document.body.style.overflow = 'hidden';
462
+ }
463
+
464
+ // Open login modal
465
+ function openLoginModal() {
466
+ loginModal.classList.remove('hidden');
467
+ document.body.style.overflow = 'hidden';
468
+ }
469
+
470
+ // Close login modal
471
+ function closeLoginModal() {
472
+ loginModal.classList.add('hidden');
473
+ document.body.style.overflow = '';
474
+ }
475
+
476
+ // Close flipbook viewer
477
+ function closeFlipbookViewer() {
478
+ flipbookViewer.classList.add('hidden');
479
+ document.body.style.overflow = '';
480
+ }
481
+
482
+ // Close image modal
483
+ function closeImageModal() {
484
+ imageModal.classList.add('hidden');
485
+ document.body.style.overflow = '';
486
+ }
487
+
488
+ // Setup event listeners
489
+ function setupEventListeners() {
490
+ // Login link
491
+ loginLink.addEventListener('click', (e) => {
492
+ e.preventDefault();
493
+ openLoginModal();
494
+ });
495
+
496
+ // Close login modal
497
+ closeLogin.addEventListener('click', closeLoginModal);
498
+
499
+ // Login form submission
500
+ loginForm.addEventListener('submit', (e) => {
501
+ e.preventDefault();
502
+ const username = document.getElementById('username').value;
503
+ const password = document.getElementById('password').value;
504
+
505
+ // Simple authentication (in a real app, this would be a server call)
506
+ if (username === 'admin' && password === 'password') {
507
+ isLoggedIn = true;
508
+ currentUser = { username: 'admin' };
509
+ closeLoginModal();
510
+ renderAlbums();
511
+ uploadSection.classList.remove('hidden');
512
+ } else {
513
+ alert('Invalid credentials. Try admin/password');
514
+ }
515
+ });
516
+
517
+ // Close flipbook
518
+ closeFlipbook.addEventListener('click', closeFlipbookViewer);
519
+
520
+ // Flipbook navigation
521
+ prevPageBtn.addEventListener('click', () => {
522
+ if (currentPage > 0) {
523
+ currentPage--;
524
+ updatePageControls();
525
+ }
526
+ });
527
+
528
+ nextPageBtn.addEventListener('click', () => {
529
+ if (currentPage < totalPages - 1) {
530
+ currentPage++;
531
+ updatePageControls();
532
+ }
533
+ });
534
+
535
+ // Close image modal
536
+ closeImage.addEventListener('click', closeImageModal);
537
+
538
+ // Zoom out button (placeholder functionality)
539
+ zoomOutBtn.addEventListener('click', () => {
540
+ modalImage.style.transform = 'scale(1)';
541
+ });
542
+
543
+ // Download button (placeholder functionality)
544
+ downloadImageBtn.addEventListener('click', () => {
545
+ alert('Download functionality would be implemented here');
546
+ });
547
+
548
+ // Theme toggle
549
+ themeToggle.addEventListener('click', () => {
550
+ document.documentElement.classList.toggle('dark');
551
+ localStorage.setItem('darkMode', document.documentElement.classList.contains('dark'));
552
+ });
553
+
554
+ // Upload button (placeholder functionality)
555
+ uploadBtn.addEventListener('click', () => {
556
+ alert('Upload functionality would be implemented here');
557
+ });
558
+ }
559
+
560
+ // Check user's dark mode preference
561
+ function checkDarkModePreference() {
562
+ if (localStorage.getItem('darkMode') === 'true' ||
563
+ (!localStorage.getItem('darkMode') && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
564
+ document.documentElement.classList.add('dark');
565
+ } else {
566
+ document.documentElement.classList.remove('dark');
567
+ }
568
+ }
569
+
570
+ // Initialize the gallery when the DOM is loaded
571
+ document.addEventListener('DOMContentLoaded', initGallery);
572
+ </script>
573
+ <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=akbit/lumemgallery" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
574
+ </html>