Docfile commited on
Commit
ece8519
·
verified ·
1 Parent(s): 4e41129

Create index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +268 -0
templates/index.html ADDED
@@ -0,0 +1,268 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 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
+ <!-- Champ Consignes optionnel -->
117
+ <div class="relative">
118
+ <label for="consignesInput" class="block text-lg font-medium text-gray-700 mb-3">
119
+ Consignes (optionnel)
120
+ </label>
121
+ <input id="consignesInput" name="consignes" type="text" class="w-full border border-gray-300 rounded-md p-2" placeholder="Entrez vos consignes ici">
122
+ </div>
123
+
124
+ <!-- Prévisualisation -->
125
+ <div id="previewContainer" class="hidden">
126
+ <p class="text-gray-700 font-medium mb-3">Aperçu du document :</p>
127
+ <div class="relative rounded-lg overflow-hidden bg-gray-100">
128
+ <img id="previewImage" src="#" alt="Aperçu" class="w-full max-h-80 object-contain">
129
+ </div>
130
+ </div>
131
+
132
+ <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">
133
+ Lancer l'analyse
134
+ </button>
135
+ </form>
136
+
137
+ <!-- Indicateur de chargement -->
138
+ <div id="loading" class="hidden">
139
+ <div class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
140
+ <div class="bg-white p-6 rounded-lg shadow-xl text-center">
141
+ <div class="spinner mx-auto mb-4"></div>
142
+ <p class="text-gray-700 font-medium">Analyse en cours...</p>
143
+ </div>
144
+ </div>
145
+ </div>
146
+
147
+ <!-- Résultats -->
148
+ <div id="result" class="hidden mt-8 space-y-8">
149
+ <!-- Navigation -->
150
+ <div class="flex space-x-4 border-b border-gray-200">
151
+ <button id="dissertationTab" class="px-4 py-2 text-sm font-medium text-blue-600 border-b-2 border-blue-600">
152
+ Dissertation
153
+ </button>
154
+ <button id="tableauTab" class="px-4 py-2 text-sm font-medium text-gray-500 hover:text-gray-700">
155
+ Tableau d'analyse
156
+ </button>
157
+ </div>
158
+
159
+ <!-- Contenu Dissertation -->
160
+ <div id="dissertationContent" class="custom-prose prose prose-lg max-w-none">
161
+ </div>
162
+
163
+ <!-- Contenu Tableau -->
164
+ <div id="tableauContent" class="hidden markdown-table prose prose-lg max-w-none">
165
+ <div class="overflow-x-auto">
166
+ <!-- Le tableau sera injecté ici via Marked -->
167
+ </div>
168
+ </div>
169
+ </div>
170
+ </div>
171
+ </div>
172
+
173
+ <script>
174
+ const uploadForm = document.getElementById('uploadForm');
175
+ const imageInput = document.getElementById('imageInput');
176
+ const previewContainer = document.getElementById('previewContainer');
177
+ const previewImage = document.getElementById('previewImage');
178
+ const loadingIndicator = document.getElementById('loading');
179
+ const resultDiv = document.getElementById('result');
180
+ const dissertationTab = document.getElementById('dissertationTab');
181
+ const tableauTab = document.getElementById('tableauTab');
182
+ const dissertationContent = document.getElementById('dissertationContent');
183
+ const tableauContent = document.getElementById('tableauContent');
184
+
185
+ // Configuration de marked pour le rendu Markdown
186
+ marked.setOptions({
187
+ breaks: true,
188
+ gfm: true,
189
+ headerIds: true,
190
+ langPrefix: 'language-',
191
+ });
192
+
193
+ // Prévisualisation
194
+ imageInput.addEventListener('change', function() {
195
+ const file = this.files[0];
196
+ if (file) {
197
+ const reader = new FileReader();
198
+ reader.onload = function(e) {
199
+ previewImage.src = e.target.result;
200
+ previewContainer.classList.remove('hidden');
201
+ }
202
+ reader.readAsDataURL(file);
203
+ } else {
204
+ previewContainer.classList.add('hidden');
205
+ }
206
+ });
207
+
208
+ // Gestion des onglets
209
+ dissertationTab.addEventListener('click', function() {
210
+ dissertationTab.classList.add('text-blue-600', 'border-b-2', 'border-blue-600');
211
+ tableauTab.classList.remove('text-blue-600', 'border-b-2', 'border-blue-600');
212
+ dissertationContent.classList.remove('hidden');
213
+ tableauContent.classList.add('hidden');
214
+ });
215
+
216
+ tableauTab.addEventListener('click', function() {
217
+ tableauTab.classList.add('text-blue-600', 'border-b-2', 'border-blue-600');
218
+ dissertationTab.classList.remove('text-blue-600', 'border-b-2', 'border-blue-600');
219
+ tableauContent.classList.remove('hidden');
220
+ dissertationContent.classList.add('hidden');
221
+ });
222
+
223
+ // Soumission du formulaire
224
+ uploadForm.addEventListener('submit', function(e) {
225
+ e.preventDefault();
226
+ loadingIndicator.classList.remove('hidden');
227
+ resultDiv.classList.add('hidden');
228
+
229
+ const formData = new FormData(uploadForm);
230
+
231
+ fetch('/analyze', {
232
+ method: 'POST',
233
+ body: formData
234
+ })
235
+ .then(response => response.json())
236
+ .then(data => {
237
+ loadingIndicator.classList.add('hidden');
238
+ if (data.error) {
239
+ throw new Error(data.error);
240
+ }
241
+
242
+ dissertationContent.innerHTML = marked.parse(data.dissertation);
243
+ // Injection du tableau dans le conteneur overflow-x-auto
244
+ tableauContent.querySelector('.overflow-x-auto').innerHTML = marked.parse(data.tableau);
245
+
246
+ resultDiv.classList.remove('hidden');
247
+ // Afficher l'onglet dissertation par défaut
248
+ dissertationTab.click();
249
+
250
+ // Scroll vers les résultats
251
+ resultDiv.scrollIntoView({ behavior: 'smooth' });
252
+ })
253
+ .catch(error => {
254
+ loadingIndicator.classList.add('hidden');
255
+ alert("Une erreur est survenue : " + error.message);
256
+ });
257
+ });
258
+
259
+ // Animation douce pour les transitions
260
+ document.querySelectorAll('.fade-enter').forEach(element => {
261
+ element.classList.add('fade-enter-active');
262
+ setTimeout(() => {
263
+ element.classList.remove('fade-enter', 'fade-enter-active');
264
+ }, 300);
265
+ });
266
+ </script>
267
+ </body>
268
+ </html>