Docfile commited on
Commit
8cf621b
·
verified ·
1 Parent(s): 1ab4a52

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +125 -54
templates/index.html CHANGED
@@ -1,14 +1,20 @@
1
  <!DOCTYPE html>
2
  <html lang="fr">
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
  <title>Mariam AI - Analyse d'Image</title>
 
7
  <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
 
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script>
 
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.7.32/sweetalert2.all.min.js"></script>
 
10
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
11
  <style>
 
12
  .loader {
13
  width: 48px;
14
  height: 48px;
@@ -21,19 +27,31 @@
21
  }
22
 
23
  @keyframes rotation {
24
- 0% { transform: rotate(0deg); }
25
- 100% { transform: rotate(360deg); }
 
 
 
 
 
26
  }
27
 
 
28
  .fade-in {
29
  animation: fadeIn 0.5s ease-in;
30
  }
31
 
32
  @keyframes fadeIn {
33
- 0% { opacity: 0; }
34
- 100% { opacity: 1; }
 
 
 
 
 
35
  }
36
 
 
37
  .upload-zone {
38
  border: 2px dashed #6366F1;
39
  transition: all 0.3s ease;
@@ -44,6 +62,7 @@
44
  background-color: #EEF2FF;
45
  }
46
 
 
47
  .markdown-content {
48
  overflow-x: auto;
49
  padding-bottom: 1rem;
@@ -91,6 +110,7 @@
91
  background: #4F46E5;
92
  }
93
 
 
94
  .swal2-popup {
95
  width: 90% !important;
96
  max-width: 1200px !important;
@@ -101,6 +121,7 @@
101
  overflow-y: auto !important;
102
  }
103
 
 
104
  .scroll-indicator {
105
  position: absolute;
106
  bottom: 20px;
@@ -127,7 +148,7 @@
127
  border-radius: 0.5rem;
128
  overflow: hidden;
129
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
130
- 0 2px 4px -1px rgba(0, 0, 0, 0.06);
131
  }
132
 
133
  .image-preview-container img {
@@ -154,6 +175,7 @@
154
  color: white;
155
  }
156
 
 
157
  .tab-buttons {
158
  display: flex;
159
  justify-content: center;
@@ -176,6 +198,7 @@
176
  color: white;
177
  }
178
 
 
179
  .tab-content {
180
  display: none;
181
  }
@@ -184,6 +207,7 @@
184
  display: block;
185
  }
186
 
 
187
  #backupList li {
188
  margin-bottom: 0.5rem;
189
  padding: 0.75rem;
@@ -213,6 +237,7 @@
213
  }
214
  </style>
215
  </head>
 
216
  <body class="bg-gray-50">
217
  <div class="min-h-screen">
218
  <header class="bg-white shadow-sm">
@@ -225,14 +250,16 @@
225
  <main class="max-w-7xl mx-auto px-4 py-8 sm:px-6 lg:px-8">
226
  <div class="bg-white rounded-lg shadow p-6 mb-8">
227
  <form id="uploadForm" class="space-y-6">
228
- <div class="upload-zone rounded-lg p-8 text-center">
229
- <input type="file" id="imageInput" accept="image/*" required
230
- class="hidden" onchange="handleImageSelect()">
 
231
  <label for="imageInput" class="cursor-pointer">
232
  <div class="space-y-2">
233
- <svg class="mx-auto h-12 w-12 text-indigo-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
 
234
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
235
- d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
236
  </svg>
237
  <div id="fileName" class="text-sm text-gray-500">
238
  Cliquez ou glissez une image ici
@@ -241,24 +268,28 @@
241
  </label>
242
  </div>
243
 
 
244
  <div id="imagePreview" class="hidden image-preview-container">
245
  <img id="preview" src="#" alt="Prévisualisation">
246
  <button type="button" class="remove-image" onclick="removeImage()">
247
  <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
248
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/>
 
249
  </svg>
250
  </button>
251
  </div>
252
 
 
253
  <div class="flex justify-center">
254
  <button type="submit"
255
- class="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors duration-200">
256
  Analyser l'image
