Docfile commited on
Commit
edad585
·
verified ·
1 Parent(s): fe49da4

Upload index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +208 -143
templates/index.html CHANGED
@@ -3,150 +3,172 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Mariam AI (Grok Style)</title>
7
- <!-- Tailwind CSS (CDN - pour la simplicité dans un seul fichier) -->
8
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
9
- <!-- Intégration de Marked.js -->
10
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
11
-
12
  <style>
13
- /* Animations */
14
- @keyframes spin {
15
- 0% { transform: rotate(0deg); }
16
- 100% { transform: rotate(360deg); }
17
  }
18
 
19
- .loader {
20
- animation: spin 2s linear infinite;
 
21
  }
22
 
23
- /* Styles pour les boutons d'action rapide */
24
- .quick-action-btn {
25
- @apply bg-gray-800 hover:bg-gray-700 text-white font-semibold py-3 px-6 rounded-full w-full max-w-xs flex items-center justify-center transition duration-200 ease-in-out;
26
- /* Ajoutez d'autres styles si nécessaire */
27
  }
28
 
29
  .message {
30
- transition: transform 0.2s ease-out;
31
  }
32
 
33
  .message:hover {
34
- transform: translateX(5px);
35
  }
36
 
37
- /* Styles spécifiques pour la version mobile (si nécessaire) */
38
- @media (max-width: 767px) {
39
- .quick-action-btn {
40
- @apply text-sm;
41
- }
42
 
43
- .quick-actions {
44
- display: none;
45
- }
46
- .bottom-bar {
47
- display: flex;
48
- }
49
  }
50
- </style>
51
- </head>
52
- <body class="bg-gray-900 text-white font-sans h-screen flex flex-col">
53
 
54
- <div class="container mx-auto px-4 py-6 flex-grow flex flex-col">
 
 
 
55
 
56
- <header class="flex justify-between items-center mb-8">
57
- <div class="flex items-center">
58
- <span class="text-2xl font-bold">Bonsoir, GCP ✨</span>
59
- </div>
 
60
 
61
- <div class="flex items-center">
62
- <label class="flex items-center cursor-pointer mr-4">
63
- <input type="checkbox" id="webSearchToggle" class="mr-2 h-5 w-5 text-blue-500 focus:ring-blue-500 border-gray-300 rounded">
64
- <span class="text-sm">Activer la recherche web</span>
65
- </label>
66
 
67
- <button onclick="clearChat()" class="bg-red-600 hover:bg-red-700 text-white font-semibold py-2 px-4 rounded-full transition duration-200 ease-in-out">
68
- Effacer
69
- </button>
70
- </div>
71
- </header>
72
 
73
- <div class="flex flex-col items-center justify-center flex-grow space-y-4 mb-8">
74
- <button class="quick-action-btn">
75
- <svg class="w-6 h-6 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 12a9 9 0 01-9 9m9-9a9 9 0 00-9-9m9 9H3m9 9a9 9 0 01-9-9m9 9c1.657 0 3-4.03 3-9s-1.343-9-3-9m0 18c-1.657 0-3-4.03-3-9s1.343-9 3-9m-9 9a9 9 0 019-9"></path></svg>
76
- Recherche
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  </button>
78
- <button class="quick-action-btn">
79
- <svg class="w-6 h-6 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path></svg>
80
- Tempête de cerveau
 
 
81
  </button>
82
- <button class="quick-action-btn">
83
- <svg class="w-6 h-6 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"></path></svg>
84
- Analyser les données
 
 
85
  </button>
86
- <button class="quick-action-btn">
87
- <svg class="w-6 h-6 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path></svg>
88
- Créer des images
 
 
89
  </button>
90
- <button class="quick-action-btn">
91
- <svg class="w-6 h-6 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"></path></svg>
92
- Code
 
 
93
  </button>
94
  </div>
95
 
96
- <div id="chatMessages" class="flex-1 overflow-y-auto mb-4 space-y-4">
97
- {% for message in messages %}
98
- <div class="flex {% if message.role == 'user' %}justify-end{% endif %}">
99
- <div class="message max-w-3/4 p-3 rounded-lg {% if message.role == 'user' %}bg-blue-500 text-white{% else %}bg-gray-700{% endif %}">
100
- {{ message.content }}
101
- </div>
102
- </div>
103
- {% endfor %}
104
- </div>
105
 
106
- <div class="border-t border-gray-700 pt-4">
107
- <div class="mb-4 flex items-center">
 
108
  <input type="file" id="fileUpload" class="hidden" accept=".jpg,.jpeg,.png,.pdf,.txt,.mp3,.mp4">
