Docfile commited on
Commit
5212392
·
verified ·
1 Parent(s): b71fac7

Delete templates/index.html

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