257
  </button>
258
  </div>
259
  </form>
260
  </div>
261
 
 
262
  <div id="loading" class="hidden">
263
  <div class="flex flex-col items-center justify-center space-y-4">
264
  <span class="loader"></span>
@@ -266,34 +297,44 @@
266
  </div>
267
  </div>
268
 
 
269
  <div id="results" class="space-y-8 hidden">
 
270
  <div class="tab-buttons">
271
  <button id="showDissertation" class="active">Dissertation</button>
272
  <button id="showTableau">Tableau d'analyse</button>
273
  <button id="showBackups">Sauvegardes</button>
274
  </div>
275
 
 
276
  <div id="dissertationTab" class="tab-content active bg-white rounded-lg shadow p-6">
277
  <h2 class="text-2xl font-bold text-gray-900 mb-4">Dissertation</h2>
278
  <div id="dissertationResult" class="prose max-w-none markdown-content">
 
279
  </div>
280
- <button id="saveDissertation" class="mt-4 px-6 py-3 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors duration-200">
 
281
  Sauvegarder la dissertation
282
  </button>
283
  </div>
284
 
 
285
  <div id="tableauTab" class="tab-content bg-white rounded-lg shadow p-6 hidden">
286
  <h2 class="text-2xl font-bold text-gray-900 mb-4">Tableau d'analyse</h2>
287
  <div id="tableauResult" class="markdown-content">
 
288
  </div>
289
- <button id="saveTableau" class="mt-4 px-6 py-3 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors duration-200">
 
290
  Sauvegarder le tableau
291
  </button>
292
  </div>
293
 
 
294
  <div id="backupsTab" class="tab-content bg-white rounded-lg shadow p-6 hidden">
295
  <h2 class="text-2xl font-bold text-gray-900 mb-4">Sauvegardes locales</h2>
296
  <ul id="backupList" class="space-y-2">
 
297
  </ul>
298
  </div>
299
  </div>
@@ -305,6 +346,7 @@
305
  let dissertationContent = '';
306
  let backups = loadBackups();
