Docfile commited on
Commit
f9ced6f
·
verified ·
1 Parent(s): 7631179

Upload index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +180 -97
templates/index.html CHANGED
@@ -2,96 +2,166 @@
2
  <html lang="fr">
3
  <head>
4
  <meta charset="UTF-8">
5
- <title>Mariam AI - Section Commentaire Composé</title>
6
- <!-- Intégration de Tailwind CSS avec le plugin Typography -->
7
- <script src="https://cdn.tailwindcss.com?plugins=typography"></script>
8
- <!-- Intégration de Marked.js pour la conversion Markdown -->
9
- <script src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
10
  <style>
11
- /* Spinner personnalisé */
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  .spinner {
13
  border: 4px solid rgba(0, 0, 0, 0.1);
14
  width: 3rem;
15
  height: 3rem;
16
  border-radius: 50%;
17
- border-left-color: #4f46e5;
18
  animation: spin 1s linear infinite;
19
  }
 
20
  @keyframes spin {
21
  to { transform: rotate(360deg); }
22
  }
23
- /* Style personnalisé pour les tableaux générés en Markdown */
24
- .prose table {
25
- width: 100%;
26
- max-width: 100%;
27
- border-collapse: collapse;
28
- }
29
- .prose th,
30
- .prose td {
31
- border: 1px solid #e5e7eb;
32
- padding: 0.75rem;
33
- text-align: left;
34
  }
35
- .prose th {
36
- background-color: #f3f4f6;
37
- font-weight: 600;
 
 
38
  }
39
  </style>
40
  </head>
41
- <body class="bg-gray-100">
42
- <div class="max-w-3xl mx-auto p-4">
43
- <!-- En-tête de l'application -->
44
- <header class="mb-8 text-center">
45
- <h1 class="text-4xl font-extrabold text-gray-800">Mariam AI</h1>
46
- <p class="text-xl text-gray-600">Section Commentaire Composé</p>
47
  </header>
48
 
49
- <div class="bg-white rounded-lg shadow-lg p-6">
50
- <!-- Formulaire d'upload et prévisualisation -->
51
- <form id="uploadForm" enctype="multipart/form-data" class="mb-6">
52
- <label for="imageInput" class="block text-lg font-medium text-gray-700 mb-2">
53
- Sélectionnez une image :
54
- </label>
55
- <input type="file" name="image" id="imageInput" accept="image/*" required
56
- class="block w-full border border-gray-300 rounded-md p-2 mb-4 focus:ring focus:ring-blue-300">
57
- <!-- Prévisualisation de l'image -->
58
- <div id="previewContainer" class="mb-4 hidden">
59
- <p class="text-gray-700 font-medium mb-2">Prévisualisation :</p>
60
- <img id="previewImage" src="#" alt="Prévisualisation" class="w-full max-h-64 object-contain rounded-lg shadow-md">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  </div>
62
- <button type="submit" class="w-full bg-blue-600 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded transition-colors">
63
- Analyser
 
64
  </button>
65
  </form>
66
 
67
  <!-- Indicateur de chargement -->
68
- <div id="loading" class="flex flex-col items-center space-y-2 mb-6 hidden">
69
- <div class="spinner"></div>
70
- <span class="text-gray-700 font-medium">Analyse en cours...</span>
 
 
 
 
71
  </div>
72
 
73
- <!-- Bouton pour afficher/masquer le tableau d'analyse -->
74
- <button id="toggleButton" class="hidden bg-green-600 hover:bg-green-700 text-white font-bold py-2 px-4 rounded w-full mb-4 transition-colors">
75
- Afficher le Tableau
76
- </button>
77
-
78
- <!-- Zone de résultats -->
79
- <div id="result" class="hidden">
80
- <!-- Section Dissertation -->
81
- <section class="mb-8">
82
- <h2 class="text-2xl font-semibold text-gray-800 mb-4">Dissertation</h2>
83
- <div id="dissertationContent" class="prose prose-sm sm:prose lg:prose-xl bg-gray-50 border border-gray-200 rounded p-6 text-gray-800 overflow-x-auto"></div>
84
- </section>
85
- <!-- Section Tableau d'analyse -->
86
- <section id="tableauSection" class="hidden">
87
- <h2 class="text-2xl font-semibold text-gray-800 mb-4">Tableau d'analyse</h2>
88
- <div id="tableauContent" class="prose prose-sm sm:prose lg:prose-xl bg-gray-50 border border-gray-200 rounded p-6 text-gray-800 overflow-x-auto"></div>
89
- </section>
 
 
 
 
 