109
- <label for="fileUpload" class="cursor-pointer bg-gray-700 hover:bg-gray-600 text-white py-2 px-4 rounded-full transition duration-200 ease-in-out mr-2">
110
- <svg class="w-5 h-5 inline-block" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"></path></svg>
 
 
 
111
  </label>
112
- <span id="fileName" class="text-sm text-gray-400"></span>
113
  </div>
114
-
115
  <div class="flex space-x-4">
116
-
117
- <div class="relative flex-grow">
118
  <input type="text" id="messageInput"
119
- class="w-full bg-gray-800 text-white rounded-full px-12 py-3 pl-4 focus:outline-none focus:ring-2 focus:ring-blue-500 transition duration-200"
120
- placeholder="Montrez-">
121
- <button class="absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500 hover:text-gray-300">
122
- <svg class="h-6 w-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 11a7 7 0 01-7 7m0 0a7 7 0 01-7-7m7 7v4m0 0H8m4 0h4m-4-8a3 3 0 01-3-3V5a3 3 0 116 0v6a3 3 0 01-3 3z"></path></svg>
123
- </button>
124
  </div>
125
-
126
- <button onclick="sendMessage()" class="bg-blue-600 hover:bg-blue-700 text-white font-semibold py-2 px-6 rounded-full transition duration-200 ease-in-out">
127
- <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7"></path></svg>
128
- </button>
 
129
  </div>
130
- </div>
131
- </div>
132
-
133
- <div class="md:hidden fixed bottom-0 left-0 right-0 bg-gray-800 p-2 flex justify-around">
134
- <button class="text-gray-400 hover:text-white">
135
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6"></path></svg>
136
- </button>
137
- <button class="text-gray-400 hover:text-white">
138
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"></path></svg>
139
- </button>
140
- <button class="text-gray-400 hover:text-white">
141
- <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 6v6m0 0v6m0-6h6m-6 0H6"></path></svg>
142
- </button>
143
- <button class="text-gray-400 hover:text-white">
144
- <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-6-3a2 2 0 11-4 0 2 2 0 014 0zm-2 4a5 5 0 00-4.546 2.916A5.986 5.986 0 0010 16a5.986 5.986 0 004.546-2.084A5 5 0 0010 11z" clip-rule="evenodd"></path></svg>
145
- </button>
146
  </div>
147
 
148
- <div id="loadingOverlay" class="fixed inset-0 bg-gray-900 bg-opacity-50 z-50 hidden flex items-center justify-center">
149
- <div class="loader ease-linear rounded-full border-8 border-t-8 border-gray-200 h-32 w-32"></div>
 
150
  </div>
151
 
152
  <script>
@@ -157,12 +179,12 @@
157
  const fileName = document.getElementById('fileName');
158
  const loadingOverlay = document.getElementById('loadingOverlay');
159
 
160
- function addMessage(content, isUser = false) {
161
  const messageDiv = document.createElement('div');
162
- messageDiv.className = `flex ${isUser ? 'justify-end' : ''}`;
163
 
164
  const innerDiv = document.createElement('div');
165
- innerDiv.className = `message max-w-3/4 p-3 rounded-lg ${isUser ? 'bg-blue-500 text-white' : 'bg-gray-700'}`;
166
  innerDiv.innerHTML = marked.parse(content);
167
 
168
  messageDiv.appendChild(innerDiv);
@@ -195,7 +217,7 @@
195
  if (data.error) {
196
  addMessage(`Erreur: ${data.error}`);
197
  } else {
198
- addMessage(data.response);
199
  }
200
  } catch (error) {
201
  hideLoading();
@@ -203,14 +225,14 @@
203
  }
204
  }
205
 
206
- messageInput.addEventListener('keypress', (e) => {
207
  if (e.key === 'Enter' && !e.shiftKey) {
208
  e.preventDefault();
209
  sendMessage();
210
  }
211
  });
212
 
213
- fileUpload.addEventListener('change', async (e) => {
214
  const file = e.target.files[0];
215
  if (!file) return;
216
 
@@ -227,30 +249,29 @@
227
  });
228
 
229
  const data = await response.json();
230
- hideLoading();
231
  if (data.error) {
232
- alert(`Erreur: ${data.error}`);
233
  } else {
234
- addMessage(`Fichier téléchargé: ${file.name}`);
235
  }
236
  } catch (error) {
237
- hideLoading();
238
- alert(`Erreur: ${error.message}`);
239
  }
240
  });
241
 
