Docfile commited on
Commit
bbc7bc4
·
verified ·
1 Parent(s): 66bd406

Update templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +775 -752
templates/index.html CHANGED
@@ -1,4 +1,6 @@
 
1
  <!DOCTYPE html>
 
2
  <html lang="fr">
3
  <head>
4
  <meta charset="UTF-8">
@@ -34,188 +36,189 @@
34
  <style>
35
  @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
36
 
37
- body {
38
- font-family: 'Poppins', sans-serif;
39
- background-color: #f8fafc;
40
- }
41
-
42
- .flashcard {
43
- perspective: 1000px;
44
- height: 220px;
45
- }
46
-
47
- .flashcard-inner {
48
- position: relative;
49
- width: 100%;
50
- height: 100%;
51
- transition: transform 0.8s;
52
- transform-style: preserve-3d;
53
- }
54
-
55
- .flashcard.flipped .flashcard-inner {
56
- transform: rotateY(180deg);
57
- }
58
-
59
- .flashcard-front, .flashcard-back {
60
- position: absolute;
61
- width: 100%;
62
- height: 100%;
63
- -webkit-backface-visibility: hidden;
64
- backface-visibility: hidden;
65
- display: flex;
66
- align-items: center;
67
- justify-content: center;
68
- border-radius: 0.5rem;
69
- padding: 1.5rem;
70
- box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
71
- }
72
-
73
- .flashcard-front {
74
- background-color: #ffffff;
75
- color: #1e293b;
76
- border-left: 5px solid #0ea5e9;
77
- }
78
-
79
- .flashcard-back {
80
- background-color: #0ea5e9;
81
- color: white;
82
- transform: rotateY(180deg);
83
- }
84
-
85
- .quiz-option {
86
- position: relative;
87
- padding-left: 2.5rem;
88
- }
89
-
90
- .quiz-option input[type="radio"] {
91
- position: absolute;
92
- opacity: 0;
93
- }
94
-
95
- .quiz-option label {
96
- display: block;
97
- position: relative;
98
- padding: 1rem 1.5rem 1rem 2.5rem;
99
- cursor: pointer;
100
- border: 1px solid #e2e8f0;
101
- border-radius: 0.5rem;
102
- transition: all 0.3s ease;
103
- }
104
-
105
- .quiz-option label:before {
106
- content: '';
107
- position: absolute;
108
- left: 1rem;
109
- top: 50%;
110
- transform: translateY(-50%);
111
- width: 1.25rem;
112
- height: 1.25rem;
113
- border-radius: 50%;
114
- border: 2px solid #cbd5e1;
115
- transition: all 0.3s ease;
116
- }
117
-
118
- .quiz-option input[type="radio"]:checked + label {
119
- background-color: #e0f2fe;
120
- border-color: #0ea5e9;
121
- }
122
-
123
- .quiz-option input[type="radio"]:checked + label:before {
124
- border-color: #0ea5e9;
125
- background-color: #0ea5e9;
126
- box-shadow: inset 0 0 0 4px #e0f2fe;
127
- }
128
-
129
- .quiz-option.correct input[type="radio"]:checked + label {
130
- background-color: #d1fae5;
131
- border-color: #10b981;
132
- }
133
-
134
- .quiz-option.correct input[type="radio"]:checked + label:before {
135
- border-color: #10b981;
136
- background-color: #10b981;
137
- box-shadow: inset 0 0 0 4px #d1fae5;
138
- }
139
-
140
- .quiz-option.incorrect input[type="radio"]:checked + label {
141
- background-color: #fee2e2;
142
- border-color: #ef4444;
143
- }
144
-
145
- .quiz-option.incorrect input[type="radio"]:checked + label:before {
146
- border-color: #ef4444;
147
- background-color: #ef4444;
148
- box-shadow: inset 0 0 0 4px #fee2e2;
149
- }
150
-
151
- .progress-bar-container {
152
- width: 100%;
153
- height: 8px;
154
- background-color: #e2e8f0;
155
- border-radius: 4px;
156
- overflow: hidden;
157
- }
158
-
159
- .progress-bar {
160
- height: 100%;
161
- background-color: #0ea5e9;
162
- transition: width 0.5s ease;
163
- }
164
-
165
- .floating-label {
166
- position: absolute;
167
- top: -10px;
168
- left: 10px;
169
- padding: 0 5px;
170
- background-color: white;
171
- transition: all 0.3s ease;
172
- pointer-events: none;
173
- }
174
-
175
- .pulse-animation {
176
- animation: pulse 2s infinite;
177
- }
178
-
179
- @keyframes pulse {
180
- 0% {
181
- box-shadow: 0 0 0 0 rgba(14, 165, 233, 0.4);
182
- }
183
- 70% {
184
- box-shadow: 0 0 0 10px rgba(14, 165, 233, 0);
185
- }
186
- 100% {
187
- box-shadow: 0 0 0 0 rgba(14, 165, 233, 0);
188
- }
189
- }
190
-
191
- .confetti {
192
- position: fixed;
193
- width: 10px;
194
- height: 10px;
195
- background-color: #f00;
 
 
 
 
 
 
 
 
 
 
 
196
  opacity: 0;
197
- animation: confetti-fall 3s linear forwards;
198
- }
199
-
200
- @keyframes confetti-fall {
201
- 0% {
202
- transform: translateY(0) rotate(0deg);
203
- opacity: 1;
204
- }
205
- 100% {
206
- transform: translateY(100vh) rotate(360deg);
207
- opacity: 0;
208
- }
209
  }
 
 
 
 
 
 
 
 
 
 
210
 
211
- .btn-primary {
212
- @apply bg-primary-600 text-white px-6 py-3 rounded-lg shadow-md hover:bg-primary-700 transition duration-300 ease-in-out transform hover:-translate-y-1 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-opacity-50;
213
- }
214
-
215
- .btn-secondary {
216
- @apply bg-white text-primary-600 border border-primary-600 px-6 py-3 rounded-lg shadow-md hover:bg-primary-50 transition duration-300 ease-in-out transform hover:-translate-y-1 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-opacity-50;
217
- }
218
- </style>
219
  </head>
220
  <body>
221
  <div class="min-h-screen bg-gradient-to-b from-primary-50 to-white">
@@ -238,297 +241,293 @@
238
  </div>
239
  </header>
240
 
241
- <main class="container mx-auto px-4 py-8">
242
- <div class="max-w-3xl mx-auto">
243
- <!-- Introduction -->
244
- <div class="text-center mb-8">
245
- <h2 class="text-4xl font-bold text-gray-800 mb-4">Apprenez plus efficacement</h2>
246
- <p class="text-lg text-gray-600 mb-6">Créez des flashcards ou des quiz pour mémoriser n'importe quel sujet</p>
247
- </div>
248
-
249
- <!-- Section de configuration -->
250
- <div class="bg-white rounded-xl shadow-lg p-8 mb-10 relative overflow-hidden">
251
- <div class="absolute top-0 right-0 w-40 h-40 bg-primary-100 rounded-full -mr-20 -mt-20 z-0"></div>
252
- <div class="absolute bottom-0 left-0 w-24 h-24 bg-primary-100 rounded-full -ml-12 -mb-12 z-0"></div>
253
-
254
- <div class="relative z-10">
255
- <h3 class="text-2xl font-semibold text-gray-800 mb-6">Que souhaitez-vous apprendre aujourd'hui ?</h3>
256
-
257
- <div class="space-y-6">
258
- <div class="relative">
259
- <input type="text" id="topic" class="w-full px-4 py-3 border-2 border-gray-300 rounded-lg focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 transition-all duration-300 pl-10" placeholder="Entrez un sujet...">
260
- <i class="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
261
- <div class="text-xs text-gray-500 mt-1 ml-2">Exemples: "Capitales du monde", "Photosynthèse", "Verbes irréguliers en anglais"</div>
262
- </div>
263
-
264
- <div>
265
- <p class="text-gray-700 font-medium mb-3">Choisissez votre méthode d'apprentissage :</p>
266
- <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
267
- <div class="relative">
268
- <input type="radio" id="typeFlashcards" name="contentType" value="flashcards" checked class="peer absolute opacity-0">
269
- <label for="typeFlashcards" class="flex flex-col items-center justify-center p-4 border-2 border-gray-200 rounded-lg cursor-pointer transition-all duration-300 hover:bg-gray-50 peer-checked:border-primary-500 peer-checked:bg-primary-50">
270
- <div class="w-12 h-12 rounded-full bg-primary-100 flex items-center justify-center mb-3">
271
- <i class="fas fa-clone text-xl text-primary-600"></i>
272
- </div>
273
- <h4 class="font-semibold text-gray-800">Flashcards</h4>
274
- <p class="text-sm text-gray-600 text-center mt-2">Pour mémoriser des informations par répétition</p>
275
- </label>
276
- </div>
277
-
278
- <div class="relative">
279
- <input type="radio" id="typeQuiz" name="contentType" value="quiz" class="peer absolute opacity-0">
280
- <label for="typeQuiz" class="flex flex-col items-center justify-center p-4 border-2 border-gray-200 rounded-lg cursor-pointer transition-all duration-300 hover:bg-gray-50 peer-checked:border-primary-500 peer-checked:bg-primary-50">
281
- <div class="w-12 h-12 rounded-full bg-primary-100 flex items-center justify-center mb-3">
282
- <i class="fas fa-question text-xl text-primary-600"></i>
283
- </div>
284
- <h4 class="font-semibold text-gray-800">Quiz</h4>
285
- <p class="text-sm text-gray-600 text-center mt-2">Pour tester vos connaissances avec des QCM</p>
286
- </label>
287
- </div>
288
  </div>
