Docfile commited on
Commit
a01391a
·
verified ·
1 Parent(s): 1c9d3b3

Update templates/philosophie.html

Browse files
Files changed (1) hide show
  1. templates/philosophie.html +257 -316
templates/philosophie.html CHANGED
@@ -3,312 +3,325 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Mariam AI - Assistant Philosophique</title>
7
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.7.3/sweetalert2.all.min.js"></script>
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.3.0/marked.min.js"></script>
10
  <link href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.7.3/sweetalert2.min.css" rel="stylesheet">
11
- <script src="https://cdn.tailwindcss.com"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  </head>
13
- <body class="bg-gradient-to-br from-violet-50 to-indigo-50 min-h-screen">
14
- <!-- Navbar -->
15
- <nav class="bg-white/80 backdrop-blur-md border-b border-gray-200 fixed w-full z-50">
16
- <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
17
- <div class="flex justify-between items-center h-16">
18
- <div class="flex items-center">
19
- <div class="text-2xl font-bold bg-gradient-to-r from-violet-600 to-indigo-600 text-transparent bg-clip-text">
20
- Mariam AI
21
- </div>
22
- </div>
23
- <div class="flex items-center space-x-4">
24
- <span class="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-violet-100 text-violet-800">
25
- <span class="w-2 h-2 bg-violet-400 rounded-full animate-pulse mr-2"></span>
26
- Assistant Philosophique
27
- </span>
28
- </div>
29
  </div>
30
- </div>
31
- </nav>
32
 
33
- <!-- Main Content -->
34
- <div class="pt-24 pb-12 px-4 sm:px-6 lg:px-8">
35
- <div class="max-w-4xl mx-auto">
36
- <!-- Main Card -->
37
- <div class="bg-white/80 backdrop-blur-md rounded-2xl shadow-xl border border-gray-100 overflow-hidden">
38
- <!-- Header Section -->
39
- <div class="bg-gradient-to-r from-violet-600 to-indigo-600 p-6 text-white">
40
- <h2 class="text-2xl font-bold">Générateur de Dissertation</h2>
41
- <p class="mt-2 opacity-90">Créez des dissertations philosophiques pertinentes et structurées</p>
42
- </div>
43
 
44
- <!-- Content Section -->
45
- <div class="p-8 space-y-8">
46
- <!-- Type Selection -->
47
- <div class="space-y-3">
48
- <label class="block text-sm font-medium text-gray-700">Type de dissertation</label>
49
- <div class="relative">
50
- <select id="type-select" class="w-full rounded-xl border-gray-200 shadow-sm focus:border-violet-500 focus:ring-violet-500 appearance-none bg-white py-3 px-4 pr-10">
51
- <option value="1">Type 1 - Dissertation classique</option>
52
- <option value="2">Type 2 - Analyse comparative</option>
53
- </select>
54
- <div class="absolute inset-y-0 right-0 flex items-center px-4 pointer-events-none">
55
- <svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
56
- <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
57
- </svg>
58
- </div>
59
- </div>
60
- <div id="current-type-label" class="inline-flex px-4 py-2 rounded-xl text-sm font-medium bg-gradient-to-r from-violet-50 to-indigo-50 text-violet-700 border border-violet-200">
61
- Sujet de type 1
62
- </div>
63
  </div>
 
 
64
 
65
- <!-- Course Selection -->
66
- <div class="space-y-3">
67
- <label class="block text-sm font-medium text-gray-700">Sélection du cours</label>
68
- <div class="relative">
69
- <select id="course-select" class="w-full rounded-xl border-gray-200 shadow-sm focus:border-violet-500 focus:ring-violet-500 appearance-none bg-white py-3 px-4 pr-10">
70
- <option value="">Choisir un cours...</option>
71
- </select>
72
- <div class="absolute inset-y-0 right-0 flex items-center px-4 pointer-events-none">
73
- <svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
74
- <path fill-rule="evenodd" d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z" clip-rule="evenodd" />
75
- </svg>
76
- </div>
77
- </div>
78
- <div class="course-meta hidden">
79
- <div class="bg-gradient-to-r from-gray-50 to-white rounded-xl p-4 border border-gray-100">
80
- <div class="flex justify-between items-center">
81
- <span id="course-author" class="flex items-center space-x-2">
82
- <svg class="h-5 w-5 text-violet-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
83
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
84
- </svg>
85
- <span class="text-gray-600"></span>
86
- </span>
87
- <span id="course-date" class="flex items-center space-x-2">
88
- <svg class="h-5 w-5 text-violet-500" fill="none" stroke="currentColor" viewBox="0 0 24 24">
89
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" />
90
- </svg>
91
- <span class="text-gray-600"></span>
92
- </span>
93
- </div>
94
- </div>
95
- </div>
96
- </div>
97
 