242
  async function clearChat() {
243
  try {
244
- showLoading();
245
  await fetch('/clear_chat', { method: 'POST' });
246
  chatMessages.innerHTML = '';
247
- hideLoading();
248
- fileName.textContent = '';
249
  fileUpload.value = '';
250
-
251
  } catch (error) {
252
  hideLoading();
253
- alert(`Erreur: ${error.message}`);
254
  }
255
  }
256
 
@@ -262,36 +283,80 @@
262
  loadingOverlay.classList.add('hidden');
263
  }
264
 
265
- document.querySelectorAll('.quick-action-btn').forEach(button => {
266
  button.addEventListener('click', () => {
267
- const actionText = button.textContent.trim();
268
- switch (actionText) {
 
 
269
  case 'Recherche':
270
- messageInput.value = "Effectue une recherche sur ";
271
- break;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
272
 
273
- case 'Tempête de cerveau':
274
- messageInput.value = "Donne moi des idées sur ";
275
- break;
 
 
 
 
 
 
 
276
 
277
- case 'Analyser les données':
278
- messageInput.value = "Analyse les données suivantes: ";
279
- break;
280
 
281
- case 'Créer des images':
282
- messageInput.value = "Crée une image de ";
283
- break;
 
 
 
 
284
 
285
- case 'Code':
286
- messageInput.value = "Écris du code pour ";
287
- break;
288
- default:
289
- console.log('Action non reconnue:', actionText);
290
- }
291
- messageInput.focus();
292
 
293
- });
 
 
 
 
294
  });
 
 
 
 
 
 
 
 
295
  </script>
296
  </body>
297
  </html>
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Assistant IA</title>
 
7
  <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/tailwind.min.css" rel="stylesheet">
 
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
 
9
  <style>
10
+ :root {
11
+ --primary-blue: #1E40AF;
12
+ --light-blue: #EFF6FF;
13
+ --accent-blue: #3B82F6;
14
  }
15
 
16
+ body {
17
+ background: linear-gradient(135deg, var(--light-blue) 0%, #ffffff 100%);
18
+ min-height: 100vh;
19
  }
20
 
21
+ .glass-effect {
22
+ background: rgba(255, 255, 255, 0.9);
23
+ backdrop-filter: blur(10px);
24
+ border: 1px solid rgba(255, 255, 255, 0.2);
25
  }
26
 
27
  .message {
28
+ transition: transform 0.3s ease;
29
  }
30
 
31
  .message:hover {
32
+ transform: translateY(-2px);
33
  }
34
 
35
+ .quick-action {
36
+ background: linear-gradient(135deg, var(--primary-blue) 0%, var(--accent-blue) 100%);
37
+ transition: all 0.3s ease;
38
+ }
 
39
 
40
+ .quick-action:hover {
41
+ transform: translateY(-2px);
42
+ box-shadow: 0 4px 12px rgba(59, 130, 246, 0.3);
 
 
 
43
  }
 
 
 
44
 
45
+ .custom-input {
46
+ border: 2px solid #E5E7EB;
47
+ transition: all 0.3s ease;
48
+ }
49
 
50
+ .custom-input:focus {
51
+ border-color: var(--accent-blue);
52
+ box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1);
53
+ outline: none;
54
+ }
55
 
56
+ @keyframes spin {
57
+ 0% { transform: rotate(0deg); }
58
+ 100% { transform: rotate(360deg); }
59
+ }
 
60
 
61
+ .loading-spinner {
62
+ border-top-color: var(--accent-blue);
63
+ animation: spin 1s linear infinite;
64
+ }
 
65
 
66
+ .file-upload-preview {
67
+ background: rgba(59, 130, 246, 0.1);
68
+ border: 2px dashed var(--accent-blue);
69
+ transition: all 0.3s ease;
70
+ }
71
+
72
+ .file-upload-preview:hover {
73
+ background: rgba(59, 130, 246, 0.2);
74
+ }
75
+ </style>
76
+ </head>
77
+ <body class="font-sans">
78
+ <div class="container mx-auto px-4 py-8 max-w-6xl">
79
+ <!-- Header -->
80
+ <header class="glass-effect rounded-2xl p-6 mb-8 flex justify-between items-center">
81
+ <div class="flex items-center space-x-4">
82
+ <div class="w-12 h-12 rounded-full bg-blue-600 flex items-center justify-center">
83
+ <svg class="w-8 h-8 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
84
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 10h.01M12 10h.01M16 10h.01M9 16H5a2 2 0 01-2-2V6a2 2 0 012-2h14a2 2 0 012 2v8a2 2 0 01-2 2h-5l-5 5v-5z"/>
85
+ </svg>
86
+ </div>
87
+ <div>
88
+ <h1 class="text-2xl font-bold text-blue-900">Assistant IA</h1>
89
+ <p class="text-blue-600">En ligne</p>
90
+ </div>
91
+ </div>
92
+ <div class="flex items-center space-x-4">
93
+ <label class="flex items-center space-x-2 text-blue-900">
94
+ <input type="checkbox" id="webSearchToggle" class="w-4 h-4 text-blue-600 focus:ring-blue-500">
95
+ <span>Recherche web</span>
96
+ </label>
97
+ <button onclick="clearChat()" class="bg-red-500 hover:bg-red-600 text-white px-4 py-2 rounded-lg transition-all duration-300">
98
+ Effacer
99
+ </button>
100
+ </div>
101
+ </header>
102
+
103
+ <!-- Quick Actions -->
104
+ <div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-5 gap-4 mb-8">
105
+ <button class="quick-action text-white p-4 rounded-xl flex items-center justify-center space-x-2">
106
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
107
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"/>
108
+ </svg>
109
+ <span>Recherche</span>
110
  </button>
