Mousco commited on
Commit
44fd0c6
·
verified ·
1 Parent(s): 5ccb418

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +858 -19
index.html CHANGED
@@ -1,19 +1,858 @@
1
- <!doctype html>
2
- <html>
3
- <head>
4
- <meta charset="utf-8" />
5
- <meta name="viewport" content="width=device-width" />
6
- <title>My static Space</title>
7
- <link rel="stylesheet" href="style.css" />
8
- </head>
9
- <body>
10
- <div class="card">
11
- <h1>Welcome to your static Space!</h1>
12
- <p>You can modify this app directly by editing <i>index.html</i> in the Files and versions tab.</p>
13
- <p>
14
- Also don't forget to check the
15
- <a href="https://huggingface.co/docs/hub/spaces" target="_blank">Spaces documentation</a>.
16
- </p>
17
- </div>
18
- </body>
19
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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, maximum-scale=1.0, user-scalable=no">
6
+ <title>Telegram Web (Simulation)</title>
7
+
8
+ <!-- Importation de la police Roboto (Police standard de Telegram) -->
9
+ <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&display=swap" rel="stylesheet">
10
+
11
+ <!-- Importation des icônes FontAwesome -->
12
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
13
+
14
+ <style>
15
+ /* =========================================
16
+ VARIABLES CSS & RESET
17
+ ========================================= */
18
+ :root {
19
+ --tg-blue: #3390ec;
20
+ --tg-bg: #1d242d; /* Fond sombre style "Dark Mode" ou classique */
21
+ --tg-sidebar-bg: #17212b;
22
+ --tg-chat-bg: #0e1621;
23
+ --tg-item-hover: #202b36;
24
+ --tg-text-primary: #ffffff;
25
+ --tg-text-secondary: #7f91a4;
26
+ --tg-green-msg: #2b5278;
27
+ --tg-white-msg: #182533;
28
+ --tg-input-bg: #242f3d;
29
+ --tg-border: #0e1621;
30
+ --scrollbar-thumb: #2f3844;
31
+ --header-height: 60px;
32
+ }
33
+
34
+ /* Mode Clair par défaut si préféré, mais je vais faire un thème sombre
35
+ car c'est très populaire pour les "fake" modernes */
36
+
37
+ * {
38
+ box-sizing: border-box;
39
+ margin: 0;
40
+ padding: 0;
41
+ outline: none;
42
+ -webkit-tap-highlight-color: transparent;
43
+ }
44
+
45
+ body {
46
+ font-family: 'Roboto', sans-serif;
47
+ background-color: var(--tg-bg);
48
+ color: var(--tg-text-primary);
49
+ height: 100vh;
50
+ overflow: hidden;
51
+ display: flex;
52
+ justify-content: center;
53
+ align-items: center;
54
+ }
55
+
56
+ /* Lien obligatoire "Built with anycoder" */
57
+ .anycoder-credit {
58
+ position: absolute;
59
+ top: 5px;
60
+ left: 10px;
61
+ font-size: 0.75rem;
62
+ color: var(--tg-text-secondary);
63
+ z-index: 1000;
64
+ text-decoration: none;
65
+ opacity: 0.7;
66
+ transition: opacity 0.3s;
67
+ }
68
+ .anycoder-credit:hover {
69
+ opacity: 1;
70
+ color: var(--tg-blue);
71
+ }
72
+
73
+ /* =========================================
74
+ STRUCTURE PRINCIPALE (GRID)
75
+ ========================================= */
76
+ .app-container {
77
+ display: grid;
78
+ grid-template-columns: 380px 1fr;
79
+ width: 100%;
80
+ height: 100%;
81
+ max-width: 1600px;
82
+ background-color: var(--tg-bg);
83
+ box-shadow: 0 0 20px rgba(0,0,0,0.5);
84
+ }
85
+
86
+ /* =========================================
87
+ SIDEBAR (LISTE DES CONTACTS)
88
+ ========================================= */
89
+ .sidebar {
90
+ background-color: var(--tg-sidebar-bg);
91
+ border-right: 1px solid #000;
92
+ display: flex;
93
+ flex-direction: column;
94
+ height: 100%;
95
+ position: relative;
96
+ z-index: 2;
97
+ }
98
+
99
+ /* Sidebar Header */
100
+ .sidebar-header {
101
+ height: var(--header-height);
102
+ padding: 10px 15px;
103
+ display: flex;
104
+ align-items: center;
105
+ gap: 15px;
106
+ background-color: var(--tg-sidebar-bg);
107
+ }
108
+
109
+ .menu-btn {
110
+ background: none;
111
+ border: none;
112
+ color: var(--tg-text-secondary);
113
+ font-size: 1.2rem;
114
+ cursor: pointer;
115
+ transition: color 0.2s;
116
+ }
117
+ .menu-btn:hover { color: var(--tg-text-primary); }
118
+
119
+ .search-bar {
120
+ flex: 1;
121
+ background-color: #242f3d;
122
+ border-radius: 20px;
123
+ padding: 8px 15px;
124
+ display: flex;
125
+ align-items: center;
126
+ color: var(--tg-text-secondary);
127
+ }
128
+
129
+ .search-bar input {
130
+ background: transparent;
131
+ border: none;
132
+ color: var(--tg-text-primary);
133
+ width: 100%;
134
+ margin-left: 10px;
135
+ font-size: 0.95rem;
136
+ }
137
+
138
+ /* Contact List */
139
+ .contact-list {
140
+ flex: 1;
141
+ overflow-y: auto;
142
+ scrollbar-width: thin;
143
+ scrollbar-color: var(--scrollbar-thumb) transparent;
144
+ }
145
+
146
+ .contact-list::-webkit-scrollbar {
147
+ width: 6px;
148
+ }
149
+ .contact-list::-webkit-scrollbar-thumb {
150
+ background-color: var(--scrollbar-thumb);
151
+ border-radius: 3px;
152
+ }
153
+
154
+ .contact-item {
155
+ display: flex;
156
+ padding: 10px 15px;
157
+ cursor: pointer;
158
+ transition: background 0.2s;
159
+ align-items: center;
160
+ }
161
+
162
+ .contact-item:hover {
163
+ background-color: var(--tg-item-hover);
164
+ }
165
+
166
+ .contact-item.active {
167
+ background-color: var(--tg-blue);
168
+ }
169
+
170
+ .contact-item.active .last-message,
171
+ .contact-item.active .time,
172
+ .contact-item.active .name {
173
+ color: #fff;
174
+ }
175
+
176
+ .avatar {
177
+ width: 50px;
178
+ height: 50px;
179
+ border-radius: 50%;
180
+ object-fit: cover;
181
+ margin-right: 15px;
182
+ background-color: #ccc;
183
+ }
184
+
185
+ .contact-info {
186
+ flex: 1;
187
+ display: flex;
188
+ flex-direction: column;
189
+ justify-content: center;
190
+ overflow: hidden;
191
+ }
192
+
193
+ .top-row {
194
+ display: flex;
195
+ justify-content: space-between;
196
+ margin-bottom: 4px;
197
+ }
198
+
199
+ .name {
200
+ font-weight: 500;
201
+ font-size: 1rem;
202
+ white-space: nowrap;
203
+ overflow: hidden;
204
+ text-overflow: ellipsis;
205
+ }
206
+
207
+ .time {
208
+ font-size: 0.75rem;
209
+ color: var(--tg-text-secondary);
210
+ }
211
+
212
+ .bottom-row {
213
+ display: flex;
214
+ justify-content: space-between;
215
+ align-items: center;
216
+ }
217
+
218
+ .last-message {
219
+ color: var(--tg-text-secondary);
220
+ font-size: 0.85rem;
221
+ white-space: nowrap;
222
+ overflow: hidden;
223
+ text-overflow: ellipsis;
224
+ max-width: 200px;
225
+ }
226
+
227
+ .unread-badge {
228
+ background-color: var(--tg-blue);
229
+ color: white;
230
+ font-size: 0.75rem;
231
+ padding: 2px 6px;
232
+ border-radius: 10px;
233
+ min-width: 20px;
234
+ text-align: center;
235
+ font-weight: bold;
236
+ }
237
+
238
+ /* =========================================
239
+ CHAT AREA
240
+ ========================================= */
241
+ .chat-area {
242
+ background-color: var(--tg-chat-bg);
243
+ background-image: radial-gradient(#1f2f40 1px, transparent 1px);
244
+ background-size: 20px 20px; /* Pattern subtil */
245
+ display: flex;
246
+ flex-direction: column;
247
+ position: relative;
248
+ }
249
+
250
+ /* Default Placeholder State */
251
+ .empty-state {
252
+ display: flex;
253
+ flex-direction: column;
254
+ align-items: center;
255
+ justify-content: center;
256
+ height: 100%;
257
+ color: var(--tg-text-secondary);
258
+ text-align: center;
259
+ }
260
+ .empty-state i {
261
+ font-size: 5rem;
262
+ margin-bottom: 20px;
263
+ color: #2f3844;
264
+ }
265
+
266
+ /* Chat Header */
267
+ .chat-header {
268
+ height: var(--header-height);
269
+ background-color: var(--tg-sidebar-bg);
270
+ display: flex;
271
+ align-items: center;
272
+ padding: 0 15px;
273
+ justify-content: space-between;
274
+ border-bottom: 1px solid #000;
275
+ z-index: 10;
276
+ }
277
+
278
+ .chat-header-info {
279
+ display: flex;
280
+ align-items: center;
281
+ cursor: pointer;
282
+ }
283
+
284
+ .back-btn {
285
+ display: none; /* Visible only on mobile */
286
+ margin-right: 15px;
287
+ font-size: 1.2rem;
288
+ color: var(--tg-text-secondary);
289
+ background: none;
290
+ border: none;
291
+ cursor: pointer;
292
+ }
293
+
294
+ .chat-header-text {
295
+ display: flex;
296
+ flex-direction: column;
297
+ margin-left: 10px;
298
+ }
299
+
300
+ .chat-name {
301
+ font-weight: 600;
302
+ font-size: 1rem;
303
+ }
304
+ .chat-status {
305
+ font-size: 0.75rem;
306
+ color: var(--tg-text-secondary);
307
+ }
308
+
309
+ .chat-actions {
310
+ display: flex;
311
+ gap: 20px;
312
+ color: var(--tg-text-secondary);
313
+ }
314
+ .chat-actions i {
315
+ cursor: pointer;
316
+ transition: color 0.2s;
317
+ }
318
+ .chat-actions i:hover {
319
+ color: var(--tg-text-primary);
320
+ }
321
+
322
+ /* Messages List */
323
+ .messages-container {
324
+ flex: 1;
325
+ padding: 20px;
326
+ overflow-y: auto;
327
+ display: flex;
328
+ flex-direction: column;
329
+ gap: 8px;
330
+ }
331
+
332
+ .messages-container::-webkit-scrollbar {
333
+ width: 6px;
334
+ }
335
+ .messages-container::-webkit-scrollbar-thumb {
336
+ background-color: rgba(0,0,0,0.2);
337
+ }
338
+
339
+ .message {
340
+ max-width: 65%;
341
+ padding: 8px 12px;
342
+ border-radius: 12px;
343
+ position: relative;
344
+ font-size: 0.95rem;
345
+ line-height: 1.4;
346
+ word-wrap: break-word;
347
+ animation: fadeIn 0.3s ease;
348
+ }
349
+
350
+ @keyframes fadeIn {
351
+ from { opacity: 0; transform: translateY(10px); }
352
+ to { opacity: 1; transform: translateY(0); }
353
+ }
354
+
355
+ .message.received {
356
+ align-self: flex-start;
357
+ background-color: var(--tg-white-msg);
358
+ border-bottom-left-radius: 4px;
359
+ }
360
+
361
+ .message.sent {
362
+ align-self: flex-end;
363
+ background-color: var(--tg-green-msg);
364
+ border-bottom-right-radius: 4px;
365
+ }
366
+
367
+ .msg-meta {
368
+ display: flex;
369
+ justify-content: flex-end;
370
+ align-items: center;
371
+ gap: 4px;
372
+ font-size: 0.7rem;
373
+ color: rgba(255,255,255,0.6);
374
+ margin-top: 4px;
375
+ float: right;
376
+ margin-left: 8px;
377
+ }
378
+
379
+ /* Input Area */
380
+ .input-area {
381
+ min-height: 60px;
382
+ background-color: var(--tg-sidebar-bg);
383
+ padding: 10px 15px;
384
+ display: flex;
385
+ align-items: flex-end;
386
+ gap: 15px;
387
+ }
388
+
389
+ .attach-btn, .emoji-btn {
390
+ color: var(--tg-text-secondary);
391
+ font-size: 1.4rem;
392
+ background: none;
393
+ border: none;
394
+ cursor: pointer;
395
+ padding-bottom: 5px;
396
+ }
397
+
398
+ .message-input-wrapper {
399
+ flex: 1;
400
+ background-color: var(--tg-input-bg);
401
+ border-radius: 10px; /* Plus arrondi style moderne */
402
+ padding: 10px 15px;
403
+ display: flex;
404
+ align-items: center;
405
+ }
406
+
407
+ .message-input {
408
+ width: 100%;
409
+ background: transparent;
410
+ border: none;
411
+ color: var(--tg-text-primary);
412
+ font-size: 1rem;
413
+ resize: none;
414
+ max-height: 100px;
415
+ font-family: inherit;
416
+ }
417
+
418
+ .send-btn {
419
+ color: var(--tg-blue);
420
+ font-size: 1.5rem;
421
+ background: none;
422
+ border: none;
423
+ cursor: pointer;
424
+ padding-bottom: 5px;
425
+ transition: transform 0.1s;
426
+ }
427
+ .send-btn:active {
428
+ transform: scale(0.9);
429
+ }
430
+
431
+ /* =========================================
432
+ RESPONSIVE (MOBILE)
433
+ ========================================= */
434
+ @media (max-width: 800px) {
435
+ .app-container {
436
+ grid-template-columns: 1fr;
437
+ }
438
+
439
+ .chat-area {
440
+ position: absolute;
441
+ top: 0;
442
+ left: 0;
443
+ width: 100%;
444
+ height: 100%;
445
+ transform: translateX(100%);
446
+ transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
447
+ z-index: 5;
448
+ }
449
+
450
+ .chat-area.active {
451
+ transform: translateX(0);
452
+ }
453
+
454
+ .back-btn {
455
+ display: block;
456
+ }
457
+
458
+ .sidebar {
459
+ width: 100%;
460
+ }
461
+ }
462
+ </style>
463
+ </head>
464
+ <body>
465
+
466
+ <!-- Lien crédit obligatoire -->
467
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="anycoder-credit">
468
+ Built with anycoder <i class="fas fa-external-link-alt"></i>
469
+ </a>
470
+
471
+ <div class="app-container">
472
+
473
+ <!-- SIDEBAR -->
474
+ <aside class="sidebar">
475
+ <header class="sidebar-header">
476
+ <button class="menu-btn"><i class="fas fa-bars"></i></button>
477
+ <div class="search-bar">
478
+ <i class="fas fa-search"></i>
479
+ <input type="text" id="searchInput" placeholder="Rechercher">
480
+ </div>
481
+ </header>
482
+
483
+ <div class="contact-list" id="contactList">
484
+ <!-- Les contacts seront injectés ici par JS -->
485
+ </div>
486
+ </aside>
487
+
488
+ <!-- CHAT AREA -->
489
+ <main class="chat-area" id="chatArea">
490
+ <!-- État vide (aucune sélection) -->
491
+ <div class="empty-state" id="emptyState">
492
+ <i class="fab fa-telegram"></i>
493
+ <h2>Sélectionnez un chat</h2>
494
+ <p>pour commencer la conversation</p>
495
+ </div>
496
+
497
+ <!-- Contenu du chat (caché par défaut) -->
498
+ <div id="chatContent" style="display: none; flex-direction: column; height: 100%;">
499
+ <header class="chat-header">
500
+ <div class="chat-header-info">
501
+ <button class="back-btn" id="backBtn"><i class="fas fa-arrow-left"></i></button>
502
+ <img src="" alt="" class="avatar" id="headerAvatar" style="width: 40px; height: 40px;">
503
+ <div class="chat-header-text">
504
+ <span class="chat-name" id="headerName">Nom</span>
505
+ <span class="chat-status" id="headerStatus">en ligne</span>
506
+ </div>
507
+ </div>
508
+ <div class="chat-actions">
509
+ <i class="fas fa-phone"></i>
510
+ <i class="fas fa-video"></i>
511
+ <i class="fas fa-search"></i>
512
+ <i class="fas fa-ellipsis-v"></i>
513
+ </div>
514
+ </header>
515
+
516
+ <div class="messages-container" id="messagesContainer">
517
+ <!-- Messages injectés ici -->
518
+ </div>
519
+
520
+ <footer class="input-area">
521
+ <button class="attach-btn"><i class="fas fa-paperclip"></i></button>
522
+ <div class="message-input-wrapper">
523
+ <input type="text" class="message-input" id="messageInput" placeholder="Écrivez un message..." autocomplete="off">
524
+ </div>
525
+ <button class="emoji-btn"><i class="far fa-smile"></i></button>
526
+ <button class="send-btn" id="sendBtn"><i class="fas fa-paper-plane"></i></button>
527
+ </footer>
528
+ </div>
529
+ </main>
530
+ </div>
531
+
532
+ <script>
533
+ // =========================================
534
+ // DONNÉES SIMULÉES (MOCK DATA)
535
+ // =========================================
536
+ const contactsData = [
537
+ {
538
+ id: 1,
539
+ name: "Sophie Martin",
540
+ avatar: "https://picsum.photos/seed/sophie/100/100",
541
+ time: "14:30",
542
+ unread: 2,
543
+ lastMsg: "Tu as vu le nouveau projet ?",
544
+ status: "en ligne",
545
+ messages: [
546
+ { id: 1, text: "Salut ! Comment ça va ?", type: "received", time: "14:25" },
547
+ { id: 2, text: "Ça va super, et toi ?", type: "sent", time: "14:26", read: true },
548
+ { id: 3, text: "Très bien. Tu as vu le nouveau projet ?", type: "received", time: "14:30" }
549
+ ]
550
+ },
551
+ {
552
+ id: 2,
553
+ name: "Groupe Développement",
554
+ avatar: "https://picsum.photos/seed/dev/100/100",
555
+ time: "12:15",
556
+ unread: 0,
557
+ lastMsg: "Lucas: Le merge est ready",
558
+ status: "5 membres",
559
+ messages: [
560
+ { id: 1, text: "Avez-vous pushé le code ?", type: "received", time: "12:00" },
561
+ { id: 2, text: "Je le fais maintenant.", type: "sent", time: "12:05", read: true },
562
+ { id: 3, text: "Lucas: Le merge est ready", type: "received", time: "12:15" }
563
+ ]
564
+ },
565
+ {
566
+ id: 3,
567
+ name: "Marc Dupont",
568
+ avatar: "https://picsum.photos/seed/marc/100/100",
569
+ time: "Hier",
570
+ unread: 0,
571
+ lastMsg: "Ok, à demain alors !",
572
+ status: "dernière connexion hier à 23h",
573
+ messages: [
574
+ { id: 1, text: "On se voit demain matin ?", type: "received", time: "Hier" },
575
+ { id: 2, text: "Oui, sans problème.", type: "sent", time: "Hier", read: true },
576
+ { id: 3, text: "Ok, à demain alors !", type: "received", time: "Hier" }
577
+ ]
578
+ },
579
+ {
580
+ id: 4,
581
+ name: "Service Client",
582
+ avatar: "https://picsum.photos/seed/support/100/100",
583
+ time: "Mar",
584
+ unread: 1,
585
+ lastMsg: "Votre ticket a été résolu.",
586
+ status: "bot",
587
+ messages: [
588
+ { id: 1, text: "Bonjour, comment pouvons-nous vous aider ?", type: "received", time: "Mar" },
589
+ { id: 2, text: "J'ai un souci de connexion.", type: "sent", time: "Mar", read: false },
590
+ { id: 3, text: "Votre ticket a été résolu.", type: "received", time: "Mar" }
591
+ ]
592
+ },
593
+ {
594
+ id: 5,
595
+ name: "Julie Design",
596
+ avatar: "https://picsum.photos/seed/julie/100/100",
597
+ time: "Lun",
598
+ unread: 0,
599
+ lastMsg: "J'adore les nouvelles couleurs !",
600
+ status: "en ligne",
601
+ messages: [
602
+ { id: 1, text: "Tu as vu les maquettes ?", type: "sent", time: "Lun", read: true },
603
+ { id: 2, text: "J'adore les nouvelles couleurs !", type: "received", time: "Lun" }
604
+ ]
605
+ }
606
+ ];
607
+
608
+ let activeContactId = null;
609
+
610
+ // =========================================
611
+ // DOM ELEMENTS
612
+ // =========================================
613
+ const contactListEl = document.getElementById('contactList');
614
+ const emptyStateEl = document.getElementById('emptyState');
615
+ const chatContentEl = document.getElementById('chatContent');
616
+ const chatAreaEl = document.getElementById('chatArea');
617
+
618
+ // Header Chat
619
+ const headerName = document.getElementById('headerName');
620
+ const headerStatus = document.getElementById('headerStatus');
621
+ const headerAvatar = document.getElementById('headerAvatar');
622
+
623
+ // Messages
624
+ const messagesContainer = document.getElementById('messagesContainer');
625
+
626
+ // Input
627
+ const messageInput = document.getElementById('messageInput');
628
+ const sendBtn = document.getElementById('sendBtn');
629
+ const searchInput = document.getElementById('searchInput');
630
+ const backBtn = document.getElementById('backBtn');
631
+
632
+ // =========================================
633
+ // FONCTIONS
634
+ // =========================================
635
+
636
+ // 1. Rendu de la liste des contacts
637
+ function renderContacts(filter = "") {
638
+ contactListEl.innerHTML = "";
639
+
640
+ const filteredContacts = contactsData.filter(c =>
641
+ c.name.toLowerCase().includes(filter.toLowerCase())
642
+ );
643
+
644
+ filteredContacts.forEach(contact => {
645
+ const li = document.createElement('div');
646
+ li.className = `contact-item ${activeContactId === contact.id ? 'active' : ''}`;
647
+ li.onclick = () => openChat(contact.id);
648
+
649
+ let unreadHtml = contact.unread > 0
650
+ ? `<span class="unread-badge">${contact.unread}</span>`
651
+ : '';
652
+
653
+ li.innerHTML = `
654
+ <img src="${contact.avatar}" alt="${contact.name}" class="avatar">
655
+ <div class="contact-info">
656
+ <div class="top-row">
657
+ <span class="name">${contact.name}</span>
658
+ <span class="time">${contact.time}</span>
659
+ </div>
660
+ <div class="bottom-row">
661
+ <span class="last-message">${contact.lastMsg}</span>
662
+ ${unreadHtml}
663
+ </div>
664
+ </div>
665
+ `;
666
+ contactListEl.appendChild(li);
667
+ });
668
+ }
669
+
670
+ // 2. Ouvrir un chat
671
+ function openChat(id) {
672
+ activeContactId = id;
673
+ const contact = contactsData.find(c => c.id === id);
674
+
675
+ // UI Updates
676
+ renderContacts(searchInput.value); // Refresh pour mettre la classe active
677
+ emptyStateEl.style.display = 'none';
678
+ chatContentEl.style.display = 'flex';
679
+
680
+ // Mobile: Slide effect
681
+ chatAreaEl.classList.add('active');
682
+
683
+ // Header Info
684
+ headerName.textContent = contact.name;
685
+ headerStatus.textContent = contact.status;
686
+ headerAvatar.src = contact.avatar;
687
+
688
+ // Reset unread count
689
+ contact.unread = 0;
690
+ renderContacts(searchInput.value);
691
+
692
+ // Render Messages
693
+ renderMessages(contact.messages);
694
+
695
+ // Focus input
696
+ messageInput.focus();
697
+ }
698
+
699
+ // 3. Afficher les messages
700
+ function renderMessages(messages) {
701
+ messagesContainer.innerHTML = "";
702
+
703
+ // Date divider (fake)
704
+ const dateDiv = document.createElement('div');
705
+ dateDiv.style.textAlign = 'center';
706
+ dateDiv.style.margin = '10px 0';
707
+ dateDiv.innerHTML = '<span style="background:rgba(0,0,0,0.2); padding:4px 10px; border-radius:10px; font-size:0.75rem; color:#aaa;">Aujourd\'hui</span>';
708
+ messagesContainer.appendChild(dateDiv);
709
+
710
+ messages.forEach(msg => {
711
+ appendMessageToDOM(msg);
712
+ });
713
+ scrollToBottom();
714
+ }
715
+
716
+ // 4. Ajouter un message au DOM
717
+ function appendMessageToDOM(msg) {
718
+ const div = document.createElement('div');
719
+ div.className = `message ${msg.type}`;
720
+
721
+ const checks = msg.type === 'sent'
722
+ ? (msg.read ? '<i class="fas fa-check-double"></i>' : '<i class="fas fa-check"></i>')
723
+ : '';
724
+
725
+ div.innerHTML = `
726
+ ${msg.text}
727
+ <span class="msg-meta">
728
+ ${msg.time} ${checks}
729
+ </span>
730
+ `;
731
+ messagesContainer.appendChild(div);
732
+ }
733
+
734
+ // 5. Scroll en bas
735
+ function scrollToBottom() {
736
+ messagesContainer.scrollTop = messagesContainer.scrollHeight;
737
+ }
738
+
739
+ // 6. Envoyer un message
740
+ function sendMessage() {
741
+ const text = messageInput.value.trim();
742
+ if (!text || !activeContactId) return;
743
+
744
+ const contact = contactsData.find(c => c.id === activeContactId);
745
+ const now = new Date();
746
+ const timeString = now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0');
747
+
748
+ // Création objet message
749
+ const newMsg = {
750
+ id: Date.now(),
751
+ text: text,
752
+ type: 'sent',
753
+ time: timeString,
754
+ read: false
755
+ };
756
+
757
+ // Update Data
758
+ contact.messages.push(newMsg);
759
+ contact.lastMsg = text;
760
+ contact.time = timeString;
761
+
762
+ // Update UI
763
+ appendMessageToDOM(newMsg);
764
+ messageInput.value = "";
765
+ scrollToBottom();
766
+ renderContacts(searchInput.value); // Update preview in sidebar
767
+
768
+ // Simulation réponse automatique
769
+ simulateReply(contact);
770
+ }
771
+
772
+ // 7. Simulation de réponse (Bot)
773
+ function simulateReply(contact) {
774
+ const replies = [
775
+ "C'est intéressant !",
776
+ "Je suis d'accord.",
777
+ "Tu pourrais m'en dire plus ?",
778
+ "Ok, je note ça.",
779
+ "Haha, trop drôle ! 😂",
780
+ "Je suis occupé là, je te réponds plus tard."
781
+ ];
782
+
783
+ // Random delay entre 1s et 3s
784
+ const delay = Math.floor(Math.random() * 2000) + 1000;
785
+
786
+ setTimeout(() => {
787
+ // On vérifie si on est toujours sur le même chat
788
+ if (activeContactId === contact.id) {
789
+ const replyText = replies[Math.floor(Math.random() * replies.length)];
790
+ const now = new Date();
791
+ const timeString = now.getHours().toString().padStart(2, '0') + ':' + now.getMinutes().toString().padStart(2, '0');
792
+
793
+ const replyMsg = {
794
+ id: Date.now(),
795
+ text: replyText,
796
+ type: 'received',
797
+ time: timeString
798
+ };
799
+
800
+ contact.messages.push(replyMsg);
801
+ contact.lastMsg = replyText;
802
+ contact.time = timeString;
803
+
804
+ appendMessageToDOM(replyMsg);
805
+ scrollToBottom();
806
+
807
+ // Marquer le message envoyé précédemment comme "lu"
808
+ const lastSent = contact.messages.filter(m => m.type === 'sent').pop();
809
+ if(lastSent) lastSent.read = true;
810
+
811
+ // Rafraichir la vue (pour les checks bleus)
812
+ // Dans une vraie app on ne rafraichirait pas tout, mais ici c'est simple
813
+ renderMessages(contact.messages);
814
+ renderContacts(searchInput.value);
815
+
816
+ } else {
817
+ // Si l'utilisateur a changé de chat, on incrémente les non-lus
818
+ contact.unread++;
819
+ const replyText = "Nouveau message reçu";
820
+ contact.lastMsg = replyText;
821
+ renderContacts(searchInput.value);
822
+ }
823
+ }, delay);
824
+ }
825
+
826
+ // =========================================
827
+ // EVENT LISTENERS
828
+ // =========================================
829
+
830
+ // Clic sur envoyer
831
+ sendBtn.addEventListener('click', sendMessage);
832
+
833
+ // Touche Entrée
834
+ messageInput.addEventListener('keypress', (e) => {
835
+ if (e.key === 'Enter') sendMessage();
836
+ });
837
+
838
+ // Recherche
839
+ searchInput.addEventListener('input', (e) => {
840
+ renderContacts(e.target.value);
841
+ });
842
+
843
+ // Bouton retour (Mobile)
844
+ backBtn.addEventListener('click', () => {
845
+ chatAreaEl.classList.remove('active');
846
+ setTimeout(() => {
847
+ activeContactId = null;
848
+ // Optionnel: désélectionner visuellement dans la sidebar
849
+ renderContacts(searchInput.value);
850
+ }, 300);
851
+ });
852
+
853
+ // Initialisation
854
+ renderContacts();
855
+
856
+ </script>
857
+ </body>
858
+ </html>