98
- <!-- Question Input -->
99
- <div class="space-y-3">
100
- <label class="block text-sm font-medium text-gray-700">Sujet de dissertation</label>
101
- <div class="relative">
102
- <textarea id="question" rows="4"
103
- class="w-full rounded-xl border-gray-200 shadow-sm focus:border-violet-500 focus:ring-violet-500 resize-none bg-white py-3 px-4"
104
- placeholder="Saisissez votre sujet de dissertation..."></textarea>
105
- <div class="absolute bottom-3 right-3 flex items-center space-x-2 text-gray-400">
106
- <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
107
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15.232 5.232l3.536 3.536m-2.036-5.036a2.5 2.5 0 113.536 3.536L6.5 21.036H3v-3.572L16.732 3.732z" />
108
- </svg>
109
- </div>
110
- </div>
111
- </div>
112
 
113
- <!-- Submit Button -->
114
- <button id="submit-btn" class="w-full py-4 px-6 rounded-xl bg-gradient-to-r from-violet-600 to-indigo-600 text-white font-medium shadow-lg shadow-violet-200 hover:shadow-xl hover:shadow-violet-300 transform hover:-translate-y-0.5 transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-violet-500 focus:ring-offset-2">
115
- <span class="flex items-center justify-center space-x-2">
116
- <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
117
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z" />
118
- </svg>
119
- <span>Générer la dissertation</span>
120
- </span>
121
- </button>
122
 
123
- <!-- Response Section -->
124
- <div id="response" class="hidden mt-8 prose prose-violet max-w-none">
125
- <div class="bg-gradient-to-r from-gray-50 to-white rounded-xl p-6 border border-gray-100">
126
- <!-- La réponse sera insérée ici -->
127
- </div>
128
- </div>
129
 
130
- <!-- Copy Button -->
131
- <button id="copy-btn" class="hidden w-full py-3 px-6 rounded-xl bg-gray-50 text-gray-700 font-medium border border-gray-200 hover:bg-gray-100 transform hover:-translate-y-0.5 transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2">
132
- <span class="flex items-center justify-center space-x-2">
133
- <svg class="h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24">
134
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" />
135
- </svg>
136
- <span>Copier la dissertation</span>
137
- </span>
138
- </button>
139
- </div>
140
- </div>
141
  </div>
142
  </div>
143
 
144
  <script>
