Docfile commited on
Commit
1a8ed7d
·
verified ·
1 Parent(s): a3e5c23

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +76 -12
templates/index.html CHANGED
@@ -5,6 +5,7 @@
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Générateur de Manga BD</title>
7
  <style>
 
8
  * {
9
  margin: 0;
10
  padding: 0;
@@ -217,6 +218,31 @@
217
  border: 2px solid #68d391;
218
  }
219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  @media (max-width: 768px) {
221
  .main-content {
222
  grid-template-columns: 1fr;
@@ -241,6 +267,7 @@
241
  </div>
242
 
243
  <div class="main-content">
 
244
  <div class="input-section">
245
  <h2>📝 Configuration du Manga</h2>
246
  <textarea
@@ -257,7 +284,6 @@
257
  🚀 Générer le Manga
258
  </button>
259
  </div>
260
-
261
  <div class="status-section">
262
  <h2>📊 Statut de Génération</h2>
263
  <div id="statusContainer">
@@ -268,7 +294,16 @@
268
  </div>
269
  </div>
270
  </div>
 
 
 
 
 
 
 
 
271
 
 
272
  <div class="example-section">
273
  <h2>📋 Format JSON Attendu</h2>
274
  <p style="margin-bottom: 20px;">
@@ -289,21 +324,29 @@
289
  </div>
290
 
291
  <script>
 
292
  let currentTaskId = null;
293
  let statusInterval = null;
294
 
295
  const generateBtn = document.getElementById('generateBtn');
296
  const jsonInput = document.getElementById('jsonInput');
297
  const statusContainer = document.getElementById('statusContainer');
 
 
298
 
299
  generateBtn.addEventListener('click', async () => {
300
- const jsonText = jsonInput.value.trim();
301
 
 
 
 
 
 
302
  if (!jsonText) {
303
  showAlert('Veuillez saisir une configuration JSON', 'error');
304
  return;
305
  }
306
-
307
  let jsonData;
308
  try {
309
  jsonData = JSON.parse(jsonText);
@@ -348,6 +391,7 @@
348
  }
349
  });
350
 
 
351
  function startStatusPolling() {
352
  if (statusInterval) {
353
  clearInterval(statusInterval);
@@ -378,6 +422,7 @@
378
  }, 2000); // Vérifier toutes les 2 secondes
379
  }
380
 
 
381
  function updateStatusDisplay(status) {
382
  const container = statusContainer;
383
 
@@ -396,10 +441,10 @@
396
  statusIcon = '🎨';
397
  statusText = 'Génération en cours';
398
  break;
399
- case 'creating_pdf':
400
  statusClass = 'generating';
401
- statusIcon = '📄';
402
- statusText = 'Création du PDF';
403
  break;
404
  case 'completed':
405
  statusClass = 'completed';
@@ -413,6 +458,7 @@
413
  break;
414
  }
415
 
 
416
  let progressHtml = '';
417
  if (status.total_pages && status.current_page) {
418
  const progress = (status.current_page / status.total_pages) * 100;
@@ -431,16 +477,18 @@
431
  if (status.status === 'completed') {
432
  downloadHtml = `
433
  <a href="/download/${currentTaskId}" class="download-btn" style="width: 100%; text-align: center; margin-top: 15px;">
434
- 📥 Télécharger le PDF
435
  </a>
436
  `;
437
  }
438
 
 
439
  let errorHtml = '';
440
  if (status.error) {
441
  errorHtml = `<div class="alert alert-error">${status.error}</div>`;
442
  }
443
-
 
444
  container.innerHTML = `
445
  <div class="status-card ${statusClass}">
446
  <h3>${statusIcon} ${statusText}</h3>
@@ -452,15 +500,33 @@
452
  ${downloadHtml}
453
  </div>
454
  `;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
  }
456
 
 
457
  function showAlert(message, type) {
458
  const alertClass = type === 'error' ? 'alert-error' : 'alert-success';
459
  const alertHtml = `<div class="alert ${alertClass}">${message}</div>`;
460
 
461
  statusContainer.innerHTML = alertHtml + statusContainer.innerHTML;
462
 
463
- // Retirer l'alerte après 5 secondes
464
  setTimeout(() => {
465
  const alert = statusContainer.querySelector('.alert');
466
  if (alert) {
@@ -469,20 +535,18 @@
469
  }, 5000);
470
  }
471
 
472
- // Nettoyer l'intervalle quand la page est fermée
473
  window.addEventListener('beforeunload', () => {
474
  if (statusInterval) {
475
  clearInterval(statusInterval);
476
  }
477
  });
478
 
479
- // Auto-formatter le JSON
480
  jsonInput.addEventListener('blur', () => {
481
  try {
482
  const parsed = JSON.parse(jsonInput.value);
483
  jsonInput.value = JSON.stringify(parsed, null, 2);
484
  } catch (error) {
485
- // Ignorer les erreurs de parsing
486
  }
487
  });
488
  </script>
 
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Générateur de Manga BD</title>
7
  <style>
8
+ /* ... (TOUT VOTRE CSS RESTE IDENTIQUE) ... */
9
  * {
10
  margin: 0;
11
  padding: 0;
 
218
  border: 2px solid #68d391;
219
  }
220
 
221
+ /* NOUVEAUX STYLES POUR LA GRILLE D'IMAGES */
222
+ .preview-section {
223
+ background: rgba(255, 255, 255, 0.95);
224
+ padding: 30px;
225
+ border-radius: 15px;
226
+ box-shadow: 0 10px 30px rgba(0,0,0,0.2);
227
+ margin-top: 30px;
228
+ display: none; /* Caché par défaut */
229
+ }
230
+
231
+ .image-grid {
232
+ display: grid;
233
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
234
+ gap: 20px;
235
+ }
236
+
237
+ .image-grid img {
238
+ width: 100%;
239
+ height: auto;
240
+ border-radius: 10px;
241
+ box-shadow: 0 5px 15px rgba(0,0,0,0.1);
242
+ object-fit: cover;
243
+ aspect-ratio: 2 / 3; /* Ratio commun pour les pages de manga */
244
+ }
245
+
246
  @media (max-width: 768px) {
247
  .main-content {
248
  grid-template-columns: 1fr;
 
267
  </div>
268
 
269
  <div class="main-content">
270
+ <!-- ... (La section input reste la même) ... -->
271
  <div class="input-section">
272
  <h2>📝 Configuration du Manga</h2>
273
  <textarea
 
284
  🚀 Générer le Manga
285
  </button>
286
  </div>
 
287
  <div class="status-section">
288
  <h2>📊 Statut de Génération</h2>
289
  <div id="statusContainer">
 
294
  </div>
295
  </div>
296
  </div>
297
+
298
+ <!-- NOUVELLE SECTION POUR L'AFFICHAGE DES IMAGES -->
299
+ <div id="previewSection" class="preview-section">
300
+ <h2>🖼️ Prévisualisation des Pages</h2>
301
+ <div id="imageGrid" class="image-grid">
302
+ <!-- Les images générées apparaîtront ici -->
303
+ </div>
304
+ </div>
305
 
306
+ <!-- ... (La section exemple reste la même) ... -->
307
  <div class="example-section">
308
  <h2>📋 Format JSON Attendu</h2>
309
  <p style="margin-bottom: 20px;">
 
324
  </div>
325
 
326
  <script>
327
+ // ... (Les variables globales restent les mêmes) ...
328
  let currentTaskId = null;
329
  let statusInterval = null;
330
 
331
  const generateBtn = document.getElementById('generateBtn');
332
  const jsonInput = document.getElementById('jsonInput');
333
  const statusContainer = document.getElementById('statusContainer');
334
+ const previewSection = document.getElementById('previewSection');
335
+ const imageGrid = document.getElementById('imageGrid');
336
 
337
  generateBtn.addEventListener('click', async () => {
338
+ // ... (Cette fonction reste quasi identique, on ajoute juste un reset de l'affichage)
339
 
340
+ // Reset de l'interface
341
+ imageGrid.innerHTML = '';
342
+ previewSection.style.display = 'none';
343
+
344
+ const jsonText = jsonInput.value.trim();
345
  if (!jsonText) {
346
  showAlert('Veuillez saisir une configuration JSON', 'error');
347
  return;
348
  }
349
+ // ... (Le reste du code de la fonction est inchangé)
350
  let jsonData;
351
  try {
352
  jsonData = JSON.parse(jsonText);
 
391
  }
392
  });
393
 
394
+ // La fonction startStatusPolling reste la même
395
  function startStatusPolling() {
396
  if (statusInterval) {
397
  clearInterval(statusInterval);
 
422
  }, 2000); // Vérifier toutes les 2 secondes
423
  }
424
 
425
+ // MISE À JOUR MAJEURE DE CETTE FONCTION
426
  function updateStatusDisplay(status) {
427
  const container = statusContainer;
428
 
 
441
  statusIcon = '🎨';
442
  statusText = 'Génération en cours';
443
  break;
444
+ case 'creating_zip': // STATUT MIS À JOUR
445
  statusClass = 'generating';
446
+ statusIcon = '🗜️'; // Icône de compression
447
+ statusText = 'Création de l\'archive ZIP';
448
  break;
449
  case 'completed':
450
  statusClass = 'completed';
 
458
  break;
459
  }
460
 
461
+ // ... (La logique de la barre de progression reste la même)
462
  let progressHtml = '';
463
  if (status.total_pages && status.current_page) {
464
  const progress = (status.current_page / status.total_pages) * 100;
 
477
  if (status.status === 'completed') {
478
  downloadHtml = `
479
  <a href="/download/${currentTaskId}" class="download-btn" style="width: 100%; text-align: center; margin-top: 15px;">
480
+ 📥 Télécharger l'archive ZIP
481
  </a>
482
  `;
483
  }
484
 
485
+ // ... (Le HTML pour l'erreur reste le même)
486
  let errorHtml = '';
487
  if (status.error) {
488
  errorHtml = `<div class="alert alert-error">${status.error}</div>`;
489
  }
490
+
491
+ // Affichage du statut
492
  container.innerHTML = `
493
  <div class="status-card ${statusClass}">
494
  <h3>${statusIcon} ${statusText}</h3>
 
500
  ${downloadHtml}
501
  </div>
502
  `;
503
+
504
+ // NOUVELLE PARTIE : Affichage des images
505
+ if (status.image_urls && status.image_urls.length > 0) {
506
+ previewSection.style.display = 'block';
507
+
508
+ status.image_urls.forEach(url => {
509
+ // Vérifier si l'image n'est pas déjà affichée
510
+ if (!document.querySelector(`img[src="${url}"]`)) {
511
+ const img = document.createElement('img');
512
+ img.src = url;
513
+ img.alt = `Page générée pour la tâche ${currentTaskId}`;
514
+ img.onload = () => img.style.opacity = 1; // Effet d'apparition
515
+ img.style.opacity = 0;
516
+ img.style.transition = 'opacity 0.5s';
517
+ imageGrid.appendChild(img);
518
+ }
519
+ });
520
+ }
521
  }
522
 
523
+ // ... (Le reste du script JS reste identique)
524
  function showAlert(message, type) {
525
  const alertClass = type === 'error' ? 'alert-error' : 'alert-success';
526
  const alertHtml = `<div class="alert ${alertClass}">${message}</div>`;
527
 
528
  statusContainer.innerHTML = alertHtml + statusContainer.innerHTML;
529
 
 
530
  setTimeout(() => {
531
  const alert = statusContainer.querySelector('.alert');
532
  if (alert) {
 
535
  }, 5000);
536
  }
537
 
 
538
  window.addEventListener('beforeunload', () => {
539
  if (statusInterval) {
540
  clearInterval(statusInterval);
541
  }
542
  });
543
 
 
544
  jsonInput.addEventListener('blur', () => {
545
  try {
546
  const parsed = JSON.parse(jsonInput.value);
547
  jsonInput.value = JSON.stringify(parsed, null, 2);
548
  } catch (error) {
549
+ // Ignorer les erreurs
550
  }
551
  });
552
  </script>