Docfile commited on
Commit
9708b60
·
verified ·
1 Parent(s): 78cec43

Delete templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +0 -510
templates/index.html DELETED
@@ -1,510 +0,0 @@
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 - Assistant Français Intelligent</title>
7
- <!-- Tailwind CSS, Font Awesome, Marked et MathJax -->
8
- <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/tailwindcss/dist/tailwind.min.css">
9
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
10
- <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
11
- <script src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
12
-
13
- <style>
14
- @import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:wght@300;400;500;600;700&display=swap');
15
-
16
- body {
17
- font-family: 'Plus Jakarta Sans', sans-serif;
18
- background-color: #fafafa;
19
- }
20
-
21
- /* Effet de Glassmorphism */
22
- .glassmorphism {
23
- background: rgba(255, 255, 255, 0.95);
24
- backdrop-filter: blur(10px);
25
- border: 1px solid rgba(255, 255, 255, 0.3);
26
- }
27
-
28
- /* Effet hover sur les cartes */
29
- .card-hover {
30
- transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
31
- }
32
- .card-hover:hover {
33
- transform: translateY(-4px);
34
- box-shadow: 0 12px 24px rgba(0, 0, 0, 0.08);
35
- }
36
-
37
- /* Texte en dégradé */
38
- .gradient-text {
39
- background: linear-gradient(135deg, #1a365d 0%, #3182ce 100%);
40
- -webkit-background-clip: text;
41
- -webkit-text-fill-color: transparent;
42
- }
43
-
44
- /* Animation des points de chargement */
45
- .loading-dot {
46
- animation: bounce 1.4s infinite;
47
- }
48
- .loading-dot:nth-child(2) { animation-delay: 0.2s; }
49
- .loading-dot:nth-child(3) { animation-delay: 0.4s; }
50
- @keyframes bounce {
51
- 0%, 80%, 100% { transform: translateY(0); }
52
- 40% { transform: translateY(-6px); }
53
- }
54
-
55
- /* Bouton radio personnalisé */
56
- .custom-radio:checked + span {
57
- background: linear-gradient(135deg, #1a365d 0%, #3182ce 100%);
58
- color: white;
59
- }
60
-
61
- /* Styles pour les sauvegardes */
62
- .backup-item {
63
- cursor: pointer;
64
- }
65
- .backup-content {
66
- display: none;
67
- margin-top: 10px;
68
- }
69
- .backup-content-expanded {
70
- display: block;
71
- }
72
-
73
- /* Prévisualisation d'images */
74
- .image-preview {
75
- display: flex;
76
- flex-wrap: wrap;
77
- gap: 10px;
78
- margin-top: 10px;
79
- }
80
- .image-preview-item {
81
- position: relative;
82
- width: 100px;
83
- height: 100px;
84
- }
85
- .image-preview-item img {
86
- width: 100%;
87
- height: 100%;
88
- object-fit: cover;
89
- border-radius: 5px;
90
- }
91
- .remove-image {
92
- position: absolute;
93
- top: 5px;
94
- right: 5px;
95
- background-color: rgba(0, 0, 0, 0.5);
96
- color: white;
97
- border: none;
98
- border-radius: 50%;
99
- padding: 2px 6px;
100
- cursor: pointer;
101
- font-size: 12px;
102
- }
103
- .remove-image:hover {
104
- background-color: rgba(0, 0, 0, 0.7);
105
- }
106
-
107
- /* Préserver les espaces dans le markdown */
108
- .prose {
109
- white-space: pre-wrap;
110
- word-wrap: break-word;
111
- overflow-wrap: break-word;
112
- }
113
- @media (max-width: 640px) {
114
- .prose {
115
- font-size: 0.95rem;
116
- line-height: 1.6;
117
- }
118
- }
119
- </style>
120
- </head>
121
- <body class="min-h-screen bg-gradient-to-br from-blue-50 via-white to-blue-50">
122
- <header>
123
- <nav class="glassmorphism sticky top-0 z-50 border-b border-blue-100">
124
- <div class="container mx-auto px-6 py-4">
125
- <div class="flex items-center justify-between">
126
- <div class="flex items-center space-x-4">
127
- <div class="bg-blue-600 rounded-lg p-2 shadow-lg">
128
- <i class="fas fa-robot text-white text-xl"></i>
129
- </div>
130
- <h1 class="text-2xl font-bold gradient-text">Mariam AI</h1>
131
- </div>
132
- <div class="text-blue-900 font-medium">Assistant Français Intelligent</div>
133
- </div>
134
- </div>
135
- </nav>
136
- </header>
137
-
138
- <main class="container mx-auto px-6 py-12">
139
- <div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
140
- <!-- Section Travail Argumentatif -->
141
- <section class="card-hover glassmorphism rounded-2xl overflow-hidden">
142
- <div class="p-8">
143
- <div class="flex items-center space-x-4 mb-8">
144
- <div class="bg-blue-100 rounded-lg p-3">
145
- <i class="fas fa-pen-fancy text-blue-600 text-xl"></i>
146
- </div>
147
- <h2 class="text-2xl font-bold text-gray-800">Travail Argumentatif</h2>
148
- </div>
149
- <form id="francais-form" class="space-y-8">
150
- <div class="space-y-3">
151
- <label for="sujet-francais" class="block text-sm font-medium text-gray-700">
152
- <i class="fas fa-book-open mr-2 text-blue-500"></i>Sujet
153
- </label>
154
- <textarea id="sujet-francais" name="sujet" rows="4" class="w-full px-4 py-3 rounded-xl border-2 border-gray-200 focus:border-blue-500 focus:ring-2 focus:ring-blue-200 transition-all duration-200 resize-none" placeholder="Entrez votre sujet ici..."></textarea>
155
- </div>
156
-
157
- <div class="space-y-4">
158
- <label class="block text-sm font-medium text-gray-700">
159
- <i class="fas fa-tasks mr-2 text-blue-500"></i>Type d'argumentation
160
- </label>
161
- <div class="grid grid-cols-3 gap-4">
162
- <label class="relative">
163
- <input type="radio" name="choix" value="Etaye" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer" checked>
164
- <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">Étayer</span>
165
- </label>
166
- <label class="relative">
167
- <input type="radio" name="choix" value="refute" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer">
168
- <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">Réfuter</span>
169
- </label>
170
- <label class="relative">
171
- <input type="radio" name="choix" value="discuter" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer">
172
- <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">Discuter</span>
173
- </label>
174
- </div>
175
- </div>
176
-
177
- <div class="space-y-4">
178
- <label class="block text-sm font-medium text-gray-700">
179
- <i class="fas fa-feather-alt mr-2 text-blue-500"></i>Style d'écriture
180
- </label>
181
- <div class="grid grid-cols-2 gap-4">
182
- <label class="relative">
183
- <input type="radio" name="style" value="raffiné" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer" checked>
184
- <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">Raffiné</span>
185
- </label>
186
- <label class="relative">
187
- <input type="radio" name="style" value="Normal" class="custom-radio absolute opacity-0 w-full h-full cursor-pointer">
188
- <span class="flex items-center justify-center p-3 border-2 border-gray-200 rounded-xl text-sm font-medium transition-all duration-200 hover:border-blue-400">Normal</span>
189
- </label>
190
- </div>
191
- </div>
192
-
193
- <button type="submit" class="w-full bg-gradient-to-r from-blue-600 to-blue-800 text-white px-6 py-4 rounded-xl font-medium hover:from-blue-700 hover:to-blue-900 transition-all duration-300 transform hover:scale-[1.02] active:scale-[0.98] shadow-lg">
194
- <div class="flex items-center justify-center space-x-3">
195
- <i class="fas fa-magic"></i>
196
- <span>Générer</span>
197
- </div>
198
- </button>
199
- </form>
200
- <div id="francais-output" class="mt-8 p-6 bg-blue-50 rounded-xl prose max-w-none">
201
- <!-- Le contenu généré sera inséré ici -->
202
- </div>
203
- </div>
204
- </section>
205
-
206
- <!-- Section Étude de texte -->
207
- <section class="card-hover glassmorphism rounded-2xl overflow-hidden">
208
- <div class="p-8">
209
- <div class="flex items-center space-x-4 mb-8">
210
- <div class="bg-blue-100 rounded-lg p-3">
211
- <i class="fas fa-file-alt text-blue-600 text-xl"></i>
212
- </div>
213
- <h2 class="text-2xl font-bold text-gray-800">Étude de texte</h2>
214
- </div>
215
- <form id="etude-texte-form" class="space-y-8" enctype="multipart/form-data">
216
- <div class="space-y-4">
217
- <label class="block text-sm font-medium text-gray-700">
218
- <i class="fas fa-image mr-2 text-blue-500"></i>Image du texte
219
- </label>
220
- <div class="border-3 border-dashed border-gray-300 rounded-xl p-8 text-center cursor-pointer hover:border-blue-400 transition-all duration-200" id="drop-zone">
221
- <input type="file" id="image-upload" name="images" accept="image/*" class="hidden" multiple>
222
- <div class="space-y-3">
223
- <div class="bg-blue-50 rounded-full w-16 h-16 flex items-center justify-center mx-auto">
224
- <i class="fas fa-cloud-upload-alt text-3xl text-blue-500"></i>
225
- </div>
226
- <p class="text-sm text-gray-600 font-medium">Glissez vos images ici ou cliquez pour sélectionner</p>
227
- <p class="text-xs text-gray-400">PNG, JPG jusqu'à 10MB</p>
228
- </div>
229
- </div>
230
- <div id="image-preview" class="image-preview"></div>
231
- </div>
232
-
233
- <button type="submit" class="w-full bg-gradient-to-r from-blue-600 to-blue-800 text-white px-6 py-4 rounded-xl font-medium hover:from-blue-700 hover:to-blue-900 transition-all duration-300 transform hover:scale-[1.02] active:scale-[0.98] shadow-lg">
234
- <div class="flex items-center justify-center space-x-3">
235
- <i class="fas fa-search"></i>
236
- <span>Analyser</span>
237
- </div>
238
- </button>
239
- </form>
240
- <div id="etude-texte-output" class="mt-8 p-6 bg-blue-50 rounded-xl prose max-w-none">
241
- <!-- Le contenu analysé sera inséré ici -->
242
- </div>
243
- </div>
244
- </section>
245
- </div>
246
-
247
- <!-- Section Sauvegardes -->
248
- <section class="mt-12">
249
- <h2 class="text-2xl font-bold text-gray-800 mb-4">Sauvegardes</h2>
250
- <div id="backups-list" class="space-y-4">
251
- <!-- Les sauvegardes seront listées ici -->
252
- </div>
253
- </section>
254
- </main>
255
-
256
- <script>
257
- // Gestion de l'upload d'images
258
- function initializeFileUpload() {
259
- const dropZone = document.getElementById('drop-zone');
260
- const fileInput = document.getElementById('image-upload');
261
- const imagePreview = document.getElementById('image-preview');
262
-
263
- dropZone.addEventListener('click', () => fileInput.click());
264
-
265
- ['dragenter', 'dragover'].forEach(eventName => {
266
- dropZone.addEventListener(eventName, (e) => {
267
- e.preventDefault();
268
- dropZone.classList.add('border-blue-500', 'bg-blue-50');
269
- });
270
- });
271
-
272
- ['dragleave', 'drop'].forEach(eventName => {
273
- dropZone.addEventListener(eventName, (e) => {
274
- e.preventDefault();
275
- dropZone.classList.remove('border-blue-500', 'bg-blue-50');
276
- });
277
- });
278
-
279
- dropZone.addEventListener('drop', (e) => {
280
- e.preventDefault();
281
- const files = e.dataTransfer.files;
282
- handleFiles(files);
283
- });
284
-
285
- fileInput.addEventListener('change', () => {
286
- handleFiles(fileInput.files);
287
- });
288
-
289
- function handleFiles(files) {
290
- Array.from(files).forEach(file => {
291
- if (!file.type.startsWith('image/')) return;
292
- const reader = new FileReader();
293
- reader.onload = (e) => {
294
- const previewItem = document.createElement('div');
295
- previewItem.classList.add('image-preview-item');
296
- previewItem.innerHTML = `
297
- <img src="${e.target.result}" alt="${file.name}">
298
- <button class="remove-image" title="Supprimer">×</button>
299
- `;
300
- imagePreview.appendChild(previewItem);
301
- previewItem.querySelector('.remove-image').addEventListener('click', () => {
302
- imagePreview.removeChild(previewItem);
303
- });
304
- };
305
- reader.readAsDataURL(file);
306
- });
307
- }
308
- }
309
-
310
- // Sauvegarde et affichage des réponses dans le localStorage
311
- function sauvegarderReponse(titre, contenu) {
312
- const sauvegardes = JSON.parse(localStorage.getItem('mariam_ai_sauvegardes') || '[]');
313
- const dateSauvegarde = new Date().toISOString();
314
- sauvegardes.push({ titre, contenu, date: dateSauvegarde });
315
- localStorage.setItem('mariam_ai_sauvegardes', JSON.stringify(sauvegardes));
316
- afficherSauvegardes();
317
- }
318
-
319
- function supprimerSauvegarde(index) {
320
- let sauvegardes = JSON.parse(localStorage.getItem('mariam_ai_sauvegardes') || '[]');
321
- sauvegardes.splice(index, 1);
322
- localStorage.setItem('mariam_ai_sauvegardes', JSON.stringify(sauvegardes));
323
- afficherSauvegardes();
324
- }
325
-
326
- function afficherSauvegardes() {
327
- const sauvegardes = JSON.parse(localStorage.getItem('mariam_ai_sauvegardes') || '[]');
328
- const backupsList = document.getElementById('backups-list');
329
- backupsList.innerHTML = sauvegardes.length === 0
330
- ? '<p class="text-gray-600">Aucune sauvegarde pour le moment.</p>'
331
- : '';
332
-
333
- sauvegardes.forEach((sauvegarde, index) => {
334
- const sauvegardeDiv = document.createElement('div');
335
- sauvegardeDiv.className = 'bg-white rounded-lg shadow-md p-4 relative backup-item';
336
- sauvegardeDiv.innerHTML = `
337
- <h3 class="text-lg font-semibold text-gray-800">${sauvegarde.titre}</h3>
338
- <p class="text-sm text-gray-600 mb-2">${new Date(sauvegarde.date).toLocaleString()}</p>
339
- <div class="text-sm text-gray-700 backup-content prose max-w-none">${marked.parse(sauvegarde.contenu)}</div>
340
- <button class="absolute top-2 right-2 text-red-500 hover:text-red-700 focus:outline-none" data-index="${index}">
341
- <i class="fas fa-trash"></i>
342
- </button>
343
- `;
344
- backupsList.appendChild(sauvegardeDiv);
345
-
346
- // Toggle du contenu lors d'un clic sur la sauvegarde (hors bouton de suppression)
347
- const backupContentDiv = sauvegardeDiv.querySelector('.backup-content');
348
- sauvegardeDiv.addEventListener('click', (e) => {
349
- if (e.target.tagName === "BUTTON") return;
350
- backupContentDiv.classList.toggle('backup-content-expanded');
351
- MathJax.typesetPromise([backupContentDiv]);
352
- });
353
-
354
- sauvegardeDiv.querySelector('button').addEventListener('click', () => {
355
- if (confirm('Êtes-vous sûr de vouloir supprimer cette sauvegarde ?')) {
356
- supprimerSauvegarde(index);
357
- }
358
- });
359
- });
360
- }
361
-
362
- // Gestion des formulaires
363
- function submitFrancaisForm() {
364
- const form = document.getElementById('francais-form');
365
- const output = document.getElementById('francais-output');
366
-
367
- form.addEventListener('submit', async (e) => {
368
- e.preventDefault();
369
- output.innerHTML = `
370
- <div class="flex items-center justify-center space-x-2 text-blue-600">
371
- <div class="loading-dot">[x]</div>
372
- <div class="loading-dot">[x]</div>
373
- <div class="loading-dot">[x]</div>
374
- <span class="ml-3 text-sm font-medium text-gray-600">Génération en cours...</span>
375
- </div>`;
376
-
377
- const formData = new FormData(form);
378
- try {
379
- const response = await fetch('/api/francais', { method: 'POST', body: formData });
380
- const result = await response.json();
381
- output.innerHTML = marked.parse(result.output);
382
- sauvegarderReponse(formData.get('sujet'), result.output);
383
- MathJax.typesetPromise([output]);
384
- } catch (error) {
385
- output.innerHTML = `
386
- <div class="flex items-center space-x-2 text-red-500 bg-red-50 p-4 rounded-lg">
387
- <i class="fas fa-exclamation-circle"></i>
388
- <span class="text-sm font-medium">Une erreur est survenue. Veuillez réessayer.</span>
389
- </div>`;
390
- }
391
- });
392
- }
393
-
394
- function submitEtudeTexteForm() {
395
- const form = document.getElementById('etude-texte-form');
396
- const output = document.getElementById('etude-texte-output');
397
-
398
- form.addEventListener('submit', async (e) => {
399
- e.preventDefault();
400
- output.innerHTML = `
401
- <div class="flex items-center justify-center space-x-2 text-blue-600">
402
- <div class="loading-dot">[x]</div>
403
- <div class="loading-dot">[x]</div>
404
- <div class="loading-dot">[x]</div>
405
- <span class="ml-3 text-sm font-medium text-gray-600">Analyse en cours...</span>
406
- </div>`;
407
-
408
- const formData = new FormData(form);
409
- try {
410
- const response = await fetch('/api/etude-texte', { method: 'POST', body: formData });
411
- const result = await response.json();
412
- output.innerHTML = marked.parse(result.output);
413
- const titre = "Analyse d'image " + new Date().toLocaleString();
414
- sauvegarderReponse(titre, result.output);
415
- MathJax.typesetPromise([output]);
416
- } catch (error) {
417
- output.innerHTML = `
418
- <div class="flex items-center space-x-2 text-red-500 bg-red-50 p-4 rounded-lg">
419
- <i class="fas fa-exclamation-circle"></i>
420
- <span class="text-sm font-medium">Une erreur est survenue. Veuillez réessayer.</span>
421
- </div>`;
422
- }
423
- });
424
- }
425
-
426
- // Effets d'animation et d'interaction
427
- function animateOnScroll() {
428
- const cards = document.querySelectorAll('.card-hover');
429
- const observer = new IntersectionObserver((entries) => {
430
- entries.forEach(entry => {
431
- if (entry.isIntersecting) {
432
- entry.target.style.opacity = '1';
433
- entry.target.style.transform = 'translateY(0)';
434
- }
435
- });
436
- }, { threshold: 0.1 });
437
-
438
- cards.forEach(card => {
439
- card.style.opacity = '0';
440
- card.style.transform = 'translateY(20px)';
441
- card.style.transition = 'all 0.6s cubic-bezier(0.4, 0, 0.2, 1)';
442
- observer.observe(card);
443
- });
444
- }
445
-
446
- function enhanceTextareaFocus() {
447
- document.querySelectorAll('textarea').forEach(textarea => {
448
- textarea.addEventListener('focus', () => {
449
- textarea.parentElement.classList.add('ring-2', 'ring-blue-200');
450
- });
451
- textarea.addEventListener('blur', () => {
452
- textarea.parentElement.classList.remove('ring-2', 'ring-blue-200');
453
- });
454
- });
455
- }
456
-
457
- function enhanceRadioButtons() {
458
- document.querySelectorAll('input[type="radio"] + span').forEach(label => {
459
- label.addEventListener('mouseenter', () => {
460
- if (!label.previousElementSibling.checked) {
461
- label.style.borderColor = '#3182ce';
462
- }
463
- });
464
- label.addEventListener('mouseleave', () => {
465
- if (!label.previousElementSibling.checked) {
466
- label.style.borderColor = '#e5e7eb';
467
- }
468
- });
469
- });
470
- }
471
-
472
- // Message de bienvenue (optionnel)
473
- function showWelcomeMessage() {
474
- const welcomeMessage = document.createElement('div');
475
- welcomeMessage.innerHTML = `
476
- <div class="fixed bottom-6 right-6 bg-white rounded-xl shadow-lg p-4 transform transition-all duration-500 opacity-0 translate-y-4">
477
- <div class="flex items-center space-x-3">
478
- <div class="bg-blue-100 rounded-lg p-2">
479
- <i class="fas fa-robot text-blue-600"></i>
480
- </div>
481
- <div>
482
- <p class="text-sm font-medium text-gray-800">Bienvenue sur Mariam AI</p>
483
- <p class="text-xs text-gray-500">Je suis là pour vous aider</p>
484
- </div>
485
- </div>
486
- </div>`;
487
- document.body.appendChild(welcomeMessage);
488
- setTimeout(() => {
489
- welcomeMessage.firstElementChild.classList.remove('opacity-0', 'translate-y-4');
490
- }, 1000);
491
- setTimeout(() => {
492
- welcomeMessage.firstElementChild.classList.add('opacity-0', 'translate-y-4');
493
- setTimeout(() => welcomeMessage.remove(), 500);
494
- }, 5000);
495
- }
496
-
497
- // Initialisation au chargement du DOM
498
- document.addEventListener('DOMContentLoaded', () => {
499
- initializeFileUpload();
500
- submitFrancaisForm();
501
- submitEtudeTexteForm();
502
- animateOnScroll();
503
- enhanceTextareaFocus();
504
- enhanceRadioButtons();
505
- showWelcomeMessage();
506
- afficherSauvegardes();
507
- });
508
- </script>
509
- </body>
510
- </html>