145
  $(document).ready(function() {
146
- // Configuration de marked avec support de la syntaxe GFM
147
  marked.setOptions({
148
  breaks: true,
149
  gfm: true,
150
  headerIds: true,
151
- langPrefix: 'language-',
152
- smartLists: true,
153
- smartypants: true
154
  });
155
 
156
- // Configuration des notifications
157
  const Toast = Swal.mixin({
158
  toast: true,
159
  position: 'top-end',
160
  showConfirmButton: false,
161
  timer: 3000,
162
- timerProgressBar: true,
163
- customClass: {
164
- popup: 'rounded-lg shadow-xl border border-gray-100'
165
- }
166
  });
167
 
168
- // Animation des boutons
169
- function addButtonAnimation(buttonId) {
170
- $(`#${buttonId}`).on('mousedown', function() {
171
- $(this).addClass('scale-95');
172
- }).on('mouseup mouseleave', function() {
173
- $(this).removeClass('scale-95');
174
- });
175
- }
176
-
177
- addButtonAnimation('submit-btn');
178
- addButtonAnimation('copy-btn');
179
-
180
  // Gestion du changement de type
181
  $('#type-select').change(function() {
182
  const type = $(this).val();
183
- const labels = {
184
- '1': 'Dissertation classique',
185
- '2': 'Analyse comparative'
186
- };
187
- $('#current-type-label').text(`Type ${type} - ${labels[type]}`);
188
  });
189
 
190
- // Chargement des cours avec animation
191
- function loadCourses() {
192
- return $.ajax({
193
- url: '/api/philosophy/courses',
194
- method: 'GET',
195
- beforeSend: function() {
196
- $('#course-select').addClass('animate-pulse');
197
- },
198
- complete: function() {
199
- $('#course-select').removeClass('animate-pulse');
200
- }
201
- });
202
- }
203
-
204
- loadCourses()
205
- .done(function(courses) {
206
  const select = $('#course-select');
207
  courses.forEach(course => {
208
  select.append(`<option value="${course.id}">${course.title}</option>`);
209
  });
210
- })
211
- .fail(function() {
212
  Toast.fire({
213
  icon: 'error',
214
- title: 'Erreur de chargement des cours',
215
- text: 'Veuillez réessayer ultérieurement'
216
  });
217
- });
 
218
 
219
- // Gestion du changement de cours avec animations
220
  $('#course-select').change(function() {
221
  const courseId = $(this).val();
222
  if (courseId) {
223
  $.ajax({
224
  url: `/api/philosophy/courses/${courseId}`,
225
  method: 'GET',
226
- beforeSend: function() {
227
- $('.course-meta').addClass('animate-pulse');
228
- },
229
  success: function(course) {
230
- $('.course-meta').removeClass('hidden animate-pulse')
231
- .addClass('animate-fadeIn');
232
- $('#course-author span').text(`Pr. ${course.author}`);
233
- $('#course-date span').text(new Date(course.updated_at).toLocaleDateString('fr-FR', {
234
- day: 'numeric',
235
- month: 'long',
236
- year: 'numeric' }));
 
237
  },
238
  error: function() {
239
  Toast.fire({
240
  icon: 'error',
241
- title: 'Erreur',
242
- text: 'Impossible de charger les détails du cours'
243
  });
244
  }
245
  });
246
  } else {
247
- $('.course-meta').addClass('animate-fadeOut').on('animationend', function() {
248
- $(this).addClass('hidden').removeClass('animate-fadeOut');
249
- });
250
  }
251
  });
252
 
253
- // Gestion de la soumission avec animations avancées
254
  $('#submit-btn').click(function() {
255
  const question = $('#question').val().trim();
256
-
257
- if (!question) {
258
- // Animation de secousse sur le champ vide
259
- $('#question').addClass('animate-shake border-red-300');
260
- setTimeout(() => {
261
- $('#question').removeClass('animate-shake border-red-300');
262
- }, 1000);
263
 
 
264
  Swal.fire({
265
  icon: 'warning',
266
- title: 'Champ requis',
267
- text: 'Veuillez saisir votre sujet de dissertation',
268
- showClass: {
269
- popup: 'animate__animated animate__fadeInDown'
270
- },
271
- hideClass: {
272
- popup: 'animate__animated animate__fadeOutUp'
273
- },
274
- customClass: {
275
- popup: 'rounded-2xl',
276
- confirmButton: 'bg-violet-600 hover:bg-violet-700 text-white font-medium py-2 px-4 rounded-lg transition-colors duration-200'
277
- }
278
  });
279
  return;
280
  }
281
 
282
- // Animation de chargement sophistiquée
283
  Swal.fire({
284
- title: 'Génération en cours',
285
- html: `
286
- <div class="space-y-4">
287
- <div class="flex justify-center">
288
- <div class="w-16 h-16 relative">
289
- <div class="absolute inset-0 rounded-full border-4 border-violet-200 animate-ping"></div>
290
- <div class="absolute inset-0 rounded-full border-4 border-violet-500 animate-pulse"></div>
291
- </div>
292
- </div>
293
- <div class="text-gray-600">
294
- <p class="animate-pulse">Analyse philosophique en cours...</p>
295
- <p class="text-sm mt-2 text-gray-500">Veuillez patienter quelques instants</p>
296
- </div>
297
- </div>
298
- `,
299
  allowOutsideClick: false,
300
- showConfirmButton: false,
301
- customClass: {
302
- popup: 'rounded-2xl'
303
  }
304
  });
305
 
 
306
  const data = {
307
  question: question,
308
- type: $('#type-select').val(),
309
- courseId: $('#course-select').val() || null
310
  };
311
 
 
 
 
 
 
 
312
  $.ajax({
313
  url: '/submit_philo',
314
  method: 'POST',
@@ -316,113 +329,41 @@
316
  data: JSON.stringify(data),
317
  success: function(data) {
318
  Swal.close();
319
-
320
- // Conversion et animation de la réponse
321
  const htmlContent = marked.parse(data.response);
322
- $('#response')
323
- .html(htmlContent)
324
- .removeClass('hidden')
325
- .addClass('animate-fadeIn');
326
-
327
- // Animation du bouton de copie
328
- $('#copy-btn')
329
- .removeClass('hidden')
330
- .addClass('animate-slideUp');
331
-
332
- // Scroll smooth vers la réponse
333
- $('html, body').animate({
334
- scrollTop: $('#response').offset().top - 100
335
- }, 800);
336
-
337
  Toast.fire({
338
  icon: 'success',
339
- title: 'Dissertation générée avec succès',
340
- timer: 2000
341
  });
342
  },
343
- error: function() {
344
  Swal.fire({
345
  icon: 'error',
346
- title: 'Erreur de génération',
347
- text: 'Une erreur est survenue lors de la génération de votre dissertation.',
348
- customClass: {
349
- popup: 'rounded-2xl',
350
- confirmButton: 'bg-violet-600 hover:bg-violet-700 text-white font-medium py-2 px-4 rounded-lg transition-colors duration-200'
351
- }
352
  });
353
  }
354
  });
355
  });
356
 
357
- // Gestion de la copie avec retour visuel amélioré
358
  $('#copy-btn').click(function() {
359
  const response = $('#response').text();
360
-
361
- // Animation du bouton pendant la copie
362
- $(this).addClass('scale-95 bg-violet-100');
363
-
364
- navigator.clipboard.writeText(response)
365
- .then(() => {
366
- // Success animation
367
- $(this).removeClass('scale-95 bg-violet-100')
368
- .addClass('bg-green-50 text-green-700');
369
-
370
- setTimeout(() => {
371
- $(this).removeClass('bg-green-50 text-green-700');
372
- }, 1000);
373
-
374
- Toast.fire({
375
- icon: 'success',
376
- title: 'Copié avec succès',
377
- text: 'Le contenu a été copié dans votre presse-papiers',
378
- timer: 2000
379
- });
380
- })
381
- .catch(() => {
382
- // Error animation
383
- $(this).removeClass('scale-95 bg-violet-100')
384
- .addClass('bg-red-50 text-red-700');
385
-
386
- setTimeout(() => {
387
- $(this).removeClass('bg-red-50 text-red-700');
388
- }, 1000);
389
-
390
- Toast.fire({
391
- icon: 'error',
392
- title: 'Erreur de copie',
393
- text: 'Impossible de copier le contenu',
394
- timer: 3000
395
- });
396
  });
 
397
  });
398
-
399
- // Ajout des styles d'animation personnalisés
400
- const style = document.createElement('style');
401
- style.textContent = `
402
- @keyframes fadeIn {
403
- from { opacity: 0; transform: translateY(10px); }
404
- to { opacity: 1; transform: translateY(0); }
405
- }
406
- @keyframes slideUp {
407
- from { opacity: 0; transform: translateY(20px); }
408
- to { opacity: 1; transform: translateY(0); }
409
- }
410
- @keyframes shake {
411
- 0%, 100% { transform: translateX(0); }
412
- 25% { transform: translateX(-5px); }
413
- 75% { transform: translateX(5px); }
414
- }
415
- .animate-fadeIn {
416
- animation: fadeIn 0.5s ease-out forwards;
417
- }
418
- .animate-slideUp {
419
- animation: slideUp 0.5s ease-out forwards;
420
- }
421
- .animate-shake {
422
- animation: shake 0.5s ease-in-out;
423
- }
424
- `;
425
- document.head.appendChild(style);
426
  });
