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

Upload index.html

Browse files
Files changed (1) hide show
  1. templates/index.html +191 -48
templates/index.html CHANGED
@@ -3,60 +3,150 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Mariam AI</title>
7
- <link href="https://cdnjs.cloudflare.com/ajax/libs/tailwindcss/2.2.19/tailwind.min.css" rel="stylesheet">
 
 
8
  <script src="https://cdnjs.cloudflare.com/ajax/libs/marked/4.0.2/marked.min.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  </head>
10
- <body class="bg-gray-100 h-screen">
11
- <div class="container mx-auto p-4 h-full flex flex-col">
12
- <div class="bg-white rounded-lg shadow-lg p-6 h-full flex flex-col">
13
- <!-- Header -->
14
- <div class="flex justify-between items-center mb-6">
15
- <h1 class="text-2xl font-bold">Mariam AI</h1>
16
- <div class="flex space-x-4">
17
- <label class="flex items-center">
18
- <input type="checkbox" id="webSearchToggle" class="mr-2">
19
- Activer la recherche web
20
- </label>
21
- <button onclick="clearChat()" class="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600">
22
- Effacer le chat
23
- </button>
24
- </div>
25
- </div>
26
 
27
- <!-- File Upload -->
28
- <div class="mb-4">
29
- <input type="file" id="fileUpload" class="hidden" accept=".jpg,.jpeg,.png,.pdf,.txt,.mp3,.mp4">
30
- <label for="fileUpload" class="cursor-pointer bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">
31
- Télécharger un fichier
 
 
 
 
 
 
32
  </label>
33
- <span id="fileName" class="ml-2 text-gray-600"></span>
34
- </div>
35
 
36
- <!-- Chat Messages -->
37
- <div id="chatMessages" class="flex-1 overflow-y-auto mb-4 space-y-4">
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  {% for message in messages %}
39
  <div class="flex {% if message.role == 'user' %}justify-end{% endif %}">
40
- <div class="max-w-3/4 p-3 rounded-lg {% if message.role == 'user' %}bg-blue-500 text-white{% else %}bg-gray-200{% endif %}">
41
  {{ message.content }}
42
  </div>
43
  </div>
44
  {% endfor %}
45
  </div>
46
 
47
- <!-- Input Area -->
48
- <div class="border-t pt-4">
49
- <div class="flex space-x-4">
50
- <input type="text" id="messageInput"
51
- class="flex-1 border rounded-lg px-4 py-2 focus:outline-none focus:ring-2 focus:ring-blue-500"
52
- placeholder="Écrivez votre message...">
53
- <button onclick="sendMessage()"
54
- class="bg-blue-500 text-white px-6 py-2 rounded-lg hover:bg-blue-600 transition duration-200">
55
- Envoyer
 
 
 
 
 
 
 
 
56
  </button>
57
  </div>
 
 
 
 
58
  </div>
59
- </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  </div>
61
 
62
  <script>
@@ -65,15 +155,16 @@
65
  const webSearchToggle = document.getElementById('webSearchToggle');
66
  const fileUpload = document.getElementById('fileUpload');
67
  const fileName = document.getElementById('fileName');
 
68
 
69
- function addMessage(content, isUser = false) {
70
  const messageDiv = document.createElement('div');
71
  messageDiv.className = `flex ${isUser ? 'justify-end' : ''}`;
72
-
73
  const innerDiv = document.createElement('div');
74
- innerDiv.className = `max-w-3/4 p-3 rounded-lg ${isUser ? 'bg-blue-500 text-white' : 'bg-gray-200'}`;
75
  innerDiv.innerHTML = marked.parse(content);
76
-
77
  messageDiv.appendChild(innerDiv);
78
  chatMessages.appendChild(messageDiv);
79
  chatMessages.scrollTop = chatMessages.scrollHeight;
@@ -85,6 +176,7 @@
85
 
86
  addMessage(message, true);
87
  messageInput.value = '';
 
88
 
89
  try {
90
  const response = await fetch('/send_message', {
@@ -99,23 +191,26 @@
99
  });
100
 
101
  const data = await response.json();
 
102
  if (data.error) {
103
  addMessage(`Erreur: ${data.error}`);
104
  } else {
105
- addMessage(data.response);
106
  }
107
  } catch (error) {
 
108
  addMessage(`Erreur: ${error.message}`);
109
  }
110
  }
111
 
112
- messageInput.addEventListener('keypress', (e) => {
113
- if (e.key === 'Enter') {
 
114
  sendMessage();
115
  }
116
  });
117
 
118
- fileUpload.addEventListener('change', async (e) => {
119
  const file = e.target.files[0];
120
  if (!file) return;
121
 
@@ -123,6 +218,8 @@
123
  const formData = new FormData();
124
  formData.append('file', file);
125
 
 
 
126
  try {
127
  const response = await fetch('/upload', {
128
  method: 'POST',
@@ -130,25 +227,71 @@
130
  });
131
 
132
  const data = await response.json();
 
133
  if (data.error) {
134
  alert(`Erreur: ${data.error}`);
135
  } else {
136
- addMessage(`Fichier téléchargé: ${file.name}`);
137
  }
138
  } catch (error) {
 
139
  alert(`Erreur: ${error.message}`);
140
  }
141
  });
142
 
143
  async function clearChat() {
144
  try {
 
145
  await fetch('/clear_chat', { method: 'POST' });
146
  chatMessages.innerHTML = '';
147
- location.reload();
 
 
 
148
  } catch (error) {
 
149
  alert(`Erreur: ${error.message}`);
150
  }
151
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
152
  </script>
153
  </body>
154
  </html>
 
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>
 
155
  const webSearchToggle = document.getElementById('webSearchToggle');
156
  const fileUpload = document.getElementById('fileUpload');
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);
169
  chatMessages.appendChild(messageDiv);
170
  chatMessages.scrollTop = chatMessages.scrollHeight;
 
176
 
177
  addMessage(message, true);
178
  messageInput.value = '';
179
+ showLoading();
180
 
181
  try {
182
  const response = await fetch('/send_message', {
 
191
  });
192
 
193
  const data = await response.json();
194
+ hideLoading();
195
  if (data.error) {
196
  addMessage(`Erreur: ${data.error}`);
197
  } else {
198
+ addMessage(data.response);
199
  }
200
  } catch (error) {
201
+ hideLoading();
202
  addMessage(`Erreur: ${error.message}`);
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
 
 
218
  const formData = new FormData();
219
  formData.append('file', file);
220
 
221
+ showLoading();
222
+
223
  try {
224
  const response = await fetch('/upload', {
225
  method: 'POST',
 
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
+
257
+ function showLoading() {
258
+ loadingOverlay.classList.remove('hidden');
259
+ }
260
+
261
+ function hideLoading() {
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>