307
 
 
308
  function handleImageSelect() {
309
  const input = document.getElementById('imageInput');
310
  const preview = document.getElementById('preview');
@@ -313,8 +355,8 @@
313
 
314
  if (input.files && input.files[0]) {
315
  const reader = new FileReader();
316
-
317
- reader.onload = function(e) {
318
  preview.src = e.target.result;
319
  previewContainer.classList.remove('hidden');
320
  previewContainer.classList.add('fade-in');
@@ -327,6 +369,7 @@
327
  }
328
  }
329
 
 
330
  function removeImage() {
331
  const input = document.getElementById('imageInput');
332
  const preview = document.getElementById('preview');
@@ -339,6 +382,7 @@
339
  fileName.textContent = 'Cliquez ou glissez une image ici';
340
  }
341
 
 
342
  function showScrollIndicator(container) {
343
  if (container.scrollWidth > container.clientWidth) {
344
  const indicator = document.createElement('div');
@@ -356,7 +400,7 @@
356
  } else {
357
  indicator.classList.remove('visible');
358
  }
359
-
360
  clearTimeout(container.scrollTimeout);
361
  container.scrollTimeout = setTimeout(() => {
362
  indicator.classList.remove('visible');
@@ -365,9 +409,10 @@
365
  }
366
  }
367
 
368
- document.getElementById('showTableau').addEventListener('click', () => {
 
369
  showTab('tableau');
370
- renderTableauContent();
371
  });
372
 
373
  document.getElementById('showDissertation').addEventListener('click', () => {
@@ -376,9 +421,10 @@
376
 
377
  document.getElementById('showBackups').addEventListener('click', () => {
378
  showTab('backups');
379
- updateBackupList();
380
  });
381
 
 
382
  function showTab(tabName) {
383
  document.querySelectorAll('.tab-content').forEach(tab => tab.classList.remove('active'));
384
  document.querySelectorAll('.tab-buttons button').forEach(button => button.classList.remove('active'));
@@ -387,6 +433,7 @@
387
  document.getElementById(`show${tabName.charAt(0).toUpperCase() + tabName.slice(1)}`).classList.add('active');
388
  }
389
 
 
390
  function loadBackups() {
391
  try {
392
  const storedBackups = localStorage.getItem('mariamAIBackups');
@@ -401,76 +448,96 @@
401
  const timestamp = moment().format('YYYY-MM-DD HH:mm:ss');
402
  backups.push({ timestamp, type, content });
403
  localStorage.setItem('mariamAIBackups', JSON.stringify(backups));
404
- updateBackupList();
405
  Swal.fire({
406
  icon: 'success',
407
- title: 'Sauvegarde réussie !});
 
408
  }
409
 
410
  function updateBackupList() {
411
  const backupList = document.getElementById('backupList');
412
- backupList.innerHTML = '';
 
413
  backups.forEach((backup, index) => {
414
  const listItem = document.createElement('li');
415
  listItem.innerHTML = `
416
- <span class="backup-content">${backup.type === 'dissertation' ? 'Dissertation' : 'Tableau'} - ${backup.timestamp}</span>
417
- <div class="flex items-center space-x-2">
418
- <button data-index="${index}" class="view-backup bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded">Voir</button>
419
- <button data-index="${index}" class="delete-backup bg-red-500 hover:bg-red-700 text-white font-bold py-2 px-4 rounded">Supprimer</button>
420
  </div>
421
  `;
422
  backupList.appendChild(listItem);
423
- });
424
 
425
- document.querySelectorAll('.view-backup').forEach(button => {
426
- button.addEventListener('click', viewBackup);
427
- });
428
- document.querySelectorAll('.delete-backup').forEach(button => {
429
- button.addEventListener('click', deleteBackup);
430
  });
431
  }
432
 
 
 
433
  function viewBackup(event) {
434
  const index = event.target.dataset.index;
435
  const backup = backups[index];
 
436
  Swal.fire({
437
  title: backup.type === 'dissertation' ? 'Dissertation sauvegardée' : 'Tableau sauvegardé',
438
- html: marked.parse(backup.content),
439
  width: '90%',
440
  customClass: {
441
- htmlContainer: 'markdown-content'
442
  },
443
  didRender: () => {
444
  const container = document.querySelector('.markdown-content');
445
  showScrollIndicator(container);
446
  }
 
447
  });
448
  }
449
 
450
  function deleteBackup(event) {
451
  const index = event.target.dataset.index;
452
- backups.splice(index, 1);
453
- localStorage.setItem('mariamAIBackups', JSON.stringify(backups));
454
- updateBackupList();
455
  Swal.fire({
456
- icon: 'success',
457
- title: 'Suppression réussie!'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
458
  })
 
459
  }
460
 
 
 
461
  document.getElementById('saveDissertation').addEventListener('click', () => {
462
  saveBackup('dissertation', dissertationContent);
 
463
  });
464
 
465
  document.getElementById('saveTableau').addEventListener('click', () => {
466
  saveBackup('tableau', tableauContent);
467
  });
468
 
469
-
470
-
471
  document.getElementById('uploadForm').addEventListener('submit', async (e) => {
472
  e.preventDefault();
473
-
474
  const loading = document.getElementById('loading');
475
  const results = document.getElementById('results');
476
  const dissertationResult = document.getElementById('dissertationResult');
@@ -478,39 +545,42 @@
478
 
479
  const formData = new FormData();
480
  formData.append('image', document.getElementById('imageInput').files[0]);
481
-
482
  loading.classList.remove('hidden');
483
  results.classList.add('hidden');
484
-
485
  try {
486
- const response = await fetch('/analyze', {
487
  method: 'POST',
488
  body: formData
489
  });
490
-
491
  const data = await response.json();
492
-
493
  if (response.ok) {
494
  dissertationContent = data.dissertation;
495
  tableauContent = data.tableau;
496
 
497
- dissertationResult.innerHTML = marked.parse(data.dissertation);
498
- tableauResult.innerHTML = marked.parse(data.tableau);
 
499
  results.classList.remove('hidden');
500
  results.classList.add('fade-in');
501
- showTab('dissertation'); // Afficher l'onglet dissertation par défaut après l'analyse
502
  } else {
 
503
  Swal.fire({
504
  icon: 'error',
505
- title: 'Erreur',
506
- text: data.error
507
  });
508
  }
509
  } catch (error) {
 
510
  Swal.fire({
511
  icon: 'error',
512
  title: 'Erreur',
513
- text: 'Une erreur est survenue lors de l\'analyse'
514
  });
515
  } finally {
516
  loading.classList.add('hidden');
@@ -527,4 +597,5 @@
527
 
528
  </script>
529
  </body>
 
530
  </html>
 
1
  <!DOCTYPE html>
2
  <html lang="fr">
3
+
4
  <head>
5
  <meta charset="UTF-8">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
  <title>Mariam AI - Analyse d'Image</title>
8
+ <!-- CDN pour Tailwind CSS pour le style -->
9
  <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
10
+ <!-- CDN pour Marked pour convertir le Markdown en HTML -->
11
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script>
12
+ <!-- CDN pour SweetAlert2 pour des popups plus sympas -->
13
  <script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.7.32/sweetalert2.all.min.js"></script>
14
+ <!-- CDN pour Moment.js pour formater les dates -->
15
  <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.29.1/moment.min.js"></script>
16
  <style>
17
+ /* Styles pour le loader */
18
  .loader {
19
  width: 48px;
20
  height: 48px;
 
27
  }
28
 
29
  @keyframes rotation {
30
+ 0% {
31
+ transform: rotate(0deg);
32
+ }
33
+
34
+ 100% {
35
+ transform: rotate(360deg);
36
+ }
37
  }
38
 
39
+ /* Styles pour l'animation d'apparition en fondu */
40
  .fade-in {
41
  animation: fadeIn 0.5s ease-in;
42
  }
43
 
44
  @keyframes fadeIn {
45
+ 0% {
46
+ opacity: 0;
47
+ }
48
+
49
+ 100% {
50
+ opacity: 1;
51
+ }
52
  }
53
 
54
+ /* Styles pour la zone de drop d'image */
55
  .upload-zone {
56
  border: 2px dashed #6366F1;
57
  transition: all 0.3s ease;
 
62
  background-color: #EEF2FF;
63
  }
64
 
65
+ /* Styles pour le contenu Markdown */
66
  .markdown-content {
67
  overflow-x: auto;
68
  padding-bottom: 1rem;
 
110
  background: #4F46E5;
111
  }
112
 
113
+ /* Ajustement de la taille des popups SweetAlert2 */
114
  .swal2-popup {
115
  width: 90% !important;
116
  max-width: 1200px !important;
 
121
  overflow-y: auto !important;
122
  }
123
 
124
+ /* Styles pour l'indicateur de scroll horizontal */
125
  .scroll-indicator {
126
  position: absolute;
127
  bottom: 20px;
 
148
  border-radius: 0.5rem;
149
  overflow: hidden;
150
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
151
+ 0 2px 4px -1px rgba(0, 0, 0, 0.06);
152
  }
153
 
154
  .image-preview-container img {
 
175
  color: white;
176
  }
177
 
178
+ /* Styles pour les boutons d'onglets */
179
  .tab-buttons {
180
  display: flex;
181
  justify-content: center;
 
198
  color: white;
199
  }
200
 
201
+ /* Styles pour le contenu des onglets */
202
  .tab-content {
203
  display: none;
204
  }
 
207
  display: block;
208
  }
209
 
210
+ /* Styles pour la liste des sauvegardes */
211
  #backupList li {
212
  margin-bottom: 0.5rem;
213
  padding: 0.75rem;
 
237
  }
238
  </style>
239
  </head>
240
+
241
  <body class="bg-gray-50">
242
  <div class="min-h-screen">
243
  <header class="bg-white shadow-sm">
 
250
  <main class="max-w-7xl mx-auto px-4 py-8 sm:px-6 lg:px-8">
251
  <div class="bg-white rounded-lg shadow p-6 mb-8">
252
  <form id="uploadForm" class="space-y-6">
253
+ <!-- Zone de téléchargement d'image -->
254
+ <div class="upload-zone rounded-lg p-8 text-center">
255
+ <input type="file" id="imageInput" accept="image/*" required class="hidden"
256
+ onchange="handleImageSelect()">
257
  <label for="imageInput" class="cursor-pointer">
258
  <div class="space-y-2">
259
+ <svg class="mx-auto h-12 w-12 text-indigo-500" fill="none" viewBox="0 0 24 24"
260
+ stroke="currentColor">
261
  <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
262
+ d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" />
263
  </svg>
264
  <div id="fileName" class="text-sm text-gray-500">
265
  Cliquez ou glissez une image ici
 
268
  </label>
269
  </div>
270
 
271
+ <!-- Prévisualisation de l'image -->
272
  <div id="imagePreview" class="hidden image-preview-container">
273
  <img id="preview" src="#" alt="Prévisualisation">
274
  <button type="button" class="remove-image" onclick="removeImage()">
275
  <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
276
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
277
+ d="M6 18L18 6M6 6l12 12" />
278
  </svg>
279
  </button>
280
  </div>
281
 
282
+ <!-- Bouton de soumission du formulaire -->
283
  <div class="flex justify-center">
284
  <button type="submit"
285
+ class="inline-flex items-center px-6 py-3 border border-transparent text-base font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 transition-colors duration-200">
286
  Analyser l'image
287
  </button>
288
  </div>
289
  </form>
290
  </div>
291
 
292
+ <!-- Indicateur de chargement -->
293
  <div id="loading" class="hidden">
294
  <div class="flex flex-col items-center justify-center space-y-4">
295
  <span class="loader"></span>
 
297
  </div>
298
  </div>
299
 
300
+ <!-- Section des résultats -->
301
  <div id="results" class="space-y-8 hidden">
302
+ <!-- Boutons pour changer d'onglet -->
303
  <div class="tab-buttons">
304
  <button id="showDissertation" class="active">Dissertation</button>
305
  <button id="showTableau">Tableau d'analyse</button>
306
  <button id="showBackups">Sauvegardes</button>
307
  </div>
308
 
309
+ <!-- Onglet Dissertation -->
310
  <div id="dissertationTab" class="tab-content active bg-white rounded-lg shadow p-6">
311
  <h2 class="text-2xl font-bold text-gray-900 mb-4">Dissertation</h2>
312
  <div id="dissertationResult" class="prose max-w-none markdown-content">
313
+ <!-- Le contenu de la dissertation sera affiché ici -->
314
  </div>
315
+ <button id="saveDissertation"
316
+ class="mt-4 px-6 py-3 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors duration-200">
317
  Sauvegarder la dissertation
318
  </button>
319
  </div>
320
 
321
+ <!-- Onglet Tableau d'analyse -->
322
  <div id="tableauTab" class="tab-content bg-white rounded-lg shadow p-6 hidden">
323
  <h2 class="text-2xl font-bold text-gray-900 mb-4">Tableau d'analyse</h2>
324
  <div id="tableauResult" class="markdown-content">
325
+ <!-- Le contenu du tableau sera affiché ici -->
326
  </div>
327
+ <button id="saveTableau"
328
+ class="mt-4 px-6 py-3 bg-green-600 text-white rounded-md hover:bg-green-700 transition-colors duration-200">
329
  Sauvegarder le tableau
330
  </button>
331
  </div>
332
 
333
+ <!-- Onglet Sauvegardes -->
334
  <div id="backupsTab" class="tab-content bg-white rounded-lg shadow p-6 hidden">
335
  <h2 class="text-2xl font-bold text-gray-900 mb-4">Sauvegardes locales</h2>
336
  <ul id="backupList" class="space-y-2">
337
+ <!-- La liste des sauvegardes sera affichée ici -->
338
  </ul>
339
  </div>
340
  </div>
 
346
  let dissertationContent = '';
347
  let backups = loadBackups();
348
 
349
+ // Fonction pour gérer la sélection et la prévisualisation de l'image
350
  function handleImageSelect() {
351
  const input = document.getElementById('imageInput');
352
  const preview = document.getElementById('preview');
 
355
 
356
  if (input.files && input.files[0]) {
357
  const reader = new FileReader();
358
+
359
+ reader.onload = function (e) {
360
  preview.src = e.target.result;
361
  previewContainer.classList.remove('hidden');
362
  previewContainer.classList.add('fade-in');
 
369
  }
370
  }
371
 
372
+ // Fonction pour supprimer l'image prévisualisée
373
  function removeImage() {
374
  const input = document.getElementById('imageInput');
375
  const preview = document.getElementById('preview');
 
382
  fileName.textContent = 'Cliquez ou glissez une image ici';
383
  }
384
 
385
+ // Fonction pour afficher un indicateur de scroll horizontal si nécessaire
386
  function showScrollIndicator(container) {
387
  if (container.scrollWidth > container.clientWidth) {
388
  const indicator = document.createElement('div');
 
400
  } else {
401
  indicator.classList.remove('visible');
402
  }
403
+
404
  clearTimeout(container.scrollTimeout);
405
  container.scrollTimeout = setTimeout(() => {
406
  indicator.classList.remove('visible');
 
409
  }
410
  }
411
 
412
+ // Gestion des clics sur les onglets
413
+ document.getElementById('showTableau').addEventListener('click, () => {
414
  showTab('tableau');
415
+ renderTableauContent(); // Rendre le contenu du tableau Markdown
416
  });
417
 
418
  document.getElementById('showDissertation').addEventListener('click', () => {
 
421
 
422
  document.getElementById('showBackups').addEventListener('click', () => {
423
  showTab('backups');
424
+ updateBackupList(); // Mettre à jour la liste des sauvegardes
425
  });
426
 
427
+ // Fonction pour afficher l'onglet sélectionné
428
  function showTab(tabName) {
429
  document.querySelectorAll('.tab-content').forEach(tab => tab.classList.remove('active'));
430
  document.querySelectorAll('.tab-buttons button').forEach(button => button.classList.remove('active'));
 
433
  document.getElementById(`show${tabName.charAt(0).toUpperCase() + tabName.slice(1)}`).classList.add('active');
434
  }
435
 
436
+ // Fonctions pour gérer les sauvegardes locales
437
  function loadBackups() {
438
  try {
439
  const storedBackups = localStorage.getItem('mariamAIBackups');
 
448
  const timestamp = moment().format('YYYY-MM-DD HH:mm:ss');
449
  backups.push({ timestamp, type, content });
450
  localStorage.setItem('mariamAIBackups', JSON.stringify(backups));
451
+ updateBackupList(); // Mettre à jour la liste des sauvegardes après sauvegarde
452
  Swal.fire({
453
  icon: 'success',
454
+ title: 'Sauvegarde réussie!',
455
+ });
456
  }
457
 
458
  function updateBackupList() {
459
  const backupList = document.getElementById('backupList');
460
+ backupList.innerHTML = ''; // Effacer la liste actuelle
461
+
462
  backups.forEach((backup, index) => {
463
  const listItem = document.createElement('li');
464
  listItem.innerHTML = `
465
+ <span>${backup.type === 'dissertation' ? 'Dissertation' : 'Tableau'} - ${backup.timestamp}</span>
466
+ <div>
467
+ <button data-index="${index}" class="view-backup bg-blue-500 hover:bg-blue-700 text-white font-bold py-1 px-2 rounded text-xs">Voir</button>
468
+ <button data-index="${index}" class="delete-backup bg-red-500 hover:bg-red-700 text-white font-bold py-1 px-2 rounded text-xs">Supprimer</button>
469
  </div>
470
  `;
471
  backupList.appendChild(listItem);
 
472
 
473
+ // Ajouter des écouteurs d'événements pour les boutons "Voir" et "Supprimer"
474
+ listItem.querySelector('.view-backup').addEventListener('click', viewBackup);
475
+ listItem.querySelector('.delete-backup').addEventListener('click', deleteBackup);
476
+
 
477
  });
478
  }
479
 
480
+
481
+
482
  function viewBackup(event) {
483
  const index = event.target.dataset.index;
484
  const backup = backups[index];
485
+
486
  Swal.fire({
487
  title: backup.type === 'dissertation' ? 'Dissertation sauvegardée' : 'Tableau sauvegardé',
488
+ html: marked.parse(backup.content), // Afficher le contenu Markdown
489
  width: '90%',
490
  customClass: {
491
+ htmlContainer: 'markdown-content' // Appliquer le style markdown
492
  },
493
  didRender: () => {
494
  const container = document.querySelector('.markdown-content');
495
  showScrollIndicator(container);
496
  }
497
+
498
  });
499
  }
500
 
501
  function deleteBackup(event) {
502
  const index = event.target.dataset.index;
 
 
 
503
  Swal.fire({
504
+ title: 'Êtes-vous sûr?',
505
+ text: "Vous ne pourrez pas revenir en arrière !",
506
+ icon: 'warning',
507
+ showCancelButton: true,
508
+ confirmButtonColor: '#3085d6',
509
+ cancelButtonColor: '#d33',
510
+ confirmButtonText: 'Oui, supprimer!'
511
+ }).then((result) => {
512
+ if (result.isConfirmed) {
513
+ backups.splice(index, 1);
514
+ localStorage.setItem('mariamAIBackups', JSON.stringify(backups));
515
+ updateBackupList(); // mettre à jour l'affichage
516
+ Swal.fire(
517
+ 'Supprimé!',
518
+ 'Votre fichier a été supprimé.',
519
+ 'success'
520
+ )
521
+ }
522
  })
523
+
524
  }
525
 
526
+
527
+
528
  document.getElementById('saveDissertation').addEventListener('click', () => {
529
  saveBackup('dissertation', dissertationContent);
530
+
531
  });
532
 
533
  document.getElementById('saveTableau').addEventListener('click', () => {
534
  saveBackup('tableau', tableauContent);
535
  });
536
 
537
+ // Fonction pour gérer la soumission du formulaire et l'analyse de l'image
 
538
  document.getElementById('uploadForm').addEventListener('submit', async (e) => {
539
  e.preventDefault();
540
+
541
  const loading = document.getElementById('loading');
542
  const results = document.getElementById('results');
543
  const dissertationResult = document.getElementById('dissertationResult');
 
545
 
546
  const formData = new FormData();
547
  formData.append('image', document.getElementById('imageInput').files[0]);
548
+
549
  loading.classList.remove('hidden');
550
  results.classList.add('hidden');
551
+
552
  try {
553
+ const response = await fetch('/analyze', { // Remplacez '/analyze' par l'URL de votre endpoint
554
  method: 'POST',
555
  body: formData
556
  });
557
+
558
  const data = await response.json();
559
+
560
  if (response.ok) {
561
  dissertationContent = data.dissertation;
562
  tableauContent = data.tableau;
563
 
564
+ dissertationResult.innerHTML = marked.parse(data.dissertation); // Convertir en HTML
565
+ // Ne pas afficher le tableau immédiatement, attendre que l'utilisateur clique sur l'onglet
566
+
567
  results.classList.remove('hidden');
568
  results.classList.add('fade-in');
569
+ showTab('dissertation'); // Afficher l'onglet "dissertation" par défaut
570
  } else {
571
+ // Afficher une alerte d'erreur plus informative
572
  Swal.fire({
573
  icon: 'error',
574
+ title: 'Erreur lors de l\'analyse',
575
+ text: data.error || 'Une erreur est survenue lors du traitement de votre image. Veuillez réessayer.',
576
  });
577
  }
578
  } catch (error) {
579
+
580
  Swal.fire({
581
  icon: 'error',
582
  title: 'Erreur',
583
+ text: 'Une erreur est survenue lors de la communication avec le serveur. Veuillez vérifier votre connexion internet et réessayer.',
584
  });
585
  } finally {
586
  loading.classList.add('hidden');
 
597
 
598
  </script>
599
  </body>
600
+
601
  </html>