427
  </script>
428
  </body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Philosophie</title>
7
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.7.3/sweetalert2.all.min.js"></script>
9
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.3.0/marked.min.js"></script>
10
  <link href="https://cdnjs.cloudflare.com/ajax/libs/sweetalert2/11.7.3/sweetalert2.min.css" rel="stylesheet">
11
+ <style>
12
+ .container {
13
+ max-width: 800px;
14
+ margin: 0 auto;
15
+ padding: 20px;
16
+ }
17
+ .card {
18
+ background: white;
19
+ border-radius: 8px;
20
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
21
+ padding: 20px;
22
+ }
23
+ .form-group {
24
+ margin-bottom: 20px;
25
+ }
26
+ .btn {
27
+ padding: 10px 20px;
28
+ border: none;
29
+ border-radius: 4px;
30
+ cursor: pointer;
31
+ margin-right: 10px;
32
+ font-weight: bold;
33
+ }
34
+ .btn-primary {
35
+ background-color: #4A90E2;
36
+ color: white;
37
+ }
38
+ .btn-secondary {
39
+ background-color: #6c757d;
40
+ color: white;
41
+ }
42
+ .btn-success {
43
+ background-color: #28a745;
44
+ color: white;
45
+ }
46
+ .select-wrapper {
47
+ margin-bottom: 20px;
48
+ }
49
+ select, textarea {
50
+ width: 100%;
51
+ padding: 8px;
52
+ border: 1px solid #ddd;
53
+ border-radius: 4px;
54
+ margin-top: 5px;
55
+ }
56
+ .hidden {
57
+ display: none;
58
+ }
59
+ #loader {
60
+ text-align: center;
61
+ padding: 20px;
62
+ }
63
+ #response {
64
+ margin-top: 20px;
65
+ padding: 15px;
66
+ background: #f8f9fa;
67
+ border-radius: 4px;
68
+ line-height: 1.6;
69
+ }
70
+ .course-info {
71
+ margin-top: 10px;
72
+ font-size: 0.9em;
73
+ color: #666;
74
+ }
75
+ .course-meta {
76
+ display: flex;
77
+ justify-content: space-between;
78
+ margin-bottom: 10px;
79
+ padding: 5px;
80
+ background: #f8f9fa;
81
+ border-radius: 4px;
82
+ }
83
+ .type-label {
84
+ background: #4A90E2;
85
+ color: white;
86
+ padding: 5px 10px;
87
+ border-radius: 4px;
88
+ margin-bottom: 15px;
89
+ display: inline-block;
90
+ }
91
+
92
+ /* Styles Markdown */
93
+ #response h1 {
94
+ font-size: 2em;
95
+ margin-bottom: 0.5em;
96
+ border-bottom: 2px solid #eee;
97
+ padding-bottom: 0.3em;
98
+ }
99
+ #response h2 {
100
+ font-size: 1.5em;
101
+ margin-bottom: 0.5em;
102
+ border-bottom: 1px solid #eee;
103
+ padding-bottom: 0.3em;
104
+ }
105
+ #response h3 {
106
+ font-size: 1.3em;
107
+ margin-bottom: 0.5em;
108
+ }
109
+ #response p {
110
+ margin-bottom: 1em;
111
+ }
112
+ #response ul, #response ol {
113
+ margin-bottom: 1em;
114
+ padding-left: 2em;
115
+ }
116
+ #response li {
117
+ margin-bottom: 0.5em;
118
+ }
119
+ #response blockquote {
120
+ border-left: 4px solid #ddd;
121
+ padding-left: 1em;
122
+ margin-left: 0;
123
+ color: #666;
124
+ }
125
+ #response code {
126
+ background-color: #f5f5f5;
127
+ padding: 0.2em 0.4em;
128
+ border-radius: 3px;
129
+ font-family: monospace;
130
+ }
131
+ #response pre {
132
+ background-color: #f5f5f5;
133
+ padding: 1em;
134
+ border-radius: 4px;
135
+ overflow-x: auto;
136
+ margin-bottom: 1em;
137
+ }
138
+ #response pre code {
139
+ background-color: transparent;
140
+ padding: 0;
141
+ }
142
+ #response table {
143
+ border-collapse: collapse;
144
+ width: 100%;
145
+ margin-bottom: 1em;
146
+ }
147
+ #response th, #response td {
148
+ border: 1px solid #ddd;
149
+ padding: 8px;
150
+ text-align: left;
151
+ }
152
+ #response th {
153
+ background-color: #f5f5f5;
154
+ }
155
+ #response img {
156
+ max-width: 100%;
157
+ height: auto;
158
+ }
159
+ #response hr {
160
+ border: none;
161
+ border-top: 1px solid #ddd;
162
+ margin: 1em 0;
163
+ }
164
+ </style>
165
  </head>
