Docfile commited on
Commit
73808fe
·
verified ·
1 Parent(s): db67e3f

Delete templates/index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +0 -302
templates/index.html DELETED
@@ -1,302 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="fr">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Mariam M-0</title>
7
-
8
- <!-- Intégration de Tailwind CSS -->
9
- <script defer src="https://cdn.tailwindcss.com"></script>
10
-
11
- <!-- Marked pour le rendu Markdown -->
12
- <script defer src="https://cdn.jsdelivr.net/npm/marked/marked.min.js"></script>
13
-
14
- <!-- DOMPurify pour sécuriser le rendu HTML -->
15
- <script defer src="https://cdn.jsdelivr.net/npm/[email protected]/dist/purify.min.js"></script>
16
-
17
- <!-- Highlight.js pour la coloration syntaxique -->
18
- <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/styles/github.min.css">
19
- <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"></script>
20
-
21
- <style>
22
- @keyframes gradient {
23
- 0% { background-position: 0% 50%; }
24
- 50% { background-position: 100% 50%; }
25
- 100% { background-position: 0% 50%; }
26
- }
27
- .gradient-bg {
28
- background: linear-gradient(-45deg, #ee7752, #e73c7e, #23a6d5, #23d5ab);
29
- background-size: 400% 400%;
30
- animation: gradient 15s ease infinite;
31
- }
32
-
33
- /* Assurer la bonne gestion des espaces et retours à la ligne sur mobile */
34
- .markdown-content {
35
- white-space: pre-wrap;
36
- word-break: break-word;
37
- }
38
-
39
- /* Styles pour le rendu Markdown en CSS natif */
40
- .markdown-content h1 {
41
- font-size: 1.5rem; /* text-2xl */
42
- font-weight: 700; /* font-bold */
43
- margin-top: 1.5rem; /* mt-6 */
44
- margin-bottom: 1rem; /* mb-4 */
45
- }
46
- .markdown-content h2 {
47
- font-size: 1.25rem; /* text-xl */
48
- font-weight: 700;
49
- margin-top: 1.25rem; /* mt-5 */
50
- margin-bottom: 0.75rem; /* mb-3 */
51
- }
52
- .markdown-content h3 {
53
- font-size: 1.125rem; /* text-lg */
54
- font-weight: 700;
55
- margin-top: 1rem; /* mt-4 */
56
- margin-bottom: 0.5rem; /* mb-2 */
57
- }
58
- .markdown-content p {
59
- margin-bottom: 1rem; /* mb-4 */
60
- line-height: 1.625; /* leading-relaxed */
61
- }
62
- .markdown-content ul {
63
- list-style-type: disc;
64
- margin-left: 1.5rem; /* ml-6 */
65
- margin-bottom: 1rem; /* mb-4 */
66
- }
67
- .markdown-content ol {
68
- list-style-type: decimal;
69
- margin-left: 1.5rem;
70
- margin-bottom: 1rem;
71
- }
72
- .markdown-content li {
73
- margin-bottom: 0.25rem; /* mb-1 */
74
- }
75
- .markdown-content a {
76
- color: #2563eb; /* text-blue-600 */
77
- text-decoration: underline;
78
- }
79
- .markdown-content a:hover {
80
- color: #1d4ed8; /* text-blue-800 */
81
- }
82
- .markdown-content blockquote {
83
- padding-left: 1rem; /* pl-4 */
84
- border-left: 4px solid #D1D5DB; /* border-gray-300 */
85
- font-style: italic;
86
- margin: 1rem 0; /* my-4 */
87
- }
88
- .markdown-content code:not(pre code) {
89
- background-color: #F3F4F6; /* bg-gray-100 */
90
- padding: 0 0.25rem; /* px-1 */
91
- border-radius: 0.25rem; /* rounded */
92
- font-size: 0.875rem; /* text-sm */
93
- font-family: monospace;
94
- }
95
- .markdown-content pre {
96
- background-color: #F3F4F6;
97
- padding: 1rem; /* p-4 */
98
- border-radius: 0.5rem; /* rounded-lg */
99
- margin-bottom: 1rem; /* mb-4 */
100
- overflow-x: auto;
101
- }
102
- .markdown-content table {
103
- width: 100%;
104
- border: 1px solid #D1D5DB; /* border-gray-300 */
105
- margin-bottom: 1rem;
106
- border-collapse: collapse;
107
- }
108
- .markdown-content th,
109
- .markdown-content td {
110
- border-bottom: 1px solid #D1D5DB;
111
- padding: 0.5rem 1rem; /* px-4 py-2 */
112
- text-align: left;
113
- }
114
- .markdown-content th {
115
- background-color: #F3F4F6;
116
- }
117
- .markdown-content img {
118
- max-width: 100%;
119
- height: auto;
120
- margin: 1rem 0;
121
- border-radius: 0.5rem;
122
- }
123
- </style>
124
- </head>
125
- <body class="min-h-screen bg-gray-50">
126
- <!-- Barre de gradient fixe en haut de page -->
127
- <div class="gradient-bg h-2 w-full fixed top-0"></div>
128
-
129
- <div class="max-w-4xl mx-auto px-4 py-8">
130
- <header class="text-center mb-12">
131
- <h1 class="text-4xl font-bold text-gray-800 mb-2">Mariam M-0</h1>
132
- <p class="text-gray-600">Votre assistant IA personnel</p>
133
- </header>
134
-
135
- <main>
136
- <section class="bg-white rounded-xl shadow-lg p-6 mb-8">
137
- <textarea
138
- id="question"
139
- class="w-full h-32 p-4 border border-gray-200 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent resize-none"
140
- placeholder="Posez votre question ici..."
141
- aria-label="Zone de saisie de la question"
142
- ></textarea>
143
- <button
144
- id="submitBtn"
145
- class="mt-4 px-6 py-3 bg-gradient-to-r from-blue-500 to-blue-600 text-white rounded-lg hover:from-blue-600 hover:to-blue-700 transition-all duration-200 flex items-center justify-center w-full sm:w-auto"
146
- aria-label="Obtenir une réponse"
147
- >
148
- <span>Obtenir une réponse</span>
149
- <div id="spinner" class="hidden ml-3 animate-spin rounded-full h-5 w-5 border-b-2 border-white" aria-hidden="true"></div>
150
- </button>
151
- </section>
152
-
153
- <section id="responseContainer" class="space-y-6">
154
- <article id="answerBox" class="hidden bg-white rounded-xl shadow-lg p-6 relative">
155
- <div class="flex items-center justify-between mb-4">
156
- <h2 class="text-xl font-semibold text-gray-800">Réponse</h2>
157
- <!-- Bouton Copier -->
158
- <button
159
- id="copyBtn"
160
- class="px-3 py-1 bg-blue-500 text-white text-sm rounded hover:bg-blue-600 transition-colors"
161
- title="Copier la réponse"
162
- aria-label="Copier la réponse"
163
- >
164
- Copier
165
- </button>
166
- </div>
167
- <div id="answer" class="markdown-content text-gray-700"></div>
168
- </article>
169
-
170
- <article id="thinkingBox" class="hidden bg-white rounded-xl shadow-lg p-6">
171
- <div class="flex items-center justify-between mb-4">
172
- <h2 class="text-xl font-semibold text-gray-800">Raisonnement</h2>
173
- <button
174
- id="toggleThinking"
175
- class="text-blue-500 hover:text-blue-600 focus:outline-none"
176
- aria-expanded="false"
177
- aria-controls="thinking"
178
- >
179
- Afficher
180
- </button>
181
- </div>
182
- <div id="thinking" class="hidden markdown-content text-gray-600"></div>
183
- </article>
184
- </section>
185
- </main>
186
- </div>
187
-
188
- <script defer>
189
- // Configuration de marked pour le rendu Markdown
190
- marked.setOptions({
191
- highlight: function(code, lang) {
192
- if (lang && hljs.getLanguage(lang)) {
193
- return hljs.highlight(code, { language: lang }).value;
194
- }
195
- return hljs.highlightAuto(code).value;
196
- },
197
- breaks: true,
198
- gfm: true
199
- });
200
-
201
- /**
202
- * Fonction pour rendre le Markdown de manière sécurisée.
203
- * @param {string} content - Le contenu en Markdown.
204
- * @returns {string} Le HTML rendu et sécurisé.
205
- */
206
- function renderMarkdown(content) {
207
- const rawHtml = marked.parse(content);
208
- return DOMPurify.sanitize(rawHtml);
209
- }
210
-
211
- const submitBtn = document.getElementById('submitBtn');
212
- const spinner = document.getElementById('spinner');
213
- const answerBox = document.getElementById('answerBox');
214
- const thinkingBox = document.getElementById('thinkingBox');
215
- const answer = document.getElementById('answer');
216
- const thinking = document.getElementById('thinking');
217
- const toggleThinking = document.getElementById('toggleThinking');
218
- const copyBtn = document.getElementById('copyBtn');
219
-
220
- // Bouton pour basculer l'affichage du raisonnement
221
- toggleThinking.addEventListener('click', () => {
222
- const isHidden = thinking.classList.contains('hidden');
223
- thinking.classList.toggle('hidden');
224
- toggleThinking.textContent = isHidden ? 'Masquer' : 'Afficher';
225
- toggleThinking.setAttribute('aria-expanded', isHidden);
226
- });
227
-
228
- // Bouton Copier
229
- copyBtn.addEventListener('click', () => {
230
- // Crée un élément temporaire pour copier le texte brut (sans HTML)
231
- const tempElement = document.createElement('textarea');
232
- tempElement.value = answer.innerText;
233
- document.body.appendChild(tempElement);
234
- tempElement.select();
235
- try {
236
- document.execCommand('copy');
237
- copyBtn.textContent = 'Copié';
238
- setTimeout(() => {
239
- copyBtn.textContent = 'Copier';
240
- }, 1500);
241
- } catch (err) {
242
- console.error('Erreur lors de la copie :', err);
243
- }
244
- document.body.removeChild(tempElement);
245
- });
246
-
247
- // Gestion de la soumission de la question
248
- submitBtn.addEventListener('click', async () => {
249
- const question = document.getElementById('question').value;
250
- if (!question.trim()) return;
251
-
252
- // Réinitialisation de l'interface utilisateur
253
- answer.innerHTML = '';
254
- thinking.innerHTML = '';
255
- submitBtn.disabled = true;
256
- spinner.classList.remove('hidden');
257
- answerBox.classList.add('hidden');
258
- thinkingBox.classList.add('hidden');
259
-
260
- try {
261
- const response = await fetch('/ask', {
262
- method: 'POST',
263
- headers: { 'Content-Type': 'application/json' },
264
- body: JSON.stringify({ question })
265
- });
266
-
267
- // Lecture du flux de réponse en continu
268
- const reader = response.body.getReader();
269
- const decoder = new TextDecoder();
270
-
271
- while (true) {
272
- const { done, value } = await reader.read();
273
- if (done) break;
274
- const chunks = decoder.decode(value).split('\n');
275
- chunks.forEach(chunk => {
276
- if (!chunk) return;
277
- const data = JSON.parse(chunk);
278
- if (data.type === 'thinking') {
279
- thinkingBox.classList.remove('hidden');
280
- thinking.innerHTML = renderMarkdown(data.content);
281
- } else if (data.type === 'answer') {
282
- answerBox.classList.remove('hidden');
283
- answer.innerHTML = renderMarkdown(data.content);
284
- // Rafraîchissement de la coloration syntaxique pour les blocs de code
285
- answer.querySelectorAll('pre code').forEach(block => {
286
- hljs.highlightElement(block);
287
- });
288
- }
289
- });
290
- }
291
- } catch (error) {
292
- console.error('Error:', error);
293
- answer.innerHTML = renderMarkdown("❌ Une erreur est survenue. Veuillez réessayer.");
294
- answerBox.classList.remove('hidden');
295
- } finally {
296
- submitBtn.disabled = false;
297
- spinner.classList.add('hidden');
298
- }
299
- });
300
- </script>
301
- </body>
302
- </html>