289
- </div>
290
-
291
- <div class="flex items-center justify-between pt-2">
292
- <div class="text-sm text-gray-500 italic">
293
- <i class="fas fa-info-circle mr-1"></i> La génération peut prendre jusqu'à 1 minute
 
 
 
 
 
294
  </div>
295
- <button id="generateBtn" class="btn-primary flex items-center">
296
- <span class="mr-2">Générer</span>
297
- <i class="fas fa-chevron-right"></i>
298
- </button>
299
  </div>
300
  </div>
 
 
 
 
 
 
 
 
 
 
301
  </div>
302
  </div>
 
303
 
304
- <!-- Indicateur de chargement -->
305
- <div id="loading" class="hidden">
306
- <div class="bg-white rounded-xl shadow-lg p-8 text-center">
307
- <div class="flex flex-col items-center justify-center space-y-4">
308
- <div class="relative w-24 h-24">
309
- <div class="absolute inset-0 border-4 border-primary-100 border-t-primary-500 rounded-full animate-spin"></div>
310
- <div class="absolute inset-0 flex items-center justify-center">
311
- <i class="fas fa-lightbulb text-2xl text-primary-500 animate-pulse"></i>
312
- </div>
313
  </div>
314
- <h3 class="text-xl font-semibold text-gray-800">Création en cours...</h3>
315
- <p class="text-gray-600">Nous élaborons votre contenu d'apprentissage personnalisé</p>
316
-
317
- <div class="w-full max-w-md mt-4">
318
- <div class="progress-bar-container">
319
- <div id="progressBar" class="progress-bar" style="width: 0%"></div>
320
- </div>
321
- <div id="loadingSteps" class="mt-8 text-left">
322
- <div class="flex items-center mb-3">
323
- <div class="w-6 h-6 rounded-full bg-primary-500 flex items-center justify-center mr-3">
324
- <i class="fas fa-check text-white text-xs"></i>
325
- </div>
326
- <span class="text-sm text-gray-700">Analyse du sujet</span>
327
  </div>
328
- <div class="flex items-center mb-3">
329
- <div id="step2" class="w-6 h-6 rounded-full bg-gray-200 flex items-center justify-center mr-3">
330
- <i class="fas fa-spinner text-white text-xs animate-spin"></i>
331
- </div>
332
- <span class="text-sm text-gray-500">Recherche d'informations</span>
333
  </div>
334
- <div class="flex items-center mb-3">
335
- <div id="step3" class="w-6 h-6 rounded-full bg-gray-200 flex items-center justify-center mr-3">
336
- <i class="fas fa-hourglass text-white text-xs"></i>
337
- </div>
338
- <span class="text-sm text-gray-500">Création du contenu</span>
339
  </div>
340
- <div class="flex items-center">
341
- <div id="step4" class="w-6 h-6 rounded-full bg-gray-200 flex items-center justify-center mr-3">
342
- <i class="fas fa-hourglass text-white text-xs"></i>
343
- </div>
344
- <span class="text-sm text-gray-500">Finalisation</span>
345
  </div>
 
346
  </div>
347
  </div>
348
  </div>
349
  </div>
350
  </div>
 
351
 
352
- <!-- Conteneur pour les Flashcards -->
353
- <div id="flashcardsContainer" class="mt-8 hidden">
354
- <!-- Les flashcards seront injectées ici -->
355
- </div>
356
-
357
- <!-- Conteneur pour le Quiz -->
358
- <div id="quizContainer" class="mt-8 hidden">
359
- <!-- Les questions du quiz seront injectées ici -->
360
- </div>
361
  </div>
362
- </main>
363
 
364
- <footer class="hidden md:block bg-gray-900 text-white py-8 mt-20">
365
- <div class="container mx-auto px-4">
366
- <div class="flex flex-col md:flex-row justify-between items-center">
367
- <div class="mb-4 md:mb-0">
368
- <h2 class="text-xl font-bold flex items-center">
369
- <i class="fas fa-brain mr-2"></i> Mémorisation Facile
370
- </h2>
371
- <p class="text-gray-400 text-sm mt-2">Votre outil d'apprentissage intelligent</p>
372
- </div>
373
- <div class="flex space-x-4">
374
- <a href="#" class="text-gray-400 hover:text-white transition-colors"><i class="fab fa-twitter"></i></a>
375
- <a href="#" class="text-gray-400 hover:text-white transition-colors"><i class="fab fa-facebook"></i></a>
376
- <a href="#" class="text-gray-400 hover:text-white transition-colors"><i class="fab fa-instagram"></i></a>
377
- <a href="#" class="text-gray-400 hover:text-white transition-colors"><i class="fab fa-youtube"></i></a>
378
- </div>
379
  </div>
380
- <div class="mt-8 border-t border-gray-800 pt-6 text-sm text-gray-400 text-center">
381
- © 2025 Mémorisation Facile. Tous droits réservés.
 
 
 
382
  </div>
383
  </div>