166
+ <body>
167
+ <div class="container">
168
+ <div class="card">
169
+ <h1 class="text-3xl font-bold text-gray-800">Philosophie</h1>
170
+
171
+ <!-- Sélection du type de dissertation -->
172
+ <div class="form-group">
173
+ <label for="type-select">Type de dissertation :</label>
174
+ <select id="type-select" class="form-control">
175
+ <option value="1">Type 1 </option>
176
+ <option value="2">Type 2 </option>
177
+ </select>
 
 
 
 
178
  </div>
 
 
179
 
180
+ <div class="type-label" id="current-type-label">Sujet de type 1</div>
 
 
 
 
 
 
 
 
 
181
 
182
+ <!-- Sélection du cours -->
183
+ <div class="form-group">
184
+ <label for="course-select">Sélectionner un cours :</label>
185
+ <select id="course-select" class="form-control">
186
+ <option value="">Choisir un cours...</option>
187
+ </select>
188
+ <div class="course-info">
189
+ <div class="course-meta hidden">
190
+ <span id="course-author"></span>
191
+ <span id="course-date"></span>
 
 
 
 
 
 
 
 
 
192
  </div>
193
+ </div>
194
+ </div>
195
 
196
+ <!-- Zone de texte pour la question -->
197
+ <div class="form-group">
198
+ <label for="question">Entrez juste le sujet :</label>
199
+ <textarea id="question" rows="4" class="form-control"></textarea>
200
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
 