111
+ <button class="quick-action text-white p-4 rounded-xl flex items-center justify-center space-x-2">
112
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
113
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M13 10V3L4 14h7v7l9-11h-7z"/>
114
+ </svg>
115
+ <span>Brainstorm</span>
116
  </button>
117
+ <button class="quick-action text-white p-4 rounded-xl flex items-center justify-center space-x-2">
118
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
119
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
120
+ </svg>
121
+ <span>Analyse</span>
122
  </button>
123
+ <button class="quick-action text-white p-4 rounded-xl flex items-center justify-center space-x-2">
124
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
125
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
126
+ </svg>
127
+ <span>Images</span>
128
  </button>
129
+ <button class="quick-action text-white p-4 rounded-xl flex items-center justify-center space-x-2">
130
+ <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24">
131
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 20l4-16m4 4l4 4-4 4M6 16l-4-4 4-4"/>
132
+ </svg>
133
+ <span>Code</span>
134
  </button>
135
  </div>
136
 
137
+ <!-- Chat Messages -->
138
+ <div id="chatMessages" class="glass-effect rounded-2xl p-6 mb-8 h-[500px] overflow-y-auto space-y-4">
139
+ <!-- Messages will be inserted here dynamically -->
140
+ </div>
 
 
 
 
 
141
 
142
+ <!-- Input Area -->
143
+ <div class="glass-effect rounded-2xl p-6">
144
+ <div class="mb-4">
145
  <input type="file" id="fileUpload" class="hidden" accept=".jpg,.jpeg,.png,.pdf,.txt,.mp3,.mp4">
146
+ <label for="fileUpload" class="file-upload-preview p-4 rounded-xl flex items-center justify-center cursor-pointer hover:bg-blue-50">
147
+ <svg class="w-6 h-6 text-blue-600 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
148
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 4v16m8-8H4"/>
149
+ </svg>
150
+ <span id="fileName" class="text-blue-600">Déposer un fichier</span>
151
  </label>
 
152
  </div>
153
+
154
  <div class="flex space-x-4">
155
+ <div class="relative flex-grow">
 
156
  <input type="text" id="messageInput"
157
+ class="custom-input w-full rounded-xl px-6 py-4 text-blue-900 placeholder-blue-400"
158
+ placeholder="Écrivez votre message...">
 
 
 
159
  </div>
160
+ <button onclick="sendMessage()" class="quick-action px-8 py-4 rounded-xl flex items-center justify-center">
161
+ <svg class="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
162
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"/>
163
+ </svg>
164
+ </button>
165
  </div>
166
+ </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
167
  </div>
168
 
169
+ <!-- Loading Overlay -->
170
+ <div id="loadingOverlay" class="fixed inset-0 bg-white bg-opacity-75 backdrop-filter backdrop-blur-sm hidden flex items-center justify-center z-50">
171
+ <div class="loading-spinner w-16 h-16 border-4 border-blue-200 border-t-blue-600 rounded-full"></div>
172
  </div>
173
 
174
  <script>
 
179
  const fileName = document.getElementById('fileName');
180
  const loadingOverlay = document.getElementById('loadingOverlay');
181
 