90
  </div>
91
  </div>
92
  </div>
93
 
94
- <!-- Script JavaScript -->
95
  <script>
96
  const uploadForm = document.getElementById('uploadForm');
97
  const imageInput = document.getElementById('imageInput');
@@ -99,12 +169,20 @@
99
  const previewImage = document.getElementById('previewImage');
100
  const loadingIndicator = document.getElementById('loading');
101
  const resultDiv = document.getElementById('result');
102
- const toggleButton = document.getElementById('toggleButton');
103
- const tableauSection = document.getElementById('tableauSection');
104
- const tableauContent = document.getElementById('tableauContent');
105
  const dissertationContent = document.getElementById('dissertationContent');
 
 
 
 
 
 
 
 
 
106
 
107
- // Prévisualisation de l'image sélectionnée
108
  imageInput.addEventListener('change', function() {
109
  const file = this.files[0];
110
  if (file) {
@@ -119,16 +197,27 @@
119
  }
120
  });
121
 
122
- // Gestion de la soumission du formulaire
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
123
  uploadForm.addEventListener('submit', function(e) {
124
  e.preventDefault();
125
-
126
- // Afficher le chargement et masquer les résultats
127
  loadingIndicator.classList.remove('hidden');
128
  resultDiv.classList.add('hidden');
129
- toggleButton.classList.add('hidden');
130
- tableauSection.classList.add('hidden');
131
-
132
  const formData = new FormData(uploadForm);
133
 
134
  fetch('/analyze', {
@@ -139,38 +228,32 @@
139
  .then(data => {
140
  loadingIndicator.classList.add('hidden');
141
  if (data.error) {
142
- alert("Erreur : " + data.error);
143
- } else {
144
- // Convertir le Markdown en HTML via Marked.js
145
- dissertationContent.innerHTML = marked.parse(data.dissertation);
146
- tableauContent.innerHTML = marked.parse(data.tableau);
147
-
148
- // Afficher la zone de résultats et le bouton de basculement
149
- resultDiv.classList.remove('hidden');
150
- toggleButton.classList.remove('hidden');
151
- // Masquer le tableau par défaut
152
- tableauSection.classList.add('hidden');
153
- toggleButton.textContent = 'Afficher le Tableau';
154
  }
 
 
 
 
 
 
 
 
 
 
 
155
  })
156
  .catch(error => {
157
  loadingIndicator.classList.add('hidden');
158
- console.error(error);
159
- alert("Une erreur est survenue lors de l'analyse.");
160
  });
161
  });
162
 
163
- // Gestion du bouton d'affichage/masquage du tableau
164
- toggleButton.addEventListener('click', function() {
165
- if (tableauSection.classList.contains('hidden')) {
166
- tableauSection.classList.remove('hidden');
167
- toggleButton.textContent = 'Masquer le Tableau';
168
- // Défilement automatique vers le tableau
169
- tableauSection.scrollIntoView({ behavior: 'smooth' });
170
- } else {
171
- tableauSection.classList.add('hidden');
172
- toggleButton.textContent = 'Afficher le Tableau';
173
- }
174
  });
175
  </script>
176
  </body>
 
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 Littéraire</title>
7
+ <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/9.1.6/marked.min.js"></script>
 
9
  <style>
10
+ @import url('https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;700&family=Inter:wght@300;400;500;600;700&display=swap');
11
+
12
+ .custom-prose h1, .custom-prose h2, .custom-prose h3 {
13
+ font-family: 'Playfair Display', serif;
14
+ margin-top: 2em;
15
+ margin-bottom: 1em;
16
+ line-height: 1.3;
17
+ }
18
+
19
+ .custom-prose p {
20
+ margin-bottom: 1.5em;
21
+ line-height: 1.8;
22
+ }
23
+
24
+ .custom-prose ul, .custom-prose ol {
25
+ margin-top: 1em;
26
+ margin-bottom: 1em;
27
+ padding-left: 1.5em;
28
+ }
29
+
30
+ .custom-prose li {
31
+ margin-bottom: 0.5em;
32
+ }
33
+
34
+ .markdown-table table {
35
+ width: 100%;
36
+ border-collapse: separate;
37
+ border-spacing: 0;
38
+ margin: 2em 0;
39
+ background: white;
40
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
41
+ }
42
+
43
+ .markdown-table th {
44
+ background: #1a365d;
45
+ color: white;
46
+ font-weight: 600;
47
+ padding: 1rem;
48
+ text-align: left;
49
+ }
50
+
51
+ .markdown-table td {
52
+ padding: 1rem;
53
+ border-bottom: 1px solid #e2e8f0;
54
+ }
55
+
56
+ .markdown-table tr:hover {
57
+ background: #f8fafc;
58
+ }
59
+
60
  .spinner {
61
  border: 4px solid rgba(0, 0, 0, 0.1);
62
  width: 3rem;
63
  height: 3rem;
64
  border-radius: 50%;
65
+ border-left-color: #1a365d;
66
  animation: spin 1s linear infinite;
67
  }
68
+
69
  @keyframes spin {
70
  to { transform: rotate(360deg); }
71
  }
72
+
73
+ .fade-enter {
74
+ opacity: 0;
75
+ transform: translateY(20px);
 
 
 
 
 
 
 
76
  }
77
+
78
+ .fade-enter-active {
79
+ opacity: 1;
80
+ transform: translateY(0);
81
+ transition: opacity 300ms, transform 300ms;
82
  }
83
  </style>
84
  </head>
85
+ <body class="bg-gradient-to-br from-gray-50 to-gray-100 min-h-screen font-['Inter']">
86
+ <div class="max-w-4xl mx-auto p-6">
87
+ <!-- En-tête -->
88
+ <header class="text-center mb-12">
89
+ <h1 class="font-['Playfair_Display'] text-5xl font-bold text-gray-900 mb-4">Mariam AI</h1>
90
+ <p class="text-xl text-gray-600">Assistant d'Analyse Littéraire</p>
91
  </header>
92
 
93
+ <div class="bg-white rounded-xl shadow-lg p-8">
94
+ <!-- Zone de téléchargement -->
95
+ <form id="uploadForm" class="space-y-6">
96
+ <div class="relative">
97
+ <label for="imageInput" class="block text-lg font-medium text-gray-700 mb-3">
98
+ Sélectionnez votre document
99
+ </label>
100
+ <div class="mt-2 flex justify-center px-6 pt-5 pb-6 border-2 border-gray-300 border-dashed rounded-lg hover:border-blue-500 transition-colors cursor-pointer">
101
+ <div class="space-y-2 text-center">
102
+ <svg class="mx-auto h-12 w-12 text-gray-400" stroke="currentColor" fill="none" viewBox="0 0 48 48" aria-hidden="true">
103
+ <path d="M28 8H12a4 4 0 00-4 4v20m32-12v8m0 0v8a4 4 0 01-4 4H12a4 4 0 01-4-4v-4m32-4l-3.172-3.172a4 4 0 00-5.656 0L28 28M8 32l9.172-9.172a4 4 0 015.656 0L28 28m0 0l4 4m4-24h8m-4-4v8m-12 4h.02" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
104
+ </svg>
105
+ <div class="text-sm text-gray-600">
106
+ <label for="imageInput" class="relative cursor-pointer bg-white rounded-md font-medium text-blue-600 hover:text-blue-500 focus-within:outline-none">
107
+ <span>Télécharger un fichier</span>
108
+ <input id="imageInput" name="image" type="file" class="sr-only" accept="image/*" required>
109
+ </label>
110
+ </div>
111
+ <p class="text-xs text-gray-500">PNG, JPG jusqu'à 10MB</p>
112
+ </div>
113
+ </div>
114
+ </div>
115
+
116
+ <!-- Prévisualisation -->
117
+ <div id="previewContainer" class="hidden">
118
+ <p class="text-gray-700 font-medium mb-3">Aperçu du document :</p>
119
+ <div class="relative rounded-lg overflow-hidden bg-gray-100">
120
+ <img id="previewImage" src="#" alt="Aperçu" class="w-full max-h-80 object-contain">
121
+ </div>
122
  </div>
123
+
124
+ <button type="submit" class="w-full bg-blue-600 text-white rounded-lg px-4 py-3 font-semibold hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 transition-colors">
125
+ Lancer l'analyse
126
  </button>
127
  </form>
128
 
129
  <!-- Indicateur de chargement -->
130
+ <div id="loading" class="hidden">
131
+ <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
132
+ <div class="bg-white p-6 rounded-lg shadow-xl text-center">
133
+ <div class="spinner mx-auto mb-4"></div>
134
+ <p class="text-gray-700 font-medium">Analyse en cours...</p>
135
+ </div>
136
+ </div>
137
  </div>
138
 
139
+ <!-- Résultats -->
140
+ <div id="result" class="hidden mt-8 space-y-8">
141
+ <!-- Navigation -->
142
+ <div class="flex space-x-4 border-b border-gray-200">
143
+ <button id="dissertationTab" class="px-4 py-2 text-sm font-medium text-blue-600 border-b-2 border-blue-600">
144
+ Dissertation
145
+ </button>
146
+ <button id="tableauTab" class="px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700">
147
+ Tableau d'analyse
148
+ </button>
149
+ </div>
150
+
151
+ <!-- Contenu Dissertation -->
152
+ <div id="dissertationContent" class="custom-prose prose prose-lg max-w-none">
153
+ </div>
154
+
155
+ <!-- Contenu Tableau -->
156
+ <div id="tableauContent" class="hidden markdown-table prose prose-lg max-w-none">
157
+ <div class="overflow-x-auto">
158
+ <!-- Le tableau sera injecté ici via Marked -->
159
+ </div>
160
+ </div>
161
  </div>
162
  </div>
163
  </div>
164
 
 
165
  <script>
166
  const uploadForm = document.getElementById('uploadForm');
167
  const imageInput = document.getElementById('imageInput');
 
169
  const previewImage = document.getElementById('previewImage');
170
  const loadingIndicator = document.getElementById('loading');
171
  const resultDiv = document.getElementById('result');
172
+ const dissertationTab = document.getElementById('dissertationTab');
173
+ const tableauTab = document.getElementById('tableauTab');
 
174
  const dissertationContent = document.getElementById('dissertationContent');
175
+ const tableauContent = document.getElementById('tableauContent');
176
+
177
+ // Configuration de marked pour le rendu Markdown
178
+ marked.setOptions({
179
+ breaks: true,
180
+ gfm: true,
181
+ headerIds: true,
182
+ langPrefix: 'language-',
183
+ });
184
 
185
+ // Prévisualisation
186
  imageInput.addEventListener('change', function() {
187
  const file = this.files[0];
188
  if (file) {
 
197
  }
198
  });
199
 
200
+ // Gestion des onglets
201
+ dissertationTab.addEventListener('click', function() {
202
+ dissertationTab.classList.add('text-blue-600', 'border-b-2', 'border-blue-600');
203
+ tableauTab.classList.remove('text-blue-600', 'border-b-2', 'border-blue-600');
204
+ dissertationContent.classList.remove('hidden');
205
+ tableauContent.classList.add('hidden');
206
+ });
207
+
208
+ tableauTab.addEventListener('click', function() {
209
+ tableauTab.classList.add('text-blue-600', 'border-b-2', 'border-blue-600');
210
+ dissertationTab.classList.remove('text-blue-600', 'border-b-2', 'border-blue-600');
211
+ tableauContent.classList.remove('hidden');
212
+ dissertationContent.classList.add('hidden');
213
+ });
214
+
215
+ // Soumission du formulaire
216
  uploadForm.addEventListener('submit', function(e) {
217
  e.preventDefault();
 
 
218
  loadingIndicator.classList.remove('hidden');
219
  resultDiv.classList.add('hidden');
220
+
 
 
221
  const formData = new FormData(uploadForm);
222
 
223
  fetch('/analyze', {
 
228
  .then(data => {
229
  loadingIndicator.classList.add('hidden');
230
  if (data.error) {
231
+ throw new Error(data.error);
 
 
 
 
 
 
 
 
 
 
 
232
  }
233
+
234
+ dissertationContent.innerHTML = marked.parse(data.dissertation);
235
+ // Injection du tableau dans le conteneur overflow-x-auto
236
+ tableauContent.querySelector('.overflow-x-auto').innerHTML = marked.parse(data.tableau);
237
+
238
+ resultDiv.classList.remove('hidden');
239
+ // Afficher l'onglet dissertation par défaut
240
+ dissertationTab.click();
241
+
242
+ // Scroll vers les résultats
243
+ resultDiv.scrollIntoView({ behavior: 'smooth' });
244
  })
245
  .catch(error => {
246
  loadingIndicator.classList.add('hidden');
247
+ alert("Une erreur est survenue : " + error.message);
 
248
  });
249
  });
250
 
251
+ // Animation douce pour les transitions
252
+ document.querySelectorAll('.fade-enter').forEach(element => {
253
+ element.classList.add('fade-enter-active');
254
+ setTimeout(() => {
255
+ element.classList.remove('fade-enter', 'fade-enter-active');
256
+ }, 300);
 
 
 
 
 
257
  });
258
  </script>
259
  </body>