202
+ <!-- Bouton de soumission -->
203
+ <button id="submit-btn" class="btn btn-success">Soumettre</button>
 
 
 
 
 
 
 
 
 
 
 
 
204
 
205
+ <!-- Loader -->
206
+ <div id="loader" class="hidden">
207
+ Chargement en cours...
208
+ </div>
 
 
 
 
 
209
 
210
+ <!-- Zone de réponse -->
211
+ <div id="response" class="hidden"></div>
 
 
 
 
212
 
213
+ <!-- Bouton de copie -->
214
+ <button id="copy-btn" class="btn btn-secondary hidden">Copier la réponse</button>
 
 
 
 
 
 
 
 
 
215
  </div>
216
  </div>
217
 
218
  <script>
219
  $(document).ready(function() {
220
+ // Configuration de marked
221
  marked.setOptions({
222
  breaks: true,
223
  gfm: true,
224
  headerIds: true,
225
+ langPrefix: 'language-'
 
 
226
  });
227
 
228
+ // Configuration des toasts SweetAlert2
229
  const Toast = Swal.mixin({
230
  toast: true,
231
  position: 'top-end',
232
  showConfirmButton: false,
233
  timer: 3000,
234
+ timerProgressBar: true
 
 
 
235
  });
236
 
 
 
 
 
 
 
 
 
 
 
 
 
237
  // Gestion du changement de type
238
  $('#type-select').change(function() {
239
  const type = $(this).val();
240
+ $('#current-type-label').text(`Sujet de type ${type}`);
 
 
 
 
241
  });
242
 
243
+ // Charger les cours depuis la base de données
244
+ $.ajax({
245
+ url: '/api/philosophy/courses',
246
+ method: 'GET',
247
+ success: function(courses) {
 
 
 
 
 
 
 
 
 
 
 
248
  const select = $('#course-select');
249
  courses.forEach(course => {
250
  select.append(`<option value="${course.id}">${course.title}</option>`);
251
  });
252
+ },
253
+ error: function() {
254
  Toast.fire({
255
  icon: 'error',
256
+ title: 'Erreur lors du chargement des cours'
 
257
  });
258
+ }
259
+ });
260
 
261
+ // Gestion du changement de cours
262
  $('#course-select').change(function() {
263
  const courseId = $(this).val();
264
  if (courseId) {
265
  $.ajax({
266
  url: `/api/philosophy/courses/${courseId}`,
267
  method: 'GET',
 
 
 
268
  success: function(course) {
269
+ $('.course-meta').removeClass('hidden');
270
+ $('#course-author').text(`Professeur: ${course.author}`);
271
+ $('#course-date').text(`Mis à jour: ${new Date(course.updated_at).toLocaleDateString()}`);
272
+
273
+ Toast.fire({
274
+ icon: 'success',
275
+ title: 'Cours chargé avec succès'
276
+ });
277
  },
278
  error: function() {
279
  Toast.fire({
280
  icon: 'error',
281
+ title: 'Erreur lors du chargement des détails du cours'
 
282
  });
283
  }
284
  });
285
  } else {
286
+ $('.course-meta').addClass('hidden');
 
 
287
  }
288
  });
289
 
290
+ // Gestion de la soumission
291
  $('#submit-btn').click(function() {
292
  const question = $('#question').val().trim();
293
+ const type = $('#type-select').val();
 
 
 
 
 
 
294
 
295
+ if (!question) {
296
  Swal.fire({
297
  icon: 'warning',
298
+ title: 'Attention',
299
+ text: 'Veuillez saisir une question.'
 
 
 
 
 
 
 
 
 
 
300
  });
301
  return;
302
  }
303
 
 
304
  Swal.fire({
305
+ title: 'Generation en cours',
306
+ html: 'Veuillez patienter...',
 
 
 
 
 
 
 
 
 
 
 
 
 
307
  allowOutsideClick: false,
308
+ didOpen: () => {
309
+ Swal.showLoading();
 
310
  }
311
  });
312
 
313
+ // Préparation des données
314
  const data = {
315
  question: question,
316
+ type: type
 
317
  };
318
 
319
+ // Ajout du courseId seulement s'il est sélectionné
320
+ const courseId = $('#course-select').val();
321
+ if (courseId) {
322
+ data.courseId = courseId;
323
+ }
324
+
325
  $.ajax({
326
  url: '/submit_philo',
327
  method: 'POST',
 
329
  data: JSON.stringify(data),
330
  success: function(data) {
331
  Swal.close();
332
+ // Conversion du Markdown en HTML
 
333
  const htmlContent = marked.parse(data.response);
334
+ $('#response').html(htmlContent).removeClass('hidden');
335
+ $('#copy-btn').removeClass('hidden');
336
+
 
 
 
 
 
 
 
 
 
 
 
 
337
  Toast.fire({
338
  icon: 'success',
339
+ title: 'Réponse générée avec succès'
 
340
  });
341
  },
342
+ error: function(xhr) {
343
  Swal.fire({
344
  icon: 'error',
345
+ title: 'Erreur',
346
+ text: 'Une erreur est survenue lors de la génération de la réponse.'
 
 
 
 
347
  });
348
  }
349
  });
350
  });
351
 
352
+ // Gestion de la copie de la réponse
353
  $('#copy-btn').click(function() {
354
  const response = $('#response').text();
355
+ navigator.clipboard.writeText(response).then(function() {
356
+ Toast.fire({
357
+ icon: 'success',
358
+ title: 'Réponse copiée avec succès'
359
+ });
360
+ }).catch(function() {
361
+ Toast.fire({
362
+ icon: 'error',
363
+ title: 'Erreur lors de la copie'
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
  });
365
+ });
366
  });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
367
  });
368
  </script>
369
  </body>