182
+ function addMessage(content, isUser = false) {
183
  const messageDiv = document.createElement('div');
184
+ messageDiv.className = `message flex ${isUser ? 'justify-end' : 'justify-start'}`;
185
 
186
  const innerDiv = document.createElement('div');
187
+ innerDiv.className = `max-w-[75%] p-4 rounded-xl ${isUser ? 'bg-blue-600 text-white' : 'bg-white text-blue-900'} shadow-lg`;
188
  innerDiv.innerHTML = marked.parse(content);
189
 
190
  messageDiv.appendChild(innerDiv);
 
217
  if (data.error) {
218
  addMessage(`Erreur: ${data.error}`);
219
  } else {
220
+ addMessage(data.response);
221
  }
222
  } catch (error) {
223
  hideLoading();
 
225
  }
226
  }
227
 
228
+ messageInput.addEventListener('keypress', (e) => {
229
  if (e.key === 'Enter' && !e.shiftKey) {
230
  e.preventDefault();
231
  sendMessage();
232
  }
233
  });
234
 
235
+ fileUpload.addEventListener('change', async (e) => {
236
  const file = e.target.files[0];
237
  if (!file) return;
238
 
 
249
  });
250
 
251
  const data = await response.json();
252
+ hideLoading();
253
  if (data.error) {
254
+ addMessage(`Erreur: ${data.error}`);
255
  } else {
256
+ addMessage(`Fichier téléchargé: ${file.name}`);
257
  }
258
  } catch (error) {
259
+ hideLoading();
260
+ addMessage(`Erreur: ${error.message}`);
261
  }
262
  });
263
 
264
  async function clearChat() {
265
  try {
266
+ showLoading();
267
  await fetch('/clear_chat', { method: 'POST' });
268
  chatMessages.innerHTML = '';
269
+ hideLoading();
270
+ fileName.textContent = 'Déposer un fichier';
271
  fileUpload.value = '';
 
272
  } catch (error) {
273
  hideLoading();
274
+ addMessage(`Erreur: ${error.message}`);
275
  }
276
  }
277
 
 
283
  loadingOverlay.classList.add('hidden');
284
  }
285
 
286
+ document.querySelectorAll('.quick-action').forEach(button => {
287
  button.addEventListener('click', () => {
288
+ const text = button.querySelector('span').textContent.trim();
289
+ let prompt = '';
290
+
291
+ switch (text) {
292
  case 'Recherche':
293
+ prompt = "Effectuez une recherche sur ";
294
+ break;
295
+ case 'Brainstorm':
296
+ prompt = "Donnez-moi des idées sur ";
297
+ break;
298
+ case 'Analyse':
299
+ prompt = "Analysez les données suivantes : ";
300
+ break;
301
+ case 'Images':
302
+ prompt = "Créez une image de ";
303
+ break;
304
+ case 'Code':
305
+ prompt = "Écrivez du code pour ";
306
+ break;
307
+ default:
308
+ prompt = "";
309
+ }
310
+
311
+ messageInput.value = prompt;
312
+ messageInput.focus();
313
+ // Place le curseur à la fin du texte
314
+ messageInput.setSelectionRange(prompt.length, prompt.length);
315
+ });
316
+ });
317
 
318
+ // Fonction pour initialiser l'interface
319
+ function initializeChat() {
320
+ // Vérifier si des messages existent dans le localStorage
321
+ const savedMessages = localStorage.getItem('chatMessages');
322
+ if (savedMessages) {
323
+ const messages = JSON.parse(savedMessages);
324
+ messages.forEach(msg => {
325
+ addMessage(msg.content, msg.isUser);
326
+ });
327
+ }
328
 
329
+ // Focus sur l'input au chargement
330
+ messageInput.focus();
331
+ }
332
 
333
+ // Fonction pour sauvegarder les messages
334
+ function saveMessage(content, isUser) {
335
+ const savedMessages = localStorage.getItem('chatMessages') || '[]';
336
+ const messages = JSON.parse(savedMessages);
337
+ messages.push({ content, isUser });
338
+ localStorage.setItem('chatMessages', JSON.stringify(messages));
339
+ }
340
 
341
+ // Fonction pour formater les messages avec Markdown
342
+ function formatMessage(content) {
343
+ return marked.parse(content);
344
+ }
 
 
 
345
 
346
+ // Gestion des erreurs globale
347
+ window.addEventListener('error', function(e) {
348
+ console.error('Erreur globale:', e.error);
349
+ hideLoading();
350
+ addMessage('Une erreur est survenue. Veuillez réessayer.', false);
351
  });
352
+
353
+ // Gestion de la déconnexion
354
+ window.addEventListener('offline', function() {
355
+ addMessage('La connexion internet a été perdue. Vérifiez votre connexion.', false);
356
+ });
357
+
358
+ // Initialisation de l'interface au chargement
359
+ document.addEventListener('DOMContentLoaded', initializeChat);
360
  </script>
361
  </body>
362
  </html>