384
- </footer>
385
- </div>
386
-
387
- <script>
388
- const generateBtn = document.getElementById('generateBtn');
389
- const loadingIndicator = document.getElementById('loading');
390
- const flashcardsContainer = document.getElementById('flashcardsContainer');
391
- const quizContainer = document.getElementById('quizContainer');
392
- const topicInput = document.getElementById('topic');
393
- const progressBar = document.getElementById('progressBar');
394
- const themeToggle = document.getElementById('themeToggle');
395
- const step2 = document.getElementById('step2');
396
- const step3 = document.getElementById('step3');
397
- const step4 = document.getElementById('step4');
398
-
399
- // Gestion du thème clair/sombre
400
- themeToggle.addEventListener('click', function() {
401
- document.body.classList.toggle('dark-mode');
402
- const icon = this.querySelector('i');
403
- if (icon.classList.contains('fa-moon')) {
404
- icon.classList.remove('fa-moon');
405
- icon.classList.add('fa-sun');
406
- } else {
407
- icon.classList.remove('fa-sun');
408
- icon.classList.add('fa-moon');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
409
  }
410
- });
411
-
412
- // Animation de chargement
413
- function simulateLoading() {
414
- let progress = 0;
415
- const interval = setInterval(() => {
416
- progress += 1;
417
- progressBar.style.width = `${progress}%`;
418
-
419
- if (progress === 25) {
420
- step2.classList.remove('bg-gray-200');
421
- step2.classList.add('bg-primary-500');
422
- step2.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
423
- } else if (progress === 60) {
424
- step3.classList.remove('bg-gray-200');
425
- step3.classList.add('bg-primary-500');
426
- step3.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
427
- step4.innerHTML = '<i class="fas fa-spinner text-white text-xs animate-spin"></i>';
428
- } else if (progress === 95) {
429
- step4.classList.remove('bg-gray-200');
430
- step4.classList.add('bg-primary-500');
431
- step4.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
432
- }
433
-
434
- if (progress >= 100) {
435
- clearInterval(interval);
436
- }
437
- }, 50);
438
-
439
- return interval;
440
- }
441
-
442
- // Fonction pour créer des confettis
443
- function createConfetti() {
444
- const confettiCount = 100;
445
- const colors = ['#0ea5e9', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6'];
446
-
447
- for (let i = 0; i < confettiCount; i++) {
448
- const confetti = document.createElement('div');
449
- confetti.className = 'confetti';
450
- confetti.style.left = `${Math.random() * 100}vw`;
451
- confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
452
- confetti.style.width = `${Math.random() * 10 + 5}px`;
453
- confetti.style.height = `${Math.random() * 10 + 5}px`;
454
- confetti.style.animationDuration = `${Math.random() * 3 + 2}s`;
455
- document.body.appendChild(confetti);
456
-
457
- setTimeout(() => {
458
- confetti.remove();
459
- }, 5000);
460
  }
461
- }
462
-
463
- // Gestion des flashcards
464
- function flipCard(card) {
465
- card.classList.toggle('flipped');
466
- }
467
-
468
- generateBtn.addEventListener('click', function() {
469
- const topic = topicInput.value.trim();
470
- if (!topic) {
471
- // Animation de secouement sur l'input
472
- topicInput.classList.add('border-red-500');
473
- topicInput.classList.add('animate-bounce');
474
- setTimeout(() => {
475
- topicInput.classList.remove('animate-bounce');
476
- topicInput.classList.remove('border-red-500');
477
- }, 1000);
478
-
479
- // Afficher un message d'erreur
480
- const errorMsg = document.createElement('div');
481
- errorMsg.className = 'text-red-500 text-sm mt-1 ml-2';
482
- errorMsg.textContent = 'Veuillez entrer un sujet';
483
- topicInput.parentElement.appendChild(errorMsg);
484
- setTimeout(() => {
485
- errorMsg.remove();
486
- }, 3000);
487
-
488
- return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
489
  }
490
-
491
- const contentType = document.querySelector('input[name="contentType"]:checked').value;
492
-
493
- // Afficher le chargement et cacher les anciens résultats
494
- loadingIndicator.classList.remove('hidden');
495
- flashcardsContainer.classList.add('hidden');
496
- quizContainer.classList.add('hidden');
497
- flashcardsContainer.innerHTML = '';
498
- quizContainer.innerHTML = '';
499
-
500
- // Simuler l'animation de chargement
501
- const loadingInterval = simulateLoading();
502
-
503
- // Envoi de la requête (REMPLACER CETTE PARTIE PAR VOTRE VRAIE LOGIQUE D'APPEL API)
504
- // Ici, nous simulons une réponse après un délai
505
  setTimeout(() => {
506
- // Exemple de données de réponse (remplacez par la vraie réponse de votre API)
507
- const fakeData = {
508
- flashcards: contentType === 'flashcards' ? [
509
- { question: "Quelle est la capitale de la France ?", answer: "Paris" },
510
- { question: "Quel est le plus grand océan ?", answer: "Océan Pacifique" },
511
- { question: "Combien y a-t-il de continents ?", answer: "7" },
512
- { question: "Quel gaz les plantes absorbent-elles ?", answer: "Dioxyde de carbone (CO2)" },
513
- { question: "Qui a peint la Joconde ?", answer: "Léonard de Vinci" },
514
- { question: "Quelle est la planète la plus proche du soleil ?", answer: "Mercure" }
515
- ] : null,
516
- quiz: contentType === 'quiz' ? [
517
- { question: "Quelle est la capitale de l'Italie ?", options: ["Rome", "Paris", "Madrid", "Berlin"], correctAnswer: "Rome", explanation: "Rome est la capitale et la plus grande ville d'Italie." },
518
- { question: "Quel est le fleuve le plus long du monde ?", options: ["Nil", "Amazone", "Mississippi", "Yangtsé"], correctAnswer: "Nil", explanation: "Le Nil est traditionnellement considéré comme le plus long fleuve du monde, bien que certaines études récentes suggèrent que l'Amazone pourrait être légèrement plus long." },
519
- { question: "En quelle année l'homme a-t-il marché sur la Lune pour la première fois ?", options: ["1969", "1972", "1965", "1980"], correctAnswer: "1969", explanation: "Neil Armstrong a été le premier homme à marcher sur la Lune le 20 juillet 1969, lors de la mission Apollo 11." },
520
- { question: "Quel est le symbole chimique de l'or ?", options: ["Ag", "Au", "O", "Fe"], correctAnswer: "Au", explanation: "Le symbole chimique de l'or est Au, dérivé du mot latin 'aurum'." }
521
- ] : null
522
- };
523
-
524
- // Fin de la simulation de requête
525
  clearInterval(loadingInterval);
526
  progressBar.style.width = '100%';
527
-
528
  setTimeout(() => {
529
  loadingIndicator.classList.add('hidden');
530
-
531
- if (fakeData.error) { // Gérer une éventuelle erreur de l'API
 
532
  const errorContainer = document.createElement('div');
533
  errorContainer.className = 'bg-red-50 border-l-4 border-red-500 p-4 rounded-md mt-4';
534
  errorContainer.innerHTML = `
@@ -538,7 +537,7 @@
538
  </div>
539
  <div class="ml-3">
540
  <p class="text-sm text-red-700">
541
- ${fakeData.error}
542
  </p>
543
  </div>
544
  </div>
@@ -547,25 +546,28 @@
547
  return;
548
  }
549
 
550
- if (contentType === 'flashcards' && fakeData.flashcards) {
551
  flashcardsContainer.classList.remove('hidden');
552
- displayFlashcards(fakeData.flashcards);
 
553
  createConfetti();
554
- } else if (contentType === 'quiz' && fakeData.quiz) {
555
  quizContainer.classList.remove('hidden');
556
- displayQuiz(fakeData.quiz);
 
557
  createConfetti();
558
  } else {
 
559
  const errorContainer = document.createElement('div');
560
- errorContainer.className = 'bg-yellow-50 border-l-4 border-yellow-500 p-4 rounded-md mt-4';
561
  errorContainer.innerHTML = `
562
  <div class="flex">
563
  <div class="flex-shrink-0">
564
- <i class="fas fa-info-circle text-yellow-500"></i>
565
  </div>
566
  <div class="ml-3">
567
- <p class="text-sm text-yellow-700">
568
- Impossible de générer le contenu pour ce sujet ou ce type. Essayez un autre sujet.
569
  </p>
570
  </div>
571
  </div>
@@ -573,337 +575,358 @@
573
  document.querySelector('.max-w-3xl').appendChild(errorContainer);
574
  }
575
  }, 500);
576
- }, 3000); // Simule un délai de 3 secondes pour la génération
577
- });
578
-
579
-
580
- function displayFlashcards(flashcards) {
581
- const header = document.createElement('div');
582
- header.className = 'mb-8 text-center';
583
- header.innerHTML = `
584
- <h2 class="text-3xl font-bold text-gray-800 mb-2">Vos Flashcards (${flashcards.length})</h2>
585
- <p>Cliquez sur une carte pour la retourner et voir la réponse.</p>
586
- <p class="text-gray-600">
587
- <i class="far fa-lightbulb mr-1"></i> Astuce : Essayez de répondre mentalement avant de retourner la carte
 
 
 
 
 
 
588
  </p>
589
- <p><div class="flex items-center justify-center space-x-4 mt-6">
590
- </div></p>
591
-
592
  `;
593
- flashcardsContainer.appendChild(header);
594
-
595
- const flashcardsGrid = document.createElement('div');
596
- flashcardsGrid.className = 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6';
597
- flashcardsContainer.appendChild(flashcardsGrid);
598
-
599
- flashcards.forEach((card, index) => {
600
- const cardElement = document.createElement('div');
601
- cardElement.className = 'flashcard cursor-pointer';
602
- cardElement.onclick = function() { flipCard(this); };
603
- cardElement.innerHTML = `
604
- <div class="flashcard-inner">
605
- <div class="flashcard-front">
606
- <div class="w-full">
607
- <div class="absolute top-2 left-2 text-xs text-gray-400">#${index + 1}</div>
608
- <h3 class="text-lg font-semibold mb-2 text-center">${card.question}</h3>
609
- <div class="text-center mt-4">
610
- <span class="text-xs text-gray-500">Cliquez pour voir la réponse</span>
611
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
612
  </div>
613
  </div>
614
-
615
- <div class="flashcard-back">
616
- <div class="w-full">
617
- <div class="absolute top-2 right-2 text-xs text-white opacity-70">#${index + 1}</div>
618
- <div class="text-center">
619
- <p class="font-medium">${card.answer}</p>
620
- </div>
621
- <div class="absolute bottom-2 right-2">
622
- <span class="text-xs text-white opacity-70">Cliquez pour retourner</span>
623
- </div>
624
  </div>
625
  </div>
626
  </div>
627
- `;
628
- flashcardsGrid.appendChild(cardElement);
629
- });
630
-
631
- // Ajouter des boutons de navigation et de contrôle
632
- const controls = document.createElement('div');
633
- controls.className = 'mt-10 flex flex-col items-center justify-center';
634
- controls.innerHTML = `
635
- <div class="flex items-center space-x-4 mb-6">
636
- <button id="restartFlashcardsBtn" class="px-4 py-2 bg-primary-100 hover:bg-primary-200 text-primary-700 rounded-md transition duration-300 flex items-center">
637
- <i class="fas fa-redo-alt mr-2"></i> Recommencer
638
- </button>
639
- <button id="newTopicBtnFlashcards" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-md transition duration-300 flex items-center">
640
- <i class="fas fa-plus mr-2"></i> Nouveau sujet
641
- </button>
642
  </div>
643
-
644
  `;
645
- flashcardsContainer.appendChild(controls);
646
-
647
- // Ajouter des interactions aux boutons
648
- document.getElementById('restartFlashcardsBtn').addEventListener('click', function() {
649
- const allCards = flashcardsContainer.querySelectorAll('.flashcard.flipped');
650
- allCards.forEach(card => flipCard(card)); // Retourne toutes les cartes retournées
651
- window.scrollTo({
652
- top: flashcardsContainer.offsetTop - 80, // Ajustez le décalage si nécessaire
653
- behavior: 'smooth'
654
- });
655
- });
656
-
657
-
658
- document.getElementById('newTopicBtnFlashcards').addEventListener('click', function() {
659
- window.scrollTo({
660
- top: 0,
661
- behavior: 'smooth'
662
- });
663
- topicInput.value = ''; // Efface le champ
664
- topicInput.focus();
665
- flashcardsContainer.classList.add('hidden'); // Cache les résultats actuels
666
- flashcardsContainer.innerHTML = ''; // Vide le conteneur
 
 
 
 
 
 
 
 
 
 
 
 
 
 
667
  });
668
- }
669
-
670
- function displayQuiz(quizQuestions) {
671
- const header = document.createElement('div');
672
- header.className = 'mb-8 text-center';
673
- header.innerHTML = `
674
- <h2 class="text-3xl font-bold text-gray-800 mb-2">Votre Quiz (${quizQuestions.length} questions)</h2>
675
- <p class="text-gray-600">Testez vos connaissances en répondant aux questions</p>
676
- <div class="flex items-center justify-center mt-6">
677
- <div class="bg-white px-4 py-2 rounded-full shadow-sm flex items-center">
678
- <span class="text-primary-700 font-medium">Score: </span>
679
- <span id="score" class="ml-1 text-primary-700 font-bold">0</span>
680
- <span class="mx-1 text-gray-400">/</span>
681
- <span class="text-gray-600">${quizQuestions.length}</span>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
682
  </div>
 
 
 
 
 
 
 
 
 
683
  </div>
684
- `;
685
- quizContainer.appendChild(header);
686
-
687
- // Créer un conteneur pour les questions
688
- const questionsContainer = document.createElement('div');
689
- questionsContainer.className = 'space-y-8';
690
- quizContainer.appendChild(questionsContainer);
691
-
692
- // Variable pour suivre le score
693
- let currentScore = 0;
694
-
695
- quizQuestions.forEach((question, qIndex) => {
696
- const questionElement = document.createElement('div');
697
- questionElement.className = 'bg-white rounded-xl shadow-md p-6 transition-all duration-300';
698
- questionElement.setAttribute('id', `question-${qIndex}`);
699
-
700
- let optionsHtml = '';
701
- const safeCorrectAnswer = question.correctAnswer.replace(/"/g, '"');
702
-
703
- question.options.forEach((option, oIndex) => {
704
- optionsHtml += `
705
- <div class="quiz-option mb-3" id="option-${qIndex}-${oIndex}">
706
- <input type="radio" id="q${qIndex}-o${oIndex}" name="question-${qIndex}" value="${option}" data-correct="${safeCorrectAnswer}">
707
- <label for="q${qIndex}-o${oIndex}" class="group">
708
- ${option}
709
- <span class="hidden success-icon absolute right-4 text-green-500">
710
- <i class="fas fa-check-circle"></i>
711
- </span>
712
- <span class="hidden error-icon absolute right-4 text-red-500">
713
- <i class="fas fa-times-circle"></i>
714
- </span>
715
- </label>
716
  </div>
717
- `;
718
- });
719
-
720
- questionElement.innerHTML = `
721
- <div class="flex items-center justify-between mb-4">
722
- <span class="bg-primary-100 text-primary-800 text-xs font-medium px-2.5 py-0.5 rounded">Question ${qIndex + 1}/${quizQuestions.length}</span>
723
- <span class="text-gray-400 text-sm">
724
- <i class="far fa-lightbulb"></i>
725
- </span>
726
- </div>
727
- <h3 class="text-xl font-medium text-gray-800 mb-4">${question.question}</h3>
728
- <div class="options mt-5">
729
- ${optionsHtml}
730
- </div>
731
- <div class="explanation hidden mt-6 p-4 bg-blue-50 border border-blue-100 rounded-lg" id="explanation-${qIndex}">
732
- <div class="flex items-start">
733
- <div class="flex-shrink-0 mt-0.5">
734
- <i class="fas fa-info-circle text-blue-500"></i>
735
- </div>
736
- <div class="ml-3">
737
- <h4 class="text-sm font-medium text-blue-800">Explication</h4>
738
- <div class="mt-1 text-sm text-blue-700">${question.explanation}</div>
739
- </div>
740
  </div>
741
  </div>
742
- `;
743
- questionsContainer.appendChild(questionElement);
744
-
745
- // Ajouter des gestionnaires d'événements pour les options
746
- const options = questionElement.querySelectorAll('input[type="radio"]');
747
- options.forEach((option) => {
748
- option.addEventListener('change', function() {
749
- const optionId = this.id;
750
- const [_, qIdx, oIdx] = optionId.match(/q(\d+)-o(\d+)/);
751
- const selected = this.value;
752
- const correct = this.getAttribute('data-correct');
753
- const explanationElement = document.getElementById(`explanation-${qIdx}`);
754
- const questionDiv = document.getElementById(`question-${qIdx}`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
755
 
756
- // Vérifier si la question a déjà été répondue
757
- if (questionDiv.dataset.answered === 'true') {
758
- return;
 
759
  }
760
- questionDiv.dataset.answered = 'true'; // Marquer comme répondue
761
-
762
-
763
- // Vérifier la réponse
764
- let delay = 0; // Initialiser le délai
765
- if (selected === correct) {
766
- // Réponse correcte
767
- document.getElementById(`option-${qIdx}-${oIdx}`).classList.add('correct');
768
- currentScore++;
769
- document.getElementById('score').textContent = currentScore;
770
-
771
- // Afficher une animation de succès
772
- const successIcon = this.nextElementSibling.querySelector('.success-icon');
773
- successIcon.classList.remove('hidden');
774
- delay = 2000; // 2 secondes pour une réponse correcte
775
- } else {
776
- // Réponse incorrecte
777
- document.getElementById(`option-${qIdx}-${oIdx}`).classList.add('incorrect');
778
 
779
- // Afficher une animation d'erreur
780
- const errorIcon = this.nextElementSibling.querySelector('.error-icon');
781
- errorIcon.classList.remove('hidden');
782
 
783
- // Mettre en évidence la bonne réponse
784
- options.forEach((opt, idx) => {
785
- if (opt.value === correct) {
786
- document.getElementById(`option-${qIdx}-${idx}`).classList.add('correct');
787
- const successIconCorrect = opt.nextElementSibling.querySelector('.success-icon');
788
- if(successIconCorrect) successIconCorrect.classList.remove('hidden');
789
- }
790
  });
791
- delay = 5000; // 5 secondes pour une réponse incorrecte
792
- }
793
-
794
- // Désactiver toutes les options pour cette question
795
- options.forEach((opt) => {
796
- opt.disabled = true;
797
- });
798
-
799
-
800
- // Afficher l'explication
801
- explanationElement.classList.remove('hidden');
802
-
803
- // Animer le passage à la question suivante ou afficher les résultats
804
- setTimeout(() => {
805
- const nextQuestion = document.getElementById(`question-${parseInt(qIdx) + 1}`);
806
- if (nextQuestion) {
807
- window.scrollTo({
808
- top: nextQuestion.offsetTop - 80, // Ajustez le décalage si nécessaire
809
- behavior: 'smooth'
810
- });
811
- } else {
812
- // C'était la dernière question, afficher un récapitulatif
813
- if (parseInt(qIdx) === quizQuestions.length - 1) {
814
- displayQuizResults(currentScore, quizQuestions.length);
815
- }
816
  }
817
- }, delay);
818
- });
819
  });
820
  });
821
- }
822
-
823
- function displayQuizResults(score, total) {
824
- const percentage = (score / total) * 100;
825
- let resultClass, resultIcon, resultMessage;
826
-
827
- if (percentage >= 80) {
828
- resultClass = 'bg-green-50 border-green-500 text-green-800';
829
- resultIcon = '<i class="fas fa-trophy text-3xl text-yellow-500 mb-3"></i>';
830
- resultMessage = 'Excellent ! Vous maîtrisez ce sujet.';
831
- } else if (percentage >= 60) {
832
- resultClass = 'bg-blue-50 border-blue-500 text-blue-800';
833
- resultIcon = '<i class="fas fa-medal text-3xl text-blue-500 mb-3"></i>';
834
- resultMessage = 'Bon travail ! Continuez vos efforts.';
835
- } else {
836
- resultClass = 'bg-red-50 border-red-500 text-red-800';
837
- resultIcon = '<i class="fas fa-book-open text-3xl text-red-500 mb-3"></i>';
838
- resultMessage = 'Continuez à étudier pour améliorer vos connaissances.';
839
- }
840
-
841
- const resultsElement = document.createElement('div');
842
- resultsElement.className = `mt-10 p-6 rounded-xl shadow-lg border-l-4 ${resultClass} text-center`;
843
- resultsElement.innerHTML = `
844
- <div class="flex flex-col items-center">
845
- ${resultIcon}
846
- <h3 class="text-2xl font-bold mb-2">Résultat final: ${score}/${total}</h3>
847
- <p class="mb-4">${resultMessage}</p>
848
- <div class="w-full max-w-xs bg-gray-200 rounded-full h-4 mb-4">
849
- <div class="h-4 rounded-full ${percentage >= 80 ? 'bg-green-500' : percentage >= 60 ? 'bg-blue-500' : 'bg-red-500'}" style="width: ${percentage}%"></div>
850
- </div>
851
- <div class="flex space-x-4 mt-6">
852
- <button id="retryQuizBtn" class="btn-secondary text-sm">
853
- <i class="fas fa-redo mr-2"></i> Réessayer
854
- </button>
855
- <button id="newQuizBtn" class="btn-primary text-sm">
856
- <i class="fas fa-plus mr-2"></i> Nouveau quiz
857
- </button>
858
- </div>
859
  </div>
860
- `;
861
- quizContainer.appendChild(resultsElement);
862
-
863
- // Faire défiler vers les résultats
864
- window.scrollTo({
865
- top: resultsElement.offsetTop - 80, // Ajustez le décalage
866
- behavior: 'smooth'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
867
  });
868
-
869
- // Animation de confettis si le score est bon
870
- if (percentage >= 70) {
871
- createConfetti();
872
- }
873
-
874
- // Ajouter des interactions aux boutons
875
- document.getElementById('retryQuizBtn').addEventListener('click', function() {
876
- // Réinitialiser l'état du quiz pour réessayer
877
- quizContainer.innerHTML = ''; // Effacer le contenu actuel
878
- document.getElementById('score').textContent = '0'; // Réinitialiser le score affiché
879
- const currentTopic = topicInput.value.trim();
880
- const currentType = 'quiz';
881
-
882
- // Relancer la génération avec le même sujet (simulé ici)
883
- generateBtn.click(); // Simule un nouveau clic sur générer
884
-
885
- // Si vous avez les données originales, vous pouvez simplement réafficher le quiz
886
- // displayQuiz(originalQuizData); // Assurez-vous que originalQuizData est accessible
887
-
888
-
889
  });
890
-
891
- document.getElementById('newQuizBtn').addEventListener('click', function() {
892
- window.scrollTo({
893
- top: 0,
894
- behavior: 'smooth'
895
- });
896
- topicInput.value = ''; // Effacer le champ
897
- topicInput.focus();
898
- quizContainer.classList.add('hidden'); // Cacher les résultats actuels
899
- quizContainer.innerHTML = ''; // Vider le conteneur
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900
  });
901
- }
902
-
903
- // Focus sur le champ de saisie au chargement
904
- window.addEventListener('load', () => {
905
  topicInput.focus();
906
  });
907
- </script>
 
 
 
 
 
 
 
908
  </body>
909
- </html>
 
1
+
2
  <!DOCTYPE html>
3
+
4
  <html lang="fr">
5
  <head>
6
  <meta charset="UTF-8">
 
36
  <style>
37
  @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
38
 
39
+ body {
40
+ font-family: 'Poppins', sans-serif;
41
+ background-color: #f8fafc;
42
+ }
43
+
44
+ .flashcard {
45
+ perspective: 1000px;
46
+ height: 220px;
47
+ }
48
+
49
+ .flashcard-inner {
50
+ position: relative;
51
+ width: 100%;
52
+ height: 100%;
53
+ transition: transform 0.8s;
54
+ transform-style: preserve-3d;
55
+ }
56
+
57
+ .flashcard.flipped .flashcard-inner {
58
+ transform: rotateY(180deg);
59
+ }
60
+
61
+ .flashcard-front, .flashcard-back {
62
+ position: absolute;
63
+ width: 100%;
64
+ height: 100%;
65
+ -webkit-backface-visibility: hidden;
66
+ backface-visibility: hidden;
67
+ display: flex;
68
+ align-items: center;
69
+ justify-content: center;
70
+ border-radius: 0.5rem;
71
+ padding: 1.5rem;
72
+ box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06);
73
+ }
74
+
75
+ .flashcard-front {
76
+ background-color: #ffffff;
77
+ color: #1e293b;
78
+ border-left: 5px solid #0ea5e9;
79
+ }
80
+
81
+ .flashcard-back {
82
+ background-color: #0ea5e9;
83
+ color: white;
84
+ transform: rotateY(180deg);
85
+ }
86
+
87
+ .quiz-option {
88
+ position: relative;
89
+ padding-left: 2.5rem;
90
+ }
91
+
92
+ .quiz-option input[type="radio"] {
93
+ position: absolute;
94
+ opacity: 0;
95
+ }
96
+
97
+ .quiz-option label {
98
+ display: block;
99
+ position: relative;
100
+ padding: 1rem 1.5rem 1rem 2.5rem;
101
+ cursor: pointer;
102
+ border: 1px solid #e2e8f0;
103
+ border-radius: 0.5rem;
104
+ transition: all 0.3s ease;
105
+ }
106
+
107
+ .quiz-option label:before {
108
+ content: '';
109
+ position: absolute;
110
+ left: 1rem;
111
+ top: 50%;
112
+ transform: translateY(-50%);
113
+ width: 1.25rem;
114
+ height: 1.25rem;
115
+ border-radius: 50%;
116
+ border: 2px solid #cbd5e1;
117
+ transition: all 0.3s ease;
118
+ }
119
+
120
+ .quiz-option input[type="radio"]:checked + label {
121
+ background-color: #e0f2fe;
122
+ border-color: #0ea5e9;
123
+ }
124
+
125
+ .quiz-option input[type="radio"]:checked + label:before {
126
+ border-color: #0ea5e9;
127
+ background-color: #0ea5e9;
128
+ box-shadow: inset 0 0 0 4px #e0f2fe;
129
+ }
130
+
131
+ .quiz-option.correct input[type="radio"]:checked + label {
132
+ background-color: #d1fae5;
133
+ border-color: #10b981;
134
+ }
135
+
136
+ .quiz-option.correct input[type="radio"]:checked + label:before {
137
+ border-color: #10b981;
138
+ background-color: #10b981;
139
+ box-shadow: inset 0 0 0 4px #d1fae5;
140
+ }
141
+
142
+ .quiz-option.incorrect input[type="radio"]:checked + label {
143
+ background-color: #fee2e2;
144
+ border-color: #ef4444;
145
+ }
146
+
147
+ .quiz-option.incorrect input[type="radio"]:checked + label:before {
148
+ border-color: #ef4444;
149
+ background-color: #ef4444;
150
+ box-shadow: inset 0 0 0 4px #fee2e2;
151
+ }
152
+
153
+ .progress-bar-container {
154
+ width: 100%;
155
+ height: 8px;
156
+ background-color: #e2e8f0;
157
+ border-radius: 4px;
158
+ overflow: hidden;
159
+ }
160
+
161
+ .progress-bar {
162
+ height: 100%;
163
+ background-color: #0ea5e9;
164
+ transition: width 0.5s ease;
165
+ }
166
+
167
+ .floating-label {
168
+ position: absolute;
169
+ top: -10px;
170
+ left: 10px;
171
+ padding: 0 5px;
172
+ background-color: white;
173
+ transition: all 0.3s ease;
174
+ pointer-events: none;
175
+ }
176
+
177
+ .pulse-animation {
178
+ animation: pulse 2s infinite;
179
+ }
180
+
181
+ @keyframes pulse {
182
+ 0% {
183
+ box-shadow: 0 0 0 0 rgba(14, 165, 233, 0.4);
184
+ }
185
+ 70% {
186
+ box-shadow: 0 0 0 10px rgba(14, 165, 233, 0);
187
+ }
188
+ 100% {
189
+ box-shadow: 0 0 0 0 rgba(14, 165, 233, 0);
190
+ }
191
+ }
192
+
193
+ .confetti {
194
+ position: fixed;
195
+ width: 10px;
196
+ height: 10px;
197
+ background-color: #f00;
198
+ opacity: 0;
199
+ animation: confetti-fall 3s linear forwards;
200
+ }
201
+
202
+ @keyframes confetti-fall {
203
+ 0% {
204
+ transform: translateY(0) rotate(0deg);
205
+ opacity: 1;
206
+ }
207
+ 100% {
208
+ transform: translateY(100vh) rotate(360deg);
209
  opacity: 0;
 
 
 
 
 
 
 
 
 
 
 
 
210
  }
211
+ }
212
+
213
+ .btn-primary {
214
+ @apply bg-primary-600 text-white px-6 py-3 rounded-lg shadow-md hover:bg-primary-700 transition duration-300 ease-in-out transform hover:-translate-y-1 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-opacity-50;
215
+ }
216
+
217
+ .btn-secondary {
218
+ @apply bg-white text-primary-600 border border-primary-600 px-6 py-3 rounded-lg shadow-md hover:bg-primary-50 transition duration-300 ease-in-out transform hover:-translate-y-1 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-opacity-50;
219
+ }
220
+ </style>
221
 
 
 
 
 
 
 
 
 
222
  </head>
223
  <body>
224
  <div class="min-h-screen bg-gradient-to-b from-primary-50 to-white">
 
241
  </div>
242
  </header>
243
 
244
+ <main class="container mx-auto px-4 py-8">
245
+ <div class="max-w-3xl mx-auto">
246
+ <!-- Introduction -->
247
+ <div class="text-center mb-8">
248
+ <h2 class="text-4xl font-bold text-gray-800 mb-4">Apprenez plus efficacement</h2>
249
+ <p class="text-lg text-gray-600 mb-6">Créez des flashcards ou des quiz pour mémoriser n'importe quel sujet</p>
250
+ </div>
251
+
252
+ <!-- Section de configuration -->
253
+ <div class="bg-white rounded-xl shadow-lg p-8 mb-10 relative overflow-hidden">
254
+ <div class="absolute top-0 right-0 w-40 h-40 bg-primary-100 rounded-full -mr-20 -mt-20 z-0"></div>
255
+ <div class="absolute bottom-0 left-0 w-24 h-24 bg-primary-100 rounded-full -ml-12 -mb-12 z-0"></div>
256
+
257
+ <div class="relative z-10">
258
+ <h3 class="text-2xl font-semibold text-gray-800 mb-6">Que souhaitez-vous apprendre aujourd'hui ?</h3>
259
+
260
+ <div class="space-y-6">
261
+ <div class="relative">
262
+ <input type="text" id="topic" class="w-full px-4 py-3 border-2 border-gray-300 rounded-lg focus:border-primary-500 focus:ring focus:ring-primary-200 focus:ring-opacity-50 transition-all duration-300 pl-10" placeholder="Entrez un sujet...">
263
+ <i class="fas fa-search absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-400"></i>
264
+ <div class="text-xs text-gray-500 mt-1 ml-2">Exemples: "Capitales du monde", "Photosynthèse", "Verbes irréguliers en anglais"</div>
265
+ </div>
266
+
267
+ <div>
268
+ <p class="text-gray-700 font-medium mb-3">Choisissez votre méthode d'apprentissage :</p>
269
+ <div class="grid grid-cols-1 md:grid-cols-2 gap-4">
270
+ <div class="relative">
271
+ <input type="radio" id="typeFlashcards" name="contentType" value="flashcards" checked class="peer absolute opacity-0">
272
+ <label for="typeFlashcards" class="flex flex-col items-center justify-center p-4 border-2 border-gray-200 rounded-lg cursor-pointer transition-all duration-300 hover:bg-gray-50 peer-checked:border-primary-500 peer-checked:bg-primary-50">
273
+ <div class="w-12 h-12 rounded-full bg-primary-100 flex items-center justify-center mb-3">
274
+ <i class="fas fa-clone text-xl text-primary-600"></i>
275
+ </div>
276
+ <h4 class="font-semibold text-gray-800">Flashcards</h4>
277
+ <p class="text-sm text-gray-600 text-center mt-2">Pour mémoriser des informations par répétition</p>
278
+ </label>
 
 
 
 
 
 
 
 
 
 
 
 
279
  </div>
280
+
281
+ <div class="relative">
282
+ <input type="radio" id="typeQuiz" name="contentType" value="quiz" class="peer absolute opacity-0">
283
+ <label for="typeQuiz" class="flex flex-col items-center justify-center p-4 border-2 border-gray-200 rounded-lg cursor-pointer transition-all duration-300 hover:bg-gray-50 peer-checked:border-primary-500 peer-checked:bg-primary-50">
284
+ <div class="w-12 h-12 rounded-full bg-primary-100 flex items-center justify-center mb-3">
285
+ <i class="fas fa-question text-xl text-primary-600"></i>
286
+ </div>
287
+ <h4 class="font-semibold text-gray-800">Quiz</h4>
288
+ <p class="text-sm text-gray-600 text-center mt-2">Pour tester vos connaissances avec des QCM</p>
289
+ </label>
290
  </div>
 
 
 
 
291
  </div>
292
  </div>
293
+
294
+ <div class="flex items-center justify-between pt-2">
295
+ <div class="text-sm text-gray-500 italic">
296
+ <i class="fas fa-info-circle mr-1"></i> La génération peut prendre jusqu'à 1 minute
297
+ </div>
298
+ <button id="generateBtn" class="btn-primary flex items-center">
299
+ <span class="mr-2">Générer</span>
300
+ <i class="fas fa-chevron-right"></i>
301
+ </button>
302
+ </div>
303
  </div>
304
  </div>
305
+ </div>
306
 
307
+ <!-- Indicateur de chargement -->
308
+ <div id="loading" class="hidden">
309
+ <div class="bg-white rounded-xl shadow-lg p-8 text-center">
310
+ <div class="flex flex-col items-center justify-center space-y-4">
311
+ <div class="relative w-24 h-24">
312
+ <div class="absolute inset-0 border-4 border-primary-100 border-t-primary-500 rounded-full animate-spin"></div>
313
+ <div class="absolute inset-0 flex items-center justify-center">
314
+ <i class="fas fa-lightbulb text-2xl text-primary-500 animate-pulse"></i>
 
315
  </div>
316
+ </div>
317
+ <h3 class="text-xl font-semibold text-gray-800">Création en cours...</h3>
318
+ <p class="text-gray-600">Nous élaborons votre contenu d'apprentissage personnalisé</p>
319
+
320
+ <div class="w-full max-w-md mt-4">
321
+ <div class="progress-bar-container">
322
+ <div id="progressBar" class="progress-bar" style="width: 0%"></div>
323
+ </div>
324
+ <div id="loadingSteps" class="mt-8 text-left">
325
+ <div class="flex items-center mb-3">
326
+ <div class="w-6 h-6 rounded-full bg-primary-500 flex items-center justify-center mr-3">
327
+ <i class="fas fa-check text-white text-xs"></i>
 
328
  </div>
329
+ <span class="text-sm text-gray-700">Analyse du sujet</span>
330
+ </div>
331
+ <div class="flex items-center mb-3">
332
+ <div id="step2" class="w-6 h-6 rounded-full bg-gray-200 flex items-center justify-center mr-3">
333
+ <i class="fas fa-spinner text-white text-xs animate-spin"></i>
334
  </div>
335
+ <span class="text-sm text-gray-500">Recherche d'informations</span>
336
+ </div>
337
+ <div class="flex items-center mb-3">
338
+ <div id="step3" class="w-6 h-6 rounded-full bg-gray-200 flex items-center justify-center mr-3">
339
+ <i class="fas fa-hourglass text-white text-xs"></i>
340
  </div>
341
+ <span class="text-sm text-gray-500">Création du contenu</span>
342
+ </div>
343
+ <div class="flex items-center">
344
+ <div id="step4" class="w-6 h-6 rounded-full bg-gray-200 flex items-center justify-center mr-3">
345
+ <i class="fas fa-hourglass text-white text-xs"></i>
346
  </div>
347
+ <span class="text-sm text-gray-500">Finalisation</span>
348
  </div>
349
  </div>
350
  </div>
351
  </div>
352
  </div>
353
+ </div>
354
 
355
+ <!-- Conteneur pour les Flashcards -->
356
+ <div id="flashcardsContainer" class="mt-8 hidden">
357
+ <!-- Les flashcards seront injectées ici -->
 
 
 
 
 
 
358
  </div>
 
359
 
360
+ <!-- Conteneur pour le Quiz -->
361
+ <div id="quizContainer" class="mt-8 hidden">
362
+ <!-- Les questions du quiz seront injectées ici -->
363
+ </div>
364
+ </div>
365
+ </main>
366
+
367
+ <footer class="bg-gray-900 text-white py-8 mt-20">
368
+ <div class="container mx-auto px-4">
369
+ <div class="flex flex-col md:flex-row justify-between items-center">
370
+ <div class="mb-4 md:mb-0">
371
+ <h2 class="text-xl font-bold flex items-center">
372
+ <i class="fas fa-brain mr-2"></i> Mémorisation Facile
373
+ </h2>
374
+ <p class="text-gray-400 text-sm mt-2">Votre outil d'apprentissage intelligent</p>
375
  </div>
376
+ <div class="flex space-x-4">
377
+ <a href="#" class="text-gray-400 hover:text-white transition-colors"><i class="fab fa-twitter"></i></a>
378
+ <a href="#" class="text-gray-400 hover:text-white transition-colors"><i class="fab fa-facebook"></i></a>
379
+ <a href="#" class="text-gray-400 hover:text-white transition-colors"><i class="fab fa-instagram"></i></a>
380
+ <a href="#" class="text-gray-400 hover:text-white transition-colors"><i class="fab fa-youtube"></i></a>
381
  </div>
382
  </div>
383
+ <div class="mt-8 border-t border-gray-800 pt-6 text-sm text-gray-400 text-center">
384
+ © 2025 Mémorisation Facile. Tous droits réservés.
385
+ </div>
386
+ </div>
387
+ </footer>
388
+ </div>
389
+
390
+ <script>
391
+ const generateBtn = document.getElementById('generateBtn');
392
+ const loadingIndicator = document.getElementById('loading');
393
+ const flashcardsContainer = document.getElementById('flashcardsContainer');
394
+ const quizContainer = document.getElementById('quizContainer');
395
+ const topicInput = document.getElementById('topic');
396
+ const progressBar = document.getElementById('progressBar');
397
+ const themeToggle = document.getElementById('themeToggle');
398
+ const step2 = document.getElementById('step2');
399
+ const step3 = document.getElementById('step3');
400
+ const step4 = document.getElementById('step4');
401
+
402
+ // Gestion du thème clair/sombre
403
+ themeToggle.addEventListener('click', function() {
404
+ document.body.classList.toggle('dark-mode');
405
+ const icon = this.querySelector('i');
406
+ if (icon.classList.contains('fa-moon')) {
407
+ icon.classList.remove('fa-moon');
408
+ icon.classList.add('fa-sun');
409
+ } else {
410
+ icon.classList.remove('fa-sun');
411
+ icon.classList.add('fa-moon');
412
+ }
413
+ });
414
+
415
+ // Animation de chargement
416
+ function simulateLoading() {
417
+ let progress = 0;
418
+ const interval = setInterval(() => {
419
+ progress += 1;
420
+ progressBar.style.width = `${progress}%`;
421
+
422
+ if (progress === 25) {
423
+ step2.classList.remove('bg-gray-200');
424
+ step2.classList.add('bg-primary-500');
425
+ step2.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
426
+ } else if (progress === 60) {
427
+ step3.classList.remove('bg-gray-200');
428
+ step3.classList.add('bg-primary-500');
429
+ step3.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
430
+ step4.innerHTML = '<i class="fas fa-spinner text-white text-xs animate-spin"></i>';
431
+ } else if (progress === 95) {
432
+ step4.classList.remove('bg-gray-200');
433
+ step4.classList.add('bg-primary-500');
434
+ step4.innerHTML = '<i class="fas fa-check text-white text-xs"></i>';
435
  }
436
+
437
+ if (progress >= 100) {
438
+ clearInterval(interval);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  }
440
+ }, 50);
441
+
442
+ return interval;
443
+ }
444
+
445
+ // Fonction pour créer des confettis
446
+ function createConfetti() {
447
+ const confettiCount = 100;
448
+ const colors = ['#0ea5e9', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6'];
449
+
450
+ for (let i = 0; i < confettiCount; i++) {
451
+ const confetti = document.createElement('div');
452
+ confetti.className = 'confetti';
453
+ confetti.style.left = `${Math.random() * 100}vw`;
454
+ confetti.style.backgroundColor = colors[Math.floor(Math.random() * colors.length)];
455
+ confetti.style.width = `${Math.random() * 10 + 5}px`;
456
+ confetti.style.height = `${Math.random() * 10 + 5}px`;
457
+ confetti.style.animationDuration = `${Math.random() * 3 + 2}s`;
458
+ document.body.appendChild(confetti);
459
+
460
+ setTimeout(() => {
461
+ confetti.remove();
462
+ }, 5000);
463
+ }
464
+ }
465
+
466
+ // Gestion des flashcards
467
+ function flipCard(card) {
468
+ card.classList.toggle('flipped');
469
+ }
470
+
471
+ generateBtn.addEventListener('click', function() {
472
+ const topic = topicInput.value.trim();
473
+ if (!topic) {
474
+ // Animation de secouement sur l'input
475
+ topicInput.classList.add('border-red-500');
476
+ topicInput.classList.add('animate-bounce');
477
+ setTimeout(() => {
478
+ topicInput.classList.remove('animate-bounce');
479
+ topicInput.classList.remove('border-red-500');
480
+ }, 1000);
481
+
482
+ // Afficher un message d'erreur
483
+ const errorMsg = document.createElement('div');
484
+ errorMsg.className = 'text-red-500 text-sm mt-1 ml-2';
485
+ errorMsg.textContent = 'Veuillez entrer un sujet';
486
+ topicInput.parentElement.appendChild(errorMsg);
487
+ setTimeout(() => {
488
+ errorMsg.remove();
489
+ }, 3000);
490
+
491
+ return;
492
+ }
493
+
494
+ const contentType = document.querySelector('input[name="contentType"]:checked').value;
495
+
496
+ // Afficher le chargement et cacher les anciens résultats
497
+ loadingIndicator.classList.remove('hidden');
498
+ flashcardsContainer.classList.add('hidden');
499
+ quizContainer.classList.add('hidden');
500
+ flashcardsContainer.innerHTML = '';
501
+ quizContainer.innerHTML = '';
502
+
503
+ // Simuler l'animation de chargement
504
+ const loadingInterval = simulateLoading();
505
+
506
+ // Envoi de la requête
507
+ fetch('/generate', {
508
+ method: 'POST',
509
+ headers: {
510
+ 'Content-Type': 'application/json',
511
+ },
512
+ body: JSON.stringify({ topic, type: contentType }),
513
+ })
514
+ .then(response => {
515
+ if (!response.ok) {
516
+ throw new Error(`Erreur HTTP: ${response.status}`);
517
  }
518
+ return response.json();
519
+ })
520
+ .then(data => {
521
+ // Assurons-nous que l'animation montre au moins 2 secondes
 
 
 
 
 
 
 
 
 
 
 
522
  setTimeout(() => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
523
  clearInterval(loadingInterval);
524
  progressBar.style.width = '100%';
525
+
526
  setTimeout(() => {
527
  loadingIndicator.classList.add('hidden');
528
+
529
+ if (data.error) {
530
+ // Afficher une erreur élégante
531
  const errorContainer = document.createElement('div');
532
  errorContainer.className = 'bg-red-50 border-l-4 border-red-500 p-4 rounded-md mt-4';
533
  errorContainer.innerHTML = `
 
537
  </div>
538
  <div class="ml-3">
539
  <p class="text-sm text-red-700">
540
+ ${data.error}
541
  </p>
542
  </div>
543
  </div>
 
546
  return;
547
  }
548
 
549
+ if (contentType === 'flashcards' && data.flashcards) {
550
  flashcardsContainer.classList.remove('hidden');
551
+ displayFlashcards(data.flashcards);
552
+ // Créer un effet de confettis
553
  createConfetti();
554
+ } else if (contentType === 'quiz' && data.quiz) {
555
  quizContainer.classList.remove('hidden');
556
+ displayQuiz(data.quiz);
557
+ // Créer un effet de confettis
558
  createConfetti();
559
  } else {
560
+ // Afficher une erreur élégante
561
  const errorContainer = document.createElement('div');
562
+ errorContainer.className = 'bg-red-50 border-l-4 border-red-500 p-4 rounded-md mt-4';
563
  errorContainer.innerHTML = `
564
  <div class="flex">
565
  <div class="flex-shrink-0">
566
+ <i class="fas fa-exclamation-circle text-red-500"></i>
567
  </div>
568
  <div class="ml-3">
569
+ <p class="text-sm text-red-700">
570
+ Aucune donnée reçue ou format incorrect.
571
  </p>
572
  </div>
573
  </div>
 
575
  document.querySelector('.max-w-3xl').appendChild(errorContainer);
576
  }
577
  }, 500);
578
+ }, 2000);
579
+ })
580
+ .catch(error => {
581
+ clearInterval(loadingInterval);
582
+ loadingIndicator.classList.add('hidden');
583
+ console.error('Erreur lors de la génération:', error);
584
+
585
+ // Afficher une erreur élégante
586
+ const errorContainer = document.createElement('div');
587
+ errorContainer.className = 'bg-red-50 border-l-4 border-red-500 p-4 rounded-md mt-4';
588
+ errorContainer.innerHTML = `
589
+ <div class="flex">
590
+ <div class="flex-shrink-0">
591
+ <i class="fas fa-exclamation-circle text-red-500"></i>
592
+ </div>
593
+ <div class="ml-3">
594
+ <p class="text-sm text-red-700">
595
+ Erreur lors de la génération: ${error.message}.
596
  </p>
597
+ </div>
598
+ </div>
 
599
  `;
600
+ document.querySelector('.max-w-3xl').appendChild(errorContainer);
601
+ });
602
+ });
603
+
604
+ function displayFlashcards(flashcards) {
605
+ const header = document.createElement('div');
606
+ header.className = 'mb-8 text-center';
607
+ header.innerHTML = `
608
+ <h2 class="text-3xl font-bold text-gray-800 mb-2">Vos Flashcards (${flashcards.length})</h2>
609
+ <p >Cliquez sur une carte pour la retourner et voir la réponse.</p>
610
+ <p class="text-gray-600">
611
+ <i class="far fa-lightbulb mr-1"></i> Astuce : Essayez de répondre mentalement avant de retourner la carte
612
+ </p>
613
+ <p><div class="flex items-center justify-center space-x-4 mt-6">
614
+ </div></p>
615
+
616
+ `;
617
+ flashcardsContainer.appendChild(header);
618
+
619
+ const flashcardsGrid = document.createElement('div');
620
+ flashcardsGrid.className = 'grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6';
621
+ flashcardsContainer.appendChild(flashcardsGrid);
622
+
623
+ flashcards.forEach((card, index) => {
624
+ const cardElement = document.createElement('div');
625
+ cardElement.className = 'flashcard cursor-pointer';
626
+ cardElement.onclick = function() { flipCard(this); };
627
+ cardElement.innerHTML = `
628
+ <div class="flashcard-inner">
629
+ <div class="flashcard-front">
630
+ <div class="w-full">
631
+ <div class="absolute top-2 left-2 text-xs text-gray-400">#${index + 1}</div>
632
+ <h3 class="text-lg font-semibold mb-2 text-center">${card.question}</h3>
633
+ <div class="text-center mt-4">
634
+ <span class="text-xs text-gray-500">Cliquez pour voir la réponse</span>
635
  </div>
636
  </div>
637
+ </div>
638
+
639
+ <div class="flashcard-back">
640
+ <div class="w-full">
641
+ <div class="absolute top-2 right-2 text-xs text-white opacity-70">#${index + 1}</div>
642
+ <div class="text-center">
643
+ <p class="font-medium">${card.answer}</p>
644
+ </div>
645
+ <div class="absolute bottom-2 right-2">
646
+ <span class="text-xs text-white opacity-70">Cliquez pour retourner</span>
647
  </div>
648
  </div>
649
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
650
  </div>
 
651
  `;
652
+ flashcardsGrid.appendChild(cardElement);
653
+ });
654
+
655
+ // Ajouter des boutons de navigation et de contrôle
656
+ const controls = document.createElement('div');
657
+ controls.className = 'mt-10 flex flex-col items-center justify-center';
658
+ controls.innerHTML = `
659
+ <div class="flex items-center space-x-4 mb-6">
660
+ <button class="px-4 py-2 bg-primary-100 hover:bg-primary-200 text-primary-700 rounded-md transition duration-300 flex items-center">
661
+ <i class="fas fa-redo-alt mr-2"></i> Recommencer
662
+ </button>
663
+ <button id="newTopicBtn" class="px-4 py-2 bg-primary-600 hover:bg-primary-700 text-white rounded-md transition duration-300 flex items-center">
664
+ <i class="fas fa-plus mr-2"></i> Nouveau sujet
665
+ </button>
666
+ </div>
667
+
668
+ `;
669
+ flashcardsContainer.appendChild(controls);
670
+
671
+ // Ajouter des interactions aux boutons
672
+ document.getElementById('printBtn').addEventListener('click', function() {
673
+ window.print();
674
+ });
675
+
676
+ document.getElementById('saveBtn').addEventListener('click', function() {
677
+ alert('Flashcards sauvegardées !');
678
+ });
679
+
680
+ document.getElementById('shareBtn').addEventListener('click', function() {
681
+ alert('Lien de partage copié dans le presse-papiers !');
682
+ });
683
+
684
+ document.getElementById('newTopicBtn').addEventListener('click', function() {
685
+ window.scrollTo({
686
+ top: 0,
687
+ behavior: 'smooth'
688
  });
689
+ topicInput.focus();
690
+ });
691
+ }
692
+
693
+ function displayQuiz(quizQuestions) {
694
+ const header = document.createElement('div');
695
+ header.className = 'mb-8 text-center';
696
+ header.innerHTML = `
697
+ <h2 class="text-3xl font-bold text-gray-800 mb-2">Votre Quiz (${quizQuestions.length} questions)</h2>
698
+ <p class="text-gray-600">Testez vos connaissances en répondant aux questions</p>
699
+ <div class="flex items-center justify-center mt-6">
700
+ <div class="bg-white px-4 py-2 rounded-full shadow-sm flex items-center">
701
+ <span class="text-primary-700 font-medium">Score: </span>
702
+ <span id="score" class="ml-1 text-primary-700 font-bold">0</span>
703
+ <span class="mx-1 text-gray-400">/</span>
704
+ <span class="text-gray-600">${quizQuestions.length}</span>
705
+ </div>
706
+ </div>
707
+ `;
708
+ quizContainer.appendChild(header);
709
+
710
+ // Créer un conteneur pour les questions
711
+ const questionsContainer = document.createElement('div');
712
+ questionsContainer.className = 'space-y-8';
713
+ quizContainer.appendChild(questionsContainer);
714
+
715
+ // Variable pour suivre le score
716
+ let currentScore = 0;
717
+
718
+ quizQuestions.forEach((question, qIndex) => {
719
+ const questionElement = document.createElement('div');
720
+ questionElement.className = 'bg-white rounded-xl shadow-md p-6 transition-all duration-300';
721
+ questionElement.setAttribute('id', `question-${qIndex}`);
722
+
723
+ let optionsHtml = '';
724
+ const safeCorrectAnswer = question.correctAnswer.replace(/"/g, '"');
725
+
726
+ question.options.forEach((option, oIndex) => {
727
+ optionsHtml += `
728
+ <div class="quiz-option mb-3" id="option-${qIndex}-${oIndex}">
729
+ <input type="radio" id="q${qIndex}-o${oIndex}" name="question-${qIndex}" value="${option}" data-correct="${safeCorrectAnswer}">
730
+ <label for="q${qIndex}-o${oIndex}" class="group">
731
+ ${option}
732
+ <span class="hidden success-icon absolute right-4 text-green-500">
733
+ <i class="fas fa-check-circle"></i>
734
+ </span>
735
+ <span class="hidden error-icon absolute right-4 text-red-500">
736
+ <i class="fas fa-times-circle"></i>
737
+ </span>
738
+ </label>
739
  </div>
740
+ `;
741
+ });
742
+
743
+ questionElement.innerHTML = `
744
+ <div class="flex items-center justify-between mb-4">
745
+ <span class="bg-primary-100 text-primary-800 text-xs font-medium px-2.5 py-0.5 rounded">Question ${qIndex + 1}/${quizQuestions.length}</span>
746
+ <span class="text-gray-400 text-sm">
747
+ <i class="far fa-lightbulb"></i>
748
+ </span>
749
  </div>
750
+ <h3 class="text-xl font-medium text-gray-800 mb-4">${question.question}</h3>
751
+ <div class="options mt-5">
752
+ ${optionsHtml}
753
+ </div>
754
+ <div class="explanation hidden mt-6 p-4 bg-blue-50 border border-blue-100 rounded-lg" id="explanation-${qIndex}">
755
+ <div class="flex items-start">
756
+ <div class="flex-shrink-0 mt-0.5">
757
+ <i class="fas fa-info-circle text-blue-500"></i>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
758
  </div>
759
+ <div class="ml-3">
760
+ <h4 class="text-sm font-medium text-blue-800">Explication</h4>
761
+ <div class="mt-1 text-sm text-blue-700">${question.explanation}</div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
762
  </div>
763
  </div>
764
+ </div>
765
+ `;
766
+ questionsContainer.appendChild(questionElement);
767
+
768
+ // Ajouter des gestionnaires d'événements pour les options
769
+ const options = questionElement.querySelectorAll('input[type="radio"]');
770
+ options.forEach((option) => {
771
+ option.addEventListener('change', function() {
772
+ const optionId = this.id;
773
+ const [_, qIdx, oIdx] = optionId.match(/q(\d+)-o(\d+)/);
774
+ const selected = this.value;
775
+ const correct = this.getAttribute('data-correct');
776
+ const explanationElement = document.getElementById(`explanation-${qIdx}`);
777
+
778
+ // Vérifier la réponse
779
+ let delay = 0; // Initialiser le délai
780
+ if (selected === correct) {
781
+ // Réponse correcte
782
+ document.getElementById(`option-${qIdx}-${oIdx}`).classList.add('correct');
783
+ currentScore++;
784
+ document.getElementById('score').textContent = currentScore;
785
+
786
+ // Afficher une animation de succès
787
+ const successIcon = this.nextElementSibling.querySelector('.success-icon');
788
+ successIcon.classList.remove('hidden');
789
+ delay = 2000; // 2 secondes pour une réponse correcte
790
+ } else {
791
+ // Réponse incorrecte
792
+ document.getElementById(`option-${qIdx}-${oIdx}`).classList.add('incorrect');
793
+
794
+ // Afficher une animation d'erreur
795
+ const errorIcon = this.nextElementSibling.querySelector('.error-icon');
796
+ errorIcon.classList.remove('hidden');
797
+
798
+ // Mettre en évidence la bonne réponse
799
+ options.forEach((opt, idx) => {
800
+ if (opt.value === correct) {
801
+ document.getElementById(`option-${qIdx}-${idx}`).classList.add('correct');
802
+ const successIcon = opt.nextElementSibling.querySelector('.success-icon');
803
+ successIcon.classList.remove('hidden');
804
+ }
805
+ });
806
+ delay = 5000; // 5 secondes pour une réponse incorrecte
807
+ }
808
 
809
+ // Désactiver toutes les autres options
810
+ options.forEach((opt) => {
811
+ if (opt !== this) {
812
+ opt.disabled = true;
813
  }
814
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
815
 
816
+ // Afficher l'explication
817
+ explanationElement.classList.remove('hidden');
 
818
 
819
+ // Animer le passage à la question suivante
820
+ setTimeout(() => {
821
+ const nextQuestion = document.getElementById(`question-${parseInt(qIdx) + 1}`);
822
+ if (nextQuestion) {
823
+ window.scrollTo({
824
+ top: nextQuestion.offsetTop - 20,
825
+ behavior: 'smooth'
826
  });
827
+ } else {
828
+ // C'était la dernière question, afficher un récapitulatif
829
+ if (parseInt(qIdx) === quizQuestions.length - 1) {
830
+ displayQuizResults(currentScore, quizQuestions.length);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
831
  }
832
+ }
833
+ }, delay);
834
  });
835
  });
836
+ });
837
+ }
838
+
839
+ function displayQuizResults(score, total) {
840
+ const percentage = (score / total) * 100;
841
+ let resultClass, resultIcon, resultMessage;
842
+
843
+ if (percentage >= 80) {
844
+ resultClass = 'bg-green-50 border-green-500 text-green-800';
845
+ resultIcon = '<i class="fas fa-trophy text-3xl text-yellow-500 mb-3"></i>';
846
+ resultMessage = 'Excellent ! Vous maîtrisez ce sujet.';
847
+ } else if (percentage >= 60) {
848
+ resultClass = 'bg-blue-50 border-blue-500 text-blue-800';
849
+ resultIcon = '<i class="fas fa-medal text-3xl text-blue-500 mb-3"></i>';
850
+ resultMessage = 'Bon travail ! Continuez vos efforts.';
851
+ } else {
852
+ resultClass = 'bg-red-50 border-red-500 text-red-800';
853
+ resultIcon = '<i class="fas fa-book-open text-3xl text-red-500 mb-3"></i>';
854
+ resultMessage = 'Continuez à étudier pour améliorer vos connaissances.';
855
+ }
856
+
857
+ const resultsElement = document.createElement('div');
858
+ resultsElement.className = `mt-10 p-6 rounded-xl shadow-lg border-l-4 ${resultClass} text-center`;
859
+ resultsElement.innerHTML = `
860
+ <div class="flex flex-col items-center">
861
+ ${resultIcon}
862
+ <h3 class="text-2xl font-bold mb-2">Résultat final: ${score}/${total}</h3>
863
+ <p class="mb-4">${resultMessage}</p>
864
+ <div class="w-full max-w-xs bg-gray-200 rounded-full h-4 mb-4">
865
+ <div class="h-4 rounded-full ${percentage >= 80 ? 'bg-green-500' : percentage >= 60 ? 'bg-blue-500' : 'bg-red-500'}" style="width: ${percentage}%"></div>
 
 
 
 
 
 
 
 
866
  </div>
867
+ <div class="flex space-x-4 mt-6">
868
+ <button id="retryQuizBtn" class="btn-secondary text-sm">
869
+ <i class="fas fa-redo mr-2"></i> Réessayer
870
+ </button>
871
+ <button id="newQuizBtn" class="btn-primary text-sm">
872
+ <i class="fas fa-plus mr-2"></i> Nouveau quiz
873
+ </button>
874
+ </div>
875
+ </div>
876
+ `;
877
+ quizContainer.appendChild(resultsElement);
878
+
879
+ // Animation de confettis si le score est bon
880
+ if (percentage >= 70) {
881
+ createConfetti();
882
+ }
883
+
884
+ // Ajouter des interactions aux boutons
885
+ document.getElementById('retryQuizBtn').addEventListener('click', function() {
886
+ const radios = document.querySelectorAll('input[type="radio"]');
887
+ radios.forEach(radio => {
888
+ radio.checked = false;
889
+ radio.disabled = false;
890
  });
891
+
892
+ const options = document.querySelectorAll('.quiz-option');
893
+ options.forEach(option => {
894
+ option.classList.remove('correct', 'incorrect');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
895
  });
896
+
897
+ const explanations = document.querySelectorAll('.explanation');
898
+ explanations.forEach(exp => {
899
+ exp.classList.add('hidden');
900
+ });
901
+
902
+ const icons = document.querySelectorAll('.success-icon, .error-icon');
903
+ icons.forEach(icon => {
904
+ icon.classList.add('hidden');
905
+ });
906
+
907
+ resultsElement.remove();
908
+ document.getElementById('score').textContent = '0';
909
+
910
+ window.scrollTo({
911
+ top: quizContainer.offsetTop,
912
+ behavior: 'smooth'
913
+ });
914
+ });
915
+
916
+ document.getElementById('newQuizBtn').addEventListener('click', function() {
917
+ window.scrollTo({
918
+ top: 0,
919
+ behavior: 'smooth'
920
  });
 
 
 
 
921
  topicInput.focus();
922
  });
923
+ }
924
+
925
+ // Focus sur le champ de saisie au chargement
926
+ window.addEventListener('load', () => {
927
+ topicInput.focus();
928
+ });
929
+ </script>
930
+
931
  </body>
932
+ </html>