Docfile commited on
Commit
7392e10
·
verified ·
1 Parent(s): 810e88c

Update templates/philosophie.html

Browse files
Files changed (1) hide show
  1. templates/philosophie.html +128 -347
templates/philosophie.html CHANGED
@@ -3,376 +3,157 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Assistant de Philosophie</title>
7
 
8
- <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
9
- <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
 
 
 
 
 
 
10
 
11
  <style>
12
- /* --- Styles Généraux et Interface --- */
13
- body {
14
- font-family: Arial, sans-serif;
15
- background-color: #f4f4f9;
16
- margin: 0;
17
- padding: 20px;
18
- color: #333;
19
- }
20
- .container {
21
- max-width: 900px;
22
- margin: 0 auto;
23
- background: white;
24
- padding: 30px;
25
- border-radius: 8px;
26
- box-shadow: 0 4px 10px rgba(0,0,0,0.1);
27
- }
28
- h1 {
29
- text-align: center;
30
- color: #2c3e50;
31
- }
32
- textarea {
33
- width: 100%;
34
- padding: 10px;
35
- border-radius: 4px;
36
- border: 1px solid #ddd;
37
- min-height: 80px;
38
- margin-bottom: 10px;
39
- font-size: 16px;
40
- box-sizing: border-box;
41
- }
42
- button {
43
- display: block;
44
- width: 100%;
45
- padding: 15px;
46
- background-color: #2980b9;
47
- color: white;
48
- border: none;
49
- border-radius: 5px;
50
- font-size: 18px;
51
- cursor: pointer;
52
- transition: background-color 0.3s;
53
- }
54
  button:hover { background-color: #3498db; }
55
  button:disabled { background-color: #95a5a6; cursor: not-allowed; }
56
-
57
- .loader {
58
- display: none;
59
- border: 8px solid #f3f3f3;
60
- border-top: 8px solid #3498db;
61
- border-radius: 50%;
62
- width: 50px;
63
- height: 50px;
64
- animation: spin 1s linear infinite;
65
- margin: 20px auto;
66
- }
67
  @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
68
- .error { color: #c0392b; text-align: center; margin-top: 20px; }
69
- .success { color: #27ae60; text-align: center; margin-top: 20px; }
70
-
71
- /* --- Styles du Rendu "Cahier" optimisés pour PDF --- */
72
- .dissertation-paper {
73
- font-family: 'Courier New', monospace;
74
- font-size: 14px;
75
- color: #1a2a4c;
76
- background-color: #fdfaf4;
77
- line-height: 24px;
78
- padding: 40px;
79
- margin: 40px -30px -30px -30px;
80
- position: relative;
81
- min-height: 800px;
82
-
83
- /* Simulation des lignes de cahier */
84
- background-image:
85
- linear-gradient(to right, #ffaaab 0px, #ffaaab 3px, transparent 3px),
86
- repeating-linear-gradient(
87
- transparent,
88
- transparent 23px,
89
- #d8e2ee 23px,
90
- #d8e2ee 24px
91
- );
92
- background-size: 100% 100%, 100% 24px;
93
- background-position: 0 0, 0 40px;
94
- }
95
-
96
- .dissertation-paper h2 {
97
- font-size: 18px;
98
- text-align: center;
99
- margin: 0 0 24px 0;
100
- font-weight: bold;
101
- text-decoration: underline;
102
- padding-left: 40px;
103
- }
104
-
105
- .dissertation-paper h3 {
106
- font-size: 16px;
107
- margin: 48px 0 24px 0;
108
- text-transform: uppercase;
109
- text-decoration: underline;
110
- font-weight: bold;
111
- padding-left: 40px;
112
- }
113
-
114
- .dissertation-paper .development-block {
115
- margin: 24px 0;
116
- }
117
-
118
- .dissertation-paper p {
119
- text-align: justify;
120
- margin: 0 0 24px 0;
121
- padding-left: 40px;
122
- }
123
-
124
- .dissertation-paper .prof {
125
- text-align: center;
126
- font-style: italic;
127
- margin: 0 0 24px 0;
128
- font-size: 12px;
129
- padding-left: 40px;
130
- }
131
-
132
- .dissertation-paper .indented {
133
- text-indent: 2em;
134
- }
135
-
136
- .dissertation-paper .transition {
137
- margin: 24px 0;
138
- font-style: italic;
139
- color: #4a6a9c;
140
- font-weight: 500;
141
- }
142
-
143
- .pdf-button-container {
144
- text-align: center;
145
- margin-top: 40px;
146
- background: white;
147
- padding: 20px;
148
- border-radius: 8px;
149
- }
150
-
151
- .pdf-button {
152
- font-family: Arial, sans-serif;
153
- font-size: 16px;
154
- padding: 12px 24px;
155
- width: auto;
156
- display: inline-block;
157
- background-color: #27ae60;
158
- }
159
-
160
- .pdf-button:hover {
161
- background-color: #2ecc71;
162
- }
163
-
164
- /* Style pour le PDF uniquement */
165
- .pdf-only {
166
- display: none;
167
- }
168
-
169
- /* Quand on génère le PDF, on cache le bouton et on montre le contenu PDF */
170
- .pdf-mode .pdf-button-container {
171
- display: none !important;
172
- }
173
-
174
- .pdf-mode .pdf-only {
175
- display: block !important;
176
- }
177
  </style>
178
  </head>
179
  <body>
180
 
181
- <div class="container">
 
182
  <h1>Assistant de Dissertation Philosophique</h1>
183
- <form id="philo-form">
184
- <textarea id="question" name="question" placeholder="Entrez votre sujet de dissertation ici... Par exemple : 'Sommes-nous toujours conscients ?'"></textarea>
185
- <button type="submit" id="submit-btn">Générer la dissertation</button>
 
 
 
 
 
 
186
  </form>
187
 
188
- <div id="loader" class="loader"></div>
189
- <div id="result-container"></div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
190
  </div>
191
 
192
  <script>
193
- document.addEventListener('DOMContentLoaded', () => {
194
- const form = document.getElementById('philo-form');
195
- const submitBtn = document.getElementById('submit-btn');
196
- const loader = document.getElementById('loader');
197
- const resultContainer = document.getElementById('result-container');
198
-
199
- form.addEventListener('submit', async (event) => {
200
- event.preventDefault();
201
- const question = document.getElementById('question').value.trim();
202
-
203
- if (!question) {
204
- showError("Veuillez entrer un sujet de dissertation.");
205
- return;
206
  }
207
-
208
- simulateGeneration(question);
209
- });
210
-
211
- function simulateGeneration(question) {
212
- submitBtn.disabled = true;
213
- submitBtn.textContent = 'Génération en cours...';
214
- loader.style.display = 'block';
215
- resultContainer.innerHTML = '';
216
-
217
- setTimeout(() => {
218
- const mockData = {
219
- sujet: question,
220
- prof: "M. Dupont",
221
- introduction: "L'introduction de cette dissertation explore les différentes dimensions du sujet proposé. Nous commençons par définir les termes clés et établir la problématique qui guidera notre réflexion. Cette question soulève des enjeux philosophiques fondamentaux que nous devrons examiner avec rigueur.",
222
- parties: [
223
- {
224
- chapeau: "Dans un premier temps, nous examinerons la dimension théorique de cette question.",
225
- arguments: [
226
- {
227
- paragraphe_argumentatif: "Premier argument : Cette perspective nous permet de comprendre les fondements conceptuels du problème. En effet, l'analyse théorique révèle des aspects souvent négligés dans l'approche commune de cette question."
228
- },
229
- {
230
- paragraphe_argumentatif: "Deuxième argument : L'examen des sources philosophiques classiques nous éclaire sur les différentes interprétations possibles. Les penseurs comme Descartes, Kant ou Nietzsche ont chacun apporté des éléments de réponse qui méritent d'être confrontés."
231
- }
232
- ],
233
- transition: "Cependant, cette approche théorique trouve ses limites, ce qui nous amène à considérer une perspective plus pratique."
234
- },
235
- {
236
- chapeau: "Dans un second temps, nous analyserons les implications pratiques et concrètes.",
237
- arguments: [
238
- {
239
- paragraphe_argumentatif: "L'expérience quotidienne nous confronte à des situations qui remettent en question les conclusions purement théoriques. La réalité vécue apporte une richesse d'exemples qui nuancent notre compréhension initiale."
240
- },
241
- {
242
- paragraphe_argumentatif: "Les applications contemporaines de cette réflexion philosophique montrent l'actualité et la pertinence du questionnement. Dans notre société moderne, ces enjeux prennent une dimension particulière qu'il convient d'examiner."
243
- }
244
- ]
245
- }
246
- ],
247
- conclusion: "En conclusion, cette dissertation a permis d'explorer les multiples facettes du sujet proposé. Nous avons vu que l'approche théorique, bien qu'essentielle, doit être complétée par une analyse pratique pour saisir toute la complexité de la question. Cette réflexion ouvre de nouvelles perspectives et invite à poursuivre l'investigation philosophique sur ces thèmes fondamentaux."
248
- };
249
-
250
- renderDissertation(mockData);
251
-
252
- submitBtn.disabled = false;
253
- submitBtn.textContent = 'Générer la dissertation';
254
- loader.style.display = 'none';
255
- }, 2000);
256
- }
257
-
258
- function renderDissertation(data) {
259
- let html = `
260
- <div id="dissertation-content" class="dissertation-paper">
261
- <h2>Sujet : ${data.sujet}</h2>
262
- <p class="prof">Prof : ${data.prof}</p>
263
- <h3>Introduction</h3>
264
- <p class="indented">${data.introduction}</p>
265
- `;
266
-
267
- data.parties.forEach((partie, index) => {
268
- html += `<div class="development-block">`;
269
- html += `<p class="indented">${partie.chapeau}</p>`;
270
- partie.arguments.forEach(arg => {
271
- html += `<p class="indented">${arg.paragraphe_argumentatif}</p>`;
272
- });
273
- html += `</div>`;
274
-
275
- if (partie.transition) {
276
- html += `<p class="indented transition">${partie.transition}</p>`;
277
  }
278
- });
279
-
280
- html += `
281
- <h3>Conclusion</h3>
282
- <p class="indented">${data.conclusion}</p>
283
- </div>
284
- <div class="pdf-button-container">
285
- <button class="pdf-button" id="download-pdf">Télécharger en PDF</button>
286
- </div>
287
- `;
288
-
289
- resultContainer.innerHTML = html;
290
- document.getElementById('download-pdf').addEventListener('click', generatePDF);
291
- }
292
-
293
- async function generatePDF() {
294
- const dissertationElement = document.getElementById('dissertation-content');
295
- const button = document.getElementById('download-pdf');
296
-
297
- // Désactiver le bouton et changer le texte
298
- button.disabled = true;
299
- button.textContent = 'Génération en cours...';
300
-
301
- try {
302
- // Ajouter la classe pdf-mode pour cacher le bouton
303
- document.body.classList.add('pdf-mode');
304
-
305
- // Attendre un peu pour que les styles se stabilisent
306
- await new Promise(resolve => setTimeout(resolve, 100));
307
 
308
- // Générer le canvas avec html2canvas
309
- const canvas = await html2canvas(dissertationElement, {
310
- scale: 2,
311
- useCORS: true,
312
- allowTaint: true,
313
- backgroundColor: '#fdfaf4',
314
- width: dissertationElement.scrollWidth,
315
- height: dissertationElement.scrollHeight,
316
- logging: false
317
- });
318
-
319
- // Créer le PDF avec jsPDF
320
- const { jsPDF } = window.jspdf;
321
- const imgData = canvas.toDataURL('image/png');
322
-
323
- // Calculer les dimensions pour le PDF
324
- const imgWidth = 210; // A4 width in mm
325
- const pageHeight = 295; // A4 height in mm
326
- const imgHeight = (canvas.height * imgWidth) / canvas.width;
327
- let heightLeft = imgHeight;
328
-
329
- const doc = new jsPDF('p', 'mm', 'a4');
330
- let position = 0;
331
-
332
- // Ajouter la première page
333
- doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
334
- heightLeft -= pageHeight;
335
-
336
- // Ajouter des pages supplémentaires si nécessaire
337
- while (heightLeft >= 0) {
338
- position = heightLeft - imgHeight;
339
- doc.addPage();
340
- doc.addImage(imgData, 'PNG', 0, position, imgWidth, imgHeight);
341
- heightLeft -= pageHeight;
342
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
343
 
344
- // Sauvegarder le PDF
345
- doc.save('dissertation-philosophie.pdf');
346
- showSuccess("PDF généré avec succès !");
347
-
348
- } catch (error) {
349
- console.error('Erreur lors de la génération du PDF:', error);
350
- showError('Erreur lors de la génération du PDF. Veuillez réessayer.');
351
- } finally {
352
- // Retirer la classe pdf-mode et réactiver le bouton
353
- document.body.classList.remove('pdf-mode');
354
- button.disabled = false;
355
- button.textContent = 'Télécharger en PDF';
356
  }
357
  }
358
-
359
- function showError(message) {
360
- resultContainer.innerHTML += `<p class="error">${message}</p>`;
361
- }
362
-
363
- function showSuccess(message) {
364
- const successDiv = document.createElement('div');
365
- successDiv.className = 'success';
366
- successDiv.textContent = message;
367
- resultContainer.appendChild(successDiv);
368
-
369
- setTimeout(() => {
370
- if (successDiv.parentNode) {
371
- successDiv.remove();
372
- }
373
- }, 3000);
374
- }
375
- });
376
  </script>
377
 
378
  </body>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Assistant de Philosophie (Vue.js)</title>
7
 
8
+ <!-- Importation de Vue.js et html2pdf.js via CDN -->
9
+ <script src="https://unpkg.com/vue@3"></script>
10
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/html2pdf.js/0.10.1/html2pdf.bundle.min.js"></script>
11
+
12
+ <!-- Importation des polices -->
13
+ <link rel="preconnect" href="https://fonts.googleapis.com">
14
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
15
+ <link href="https://fonts.googleapis.com/css2?family=Kalam&family=Lato:wght@400;700&display=swap" rel="stylesheet">
16
 
17
  <style>
18
+ /* Les styles CSS sont identiques à la version précédente */
19
+ body { font-family: 'Lato', sans-serif; background-color: #f4f4f9; margin: 0; padding: 20px; color: #333; }
20
+ .container { max-width: 900px; margin: 0 auto; background: white; padding: 30px; border-radius: 8px; box-shadow: 0 4px 10px rgba(0,0,0,0.1); }
21
+ h1 { text-align: center; color: #2c3e50; }
22
+ textarea { width: 100%; padding: 10px; border-radius: 4px; border: 1px solid #ddd; min-height: 80px; margin-bottom: 10px; font-size: 16px; }
23
+ button { display: block; width: 100%; padding: 15px; background-color: #2980b9; color: white; border: none; border-radius: 5px; font-size: 18px; cursor: pointer; transition: background-color 0.3s; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  button:hover { background-color: #3498db; }
25
  button:disabled { background-color: #95a5a6; cursor: not-allowed; }
26
+ .loader { display: block; border: 8px solid #f3f3f3; border-top: 8px solid #3498db; border-radius: 50%; width: 50px; height: 50px; animation: spin 1s linear infinite; margin: 20px auto; }
 
 
 
 
 
 
 
 
 
 
27
  @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } }
28
+ .error { color: #c0392b; text-align: center; margin-top: 20px; font-weight: bold; }
29
+ .dissertation-paper { font-family: 'Kalam', cursive; font-size: 20px; color: #1a2a4c; background-color: #fdfaf4; line-height: 1.8; background-image: linear-gradient(transparent 97%, #d8e2ee 98%); background-size: 100% 36px; border-left: 2px solid #ffaaab; padding-left: 4em; margin: 40px -30px -30px -30px; padding-top: 30px; padding-bottom: 30px; padding-right: 30px; }
30
+ .dissertation-paper h2 { font-size: 1.5em; text-align: center; margin-bottom: 1.8em; }
31
+ .dissertation-paper h3 { font-size: 1.2em; margin-top: 3.6em; margin-bottom: 1.8em; text-transform: uppercase; text-decoration: underline; }
32
+ .dissertation-paper .development-block { margin-top: 3.6em; }
33
+ .dissertation-paper p { text-align: justify; margin: 0; padding: 0; }
34
+ .dissertation-paper .prof { text-align: center; font-style: italic; margin-bottom: 1.8em; }
35
+ .dissertation-paper .indented { text-indent: 3em; }
36
+ .dissertation-paper .transition { margin-top: 1.8em; margin-bottom: 1.8em; font-style: italic; color: #4a6a9c; }
37
+ .dissertation-paper .pdf-button-container { text-align: center; margin-top: 3.6em; }
38
+ .dissertation-paper .pdf-button { font-family: 'Lato', sans-serif; font-size: 16px; padding: 10px 20px; width: auto; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  </style>
40
  </head>
41
  <body>
42
 
43
+ <!-- L'application Vue est montée sur cet élément -->
44
+ <div id="app" class="container">
45
  <h1>Assistant de Dissertation Philosophique</h1>
46
+
47
+ <!-- Le formulaire est maintenant géré par Vue -->
48
+ <form @submit.prevent="generateDissertation">
49
+ <textarea v-model="question" placeholder="Entrez votre sujet de dissertation ici..."></textarea>
50
+
51
+ <!-- Le bouton est désactivé et son texte change en fonction de l'état 'isLoading' -->
52
+ <button type="submit" :disabled="isLoading">
53
+ {{ isLoading ? 'Génération en cours...' : 'Générer la dissertation' }}
54
+ </button>
55
  </form>
56
 
57
+ <!-- Affiche le loader si 'isLoading' est vrai -->
58
+ <div v-if="isLoading" class="loader"></div>
59
+
60
+ <!-- Affiche un message d'erreur s'il y en a un -->
61
+ <p v-if="errorMessage" class="error">{{ errorMessage }}</p>
62
+
63
+ <!-- Le rendu de la dissertation n'apparaît que si l'objet 'dissertation' existe -->
64
+ <div v-if="dissertation" id="dissertation-content" class="dissertation-paper">
65
+ <h2>Sujet : {{ dissertation.sujet }}</h2>
66
+ <p class="prof">Prof : {{ dissertation.prof }}</p>
67
+
68
+ <h3>Introduction</h3>
69
+ <p class="indented">{{ dissertation.introduction }}</p>
70
+
71
+ <!-- On boucle sur les parties avec v-for -->
72
+ <div v-for="partie in dissertation.parties" :key="partie.chapeau">
73
+ <div class="development-block">
74
+ <p class="indented">{{ partie.chapeau }}</p>
75
+ <!-- On boucle sur les arguments de chaque partie -->
76
+ <p v-for="arg in partie.arguments" :key="arg.paragraphe_argumentatif" class="indented">
77
+ {{ arg.paragraphe_argumentatif }}
78
+ </p>
79
+ </div>
80
+ <p v-if="partie.transition" class="indented transition">{{ partie.transition }}</p>
81
+ </div>
82
+
83
+ <h3>Conclusion</h3>
84
+ <p class="indented">{{ dissertation.conclusion }}</p>
85
+
86
+ <div class="pdf-button-container" data-html2canvas-ignore="true">
87
+ <button class="pdf-button" @click="generatePDF">Télécharger en PDF</button>
88
+ </div>
89
+ </div>
90
  </div>
91
 
92
  <script>
93
+ const { createApp } = Vue;
94
+
95
+ createApp({
96
+ // --- DATA : L'état de notre application ---
97
+ data() {
98
+ return {
99
+ question: '', // Lié au textarea avec v-model
100
+ isLoading: false, // Gère l'affichage du loader et l'état du bouton
101
+ errorMessage: null, // Pour afficher les erreurs
102
+ dissertation: null // Contiendra les données JSON du backend
 
 
 
103
  }
104
+ },
105
+ // --- METHODS : Les actions de notre application ---
106
+ methods: {
107
+ async generateDissertation() {
108
+ if (!this.question.trim()) {
109
+ this.errorMessage = "Veuillez entrer un sujet de dissertation.";
110
+ return;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
 
113
+ // Réinitialisation de l'état
114
+ this.isLoading = true;
115
+ this.errorMessage = null;
116
+ this.dissertation = null;
117
+
118
+ try {
119
+ const response = await fetch('/api/generate_dissertation', {
120
+ method: 'POST',
121
+ headers: { 'Content-Type': 'application/json' },
122
+ body: JSON.stringify({ question: this.question })
123
+ });
124
+
125
+ const data = await response.json();
126
+
127
+ if (!response.ok) {
128
+ throw new Error(data.error || "Une erreur inconnue est survenue.");
129
+ }
130
+
131
+ // Succès : on met à jour la donnée 'dissertation', Vue mettra à jour l'affichage
132
+ this.dissertation = data;
133
+
134
+ } catch (error) {
135
+ this.errorMessage = error.message;
136
+ } finally {
137
+ this.isLoading = false;
 
 
 
 
 
 
 
 
 
138
  }
139
+ },
140
+ generatePDF() {
141
+ const element = document.getElementById('dissertation-content');
142
+
143
+ const options = {
144
+ margin: [0.5, 0.5, 0.5, 0.5],
145
+ filename: 'dissertation-philosophie.pdf',
146
+ image: { type: 'jpeg', quality: 0.98 },
147
+ // LA MÉTHODE FIABLE : On ignore l'élément qui contient le bouton
148
+ // On ajoute 'data-html2canvas-ignore="true"' sur le container du bouton
149
+ html2canvas: { scale: 2, useCORS: true },
150
+ jsPDF: { unit: 'in', format: 'a4', orientation: 'portrait' }
151
+ };
152
 
153
+ html2pdf().set(options).from(element).save();
 
 
 
 
 
 
 
 
 
 
 
154
  }
155
  }
156
+ }).mount('#app'); // On monte l'application Vue sur l'élément #app
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
157
  </script>
158
 
159
  </body>