samirerty commited on
Commit
a0a7ec2
·
verified ·
1 Parent(s): 1336782

Upload folder using huggingface_hub

Browse files
Files changed (1) hide show
  1. index.html +680 -1186
index.html CHANGED
@@ -3,1300 +3,794 @@
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>چت روم | پلتفرم گفتگوی آنلاین</title>
 
 
 
 
 
 
7
 
8
  <!-- Google Fonts: Vazirmatn for Persian -->
9
- <link rel="preconnect" href="https://fonts.googleapis.com">
10
- <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
11
  <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100;300;400;500;700;900&display=swap" rel="stylesheet">
12
-
13
- <!-- Phosphor Icons -->
14
- <script src="https://unpkg.com/@phosphor-icons/web"></script>
15
 
16
- <style>
17
- :root {
18
- --primary: #6366f1;
19
- --primary-dark: #4f46e5;
20
- --secondary: #ec4899;
21
- --bg: #0f172a;
22
- --surface: #1e293b;
23
- --surface-light: #334155;
24
- --text: #f8fafc;
25
- --text-muted: #94a3b8;
26
- --success: #10b981;
27
- --warning: #f59e0b;
28
- --error: #ef4444;
29
- --glass: rgba(30, 41, 59, 0.7);
30
- --shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.5);
31
- --radius: 1rem;
32
- }
33
-
34
- * {
35
- margin: 0;
36
- padding: 0;
37
- box-sizing: border-box;
38
- }
39
 
40
- body {
41
- font-family: 'Vazirmatn', sans-serif;
42
- background: var(--bg);
43
- color: var(--text);
44
- min-height: 100vh;
45
- overflow-x: hidden;
46
- line-height: 1.6;
47
- }
48
-
49
- /* Animated Background */
50
- .bg-animation {
51
- position: fixed;
52
- top: 0;
53
- left: 0;
54
- width: 100%;
55
- height: 100%;
56
- z-index: -1;
57
- background:
58
- radial-gradient(circle at 20% 50%, rgba(99, 102, 241, 0.15) 0%, transparent 50%),
59
- radial-gradient(circle at 80% 80%, rgba(236, 72, 153, 0.15) 0%, transparent 50%),
60
- radial-gradient(circle at 40% 20%, rgba(16, 185, 129, 0.1) 0%, transparent 50%);
61
- filter: blur(60px);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  }
 
63
 
64
- /* Scrollbar */
 
65
  ::-webkit-scrollbar {
66
  width: 8px;
67
  }
68
  ::-webkit-scrollbar-track {
69
- background: var(--bg);
70
  }
71
  ::-webkit-scrollbar-thumb {
72
- background: var(--surface-light);
73
  border-radius: 4px;
74
  }
75
  ::-webkit-scrollbar-thumb:hover {
76
- background: var(--primary);
77
- }
78
-
79
- /* Layout */
80
- .container {
81
- max-width: 1200px;
82
- margin: 0 auto;
83
- padding: 1rem;
84
- min-height: 100vh;
85
  }
86
 
87
- .hidden {
88
- display: none !important;
 
 
 
 
89
  }
90
-
91
- /* Header */
92
- header {
93
- display: flex;
94
- justify-content: space-between;
95
- align-items: center;
96
- padding: 1rem 2rem;
97
- background: var(--glass);
98
  backdrop-filter: blur(12px);
99
- border-bottom: 1px solid rgba(255,255,255,0.1);
100
- position: sticky;
101
- top: 0;
102
- z-index: 100;
103
- }
104
-
105
- .logo {
106
- display: flex;
107
- align-items: center;
108
- gap: 0.5rem;
109
- font-size: 1.5rem;
110
- font-weight: 900;
111
- background: linear-gradient(135deg, var(--primary), var(--secondary));
112
- -webkit-background-clip: text;
113
- -webkit-text-fill-color: transparent;
114
- text-decoration: none;
115
  }
116
 
117
- .nav-links {
118
- display: flex;
119
- gap: 2rem;
120
- align-items: center;
121
  }
122
-
123
- .nav-links a {
124
- color: var(--text-muted);
125
- text-decoration: none;
126
- font-weight: 500;
127
- transition: all 0.3s;
128
- display: flex;
129
- align-items: center;
130
- gap: 0.5rem;
131
- }
132
-
133
- .nav-links a:hover {
134
- color: var(--text);
135
- transform: translateY(-2px);
136
  }
137
-
138
- .user-menu {
139
- display: flex;
140
- align-items: center;
141
- gap: 1rem;
142
- }
143
-
144
- .avatar-small {
145
- width: 40px;
146
- height: 40px;
147
  border-radius: 50%;
148
- background: var(--surface);
149
- display: flex;
150
- align-items: center;
151
- justify-content: center;
152
- font-size: 1.5rem;
153
- border: 2px solid var(--primary);
154
- cursor: pointer;
155
- transition: transform 0.3s;
156
- }
157
-
158
- .avatar-small:hover {
159
- transform: scale(1.1);
160
- }
161
-
162
- /* Buttons */
163
- .btn {
164
- padding: 0.75rem 1.5rem;
165
- border: none;
166
- border-radius: var(--radius);
167
- font-family: inherit;
168
- font-weight: 600;
169
- cursor: pointer;
170
- transition: all 0.3s;
171
- display: inline-flex;
172
- align-items: center;
173
- justify-content: center;
174
- gap: 0.5rem;
175
- font-size: 1rem;
176
- }
177
-
178
- .btn-primary {
179
- background: linear-gradient(135deg, var(--primary), var(--primary-dark));
180
- color: white;
181
- box-shadow: 0 4px 15px rgba(99, 102, 241, 0.4);
182
- }
183
-
184
- .btn-primary:hover {
185
- transform: translateY(-2px);
186
- box-shadow: 0 8px 25px rgba(99, 102, 241, 0.6);
187
- }
188
-
189
- .btn-secondary {
190
- background: var(--surface);
191
- color: var(--text);
192
- border: 1px solid var(--surface-light);
193
- }
194
-
195
- .btn-secondary:hover {
196
- background: var(--surface-light);
197
- }
198
-
199
- .btn-danger {
200
- background: rgba(239, 68, 68, 0.2);
201
- color: var(--error);
202
- border: 1px solid var(--error);
203
- }
204
-
205
- .btn-danger:hover {
206
- background: var(--error);
207
- color: white;
208
- }
209
-
210
- .btn-ghost {
211
- background: transparent;
212
- color: var(--text-muted);
213
- }
214
-
215
- .btn-ghost:hover {
216
- color: var(--text);
217
- background: rgba(255,255,255,0.05);
218
  }
219
-
220
- /* Cards */
221
- .card {
222
- background: var(--glass);
223
- backdrop-filter: blur(12px);
224
- border: 1px solid rgba(255,255,255,0.1);
225
- border-radius: var(--radius);
226
- padding: 2rem;
227
- box-shadow: var(--shadow);
228
- }
229
-
230
- /* Forms */
231
- .form-group {
232
- margin-bottom: 1.5rem;
233
- }
234
-
235
- .form-group label {
236
- display: block;
237
- margin-bottom: 0.5rem;
238
- color: var(--text-muted);
239
- font-weight: 500;
240
- }
241
-
242
- .form-control {
243
- width: 100%;
244
- padding: 0.75rem 1rem;
245
- background: var(--surface);
246
- border: 1px solid var(--surface-light);
247
- border-radius: var(--radius);
248
- color: var(--text);
249
- font-family: inherit;
250
- font-size: 1rem;
251
- transition: all 0.3s;
252
- }
253
-
254
- .form-control:focus {
255
- outline: none;
256
- border-color: var(--primary);
257
- box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
258
- }
259
-
260
- /* Landing Page */
261
- .hero {
262
- min-height: 80vh;
263
- display: flex;
264
- flex-direction: column;
265
- justify-content: center;
266
- align-items: center;
267
- text-align: center;
268
- padding: 2rem;
269
- }
270
-
271
- .hero h1 {
272
- font-size: clamp(2.5rem, 8vw, 4rem);
273
- font-weight: 900;
274
- margin-bottom: 1rem;
275
- line-height: 1.2;
276
- }
277
-
278
- .hero h1 span {
279
- background: linear-gradient(135deg, var(--primary), var(--secondary));
280
- -webkit-background-clip: text;
281
- -webkit-text-fill-color: transparent;
282
- }
283
-
284
- .hero p {
285
- font-size: 1.25rem;
286
- color: var(--text-muted);
287
- max-width: 600px;
288
- margin-bottom: 2rem;
289
- }
290
-
291
- .features {
292
- display: grid;
293
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
294
- gap: 2rem;
295
- margin-top: 4rem;
296
- width: 100%;
297
- max-width: 1000px;
298
- }
299
-
300
- .feature-card {
301
- background: var(--glass);
302
- padding: 2rem;
303
- border-radius: var(--radius);
304
- border: 1px solid rgba(255,255,255,0.1);
305
- transition: transform 0.3s;
306
- }
307
-
308
- .feature-card:hover {
309
- transform: translateY(-5px);
310
- border-color: var(--primary);
311
  }
 
 
 
312
 
313
- .feature-card i {
314
- font-size: 2.5rem;
315
- color: var(--primary);
316
- margin-bottom: 1rem;
317
- }
318
 
319
- /* Auth Pages */
320
- .auth-container {
321
- min-height: 80vh;
322
- display: flex;
323
- align-items: center;
324
- justify-content: center;
325
- padding: 2rem;
326
- }
327
 
328
- .auth-box {
329
- width: 100%;
330
- max-width: 450px;
331
- }
 
 
 
 
332
 
333
- .auth-header {
334
- text-align: center;
335
- margin-bottom: 2rem;
336
- }
 
337
 
338
- .auth-header h2 {
339
- font-size: 2rem;
340
- margin-bottom: 0.5rem;
341
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
 
343
- .auth-header p {
344
- color: var(--text-muted);
345
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
346
 
347
- /* Rooms Grid */
348
- .rooms-grid {
349
- display: grid;
350
- grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
351
- gap: 1.5rem;
352
- margin-top: 2rem;
353
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
354
 
355
- .room-card {
356
- background: var(--surface);
357
- border-radius: var(--radius);
358
- padding: 1.5rem;
359
- border: 1px solid var(--surface-light);
360
- transition: all 0.3s;
361
- position: relative;
362
- overflow: hidden;
363
- }
 
 
364
 
365
- .room-card::before {
366
- content: '';
367
- position: absolute;
368
- top: 0;
369
- left: 0;
370
- width: 100%;
371
- height: 4px;
372
- background: linear-gradient(90deg, var(--primary), var(--secondary));
373
- transform: scaleX(0);
374
- transition: transform 0.3s;
375
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
376
 
377
- .room-card:hover::before {
378
- transform: scaleX(1);
379
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
380
 
381
- .room-card:hover {
382
- transform: translateY(-3px);
383
- border-color: var(--primary);
384
- box-shadow: 0 10px 30px rgba(0,0,0,0.3);
385
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
386
 
387
- .room-header {
388
- display: flex;
389
- justify-content: space-between;
390
- align-items: start;
391
- margin-bottom: 1rem;
392
- }
393
 
394
- .room-title {
395
- font-size: 1.25rem;
396
- font-weight: 700;
397
- }
 
 
 
 
 
 
 
 
398
 
399
- .room-meta {
400
- display: flex;
401
- gap: 1rem;
402
- color: var(--text-muted);
403
- font-size: 0.875rem;
404
- margin-bottom: 1rem;
405
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
406
 
407
- .room-actions {
408
- display: flex;
409
- gap: 0.5rem;
410
- margin-top: 1rem;
411
- }
 
 
 
 
 
412
 
413
- .btn-small {
414
- padding: 0.5rem 1rem;
415
- font-size: 0.875rem;
416
- }
417
 
418
- /* Chat Layout */
419
- .chat-container {
420
- display: grid;
421
- grid-template-columns: 300px 1fr;
422
- height: calc(100vh - 80px);
423
- gap: 1rem;
424
- padding: 1rem;
425
- }
426
 
427
- .sidebar {
428
- background: var(--glass);
429
- backdrop-filter: blur(12px);
430
- border-radius: var(--radius);
431
- border: 1px solid rgba(255,255,255,0.1);
432
- display: flex;
433
- flex-direction: column;
434
- overflow: hidden;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
435
  }
436
 
437
- .sidebar-header {
438
- padding: 1.5rem;
439
- border-bottom: 1px solid rgba(255,255,255,0.1);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
440
  }
441
 
442
- .users-list {
443
- flex: 1;
444
- overflow-y: auto;
445
- padding: 1rem;
446
- }
447
 
448
- .user-item {
449
- display: flex;
450
- align-items: center;
451
- gap: 0.75rem;
452
- padding: 0.75rem;
453
- border-radius: 0.5rem;
454
- margin-bottom: 0.5rem;
455
- transition: background 0.3s;
456
- }
457
 
458
- .user-item:hover {
459
- background: rgba(255,255,255,0.05);
460
- }
 
461
 
462
- .user-item .avatar {
463
- width: 40px;
464
- height: 40px;
465
- border-radius: 50%;
466
- background: var(--surface-light);
467
- display: flex;
468
- align-items: center;
469
- justify-content: center;
470
- font-size: 1.25rem;
471
- }
472
 
473
- .user-item .info {
474
- flex: 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
475
  }
476
 
477
- .user-item .name {
478
- font-weight: 600;
479
- font-size: 0.9rem;
 
 
480
  }
481
 
482
- .user-item .status {
483
- font-size: 0.75rem;
484
- color: var(--success);
485
- display: flex;
486
- align-items: center;
487
- gap: 0.25rem;
488
- }
489
 
490
- .chat-area {
491
- background: var(--glass);
492
- backdrop-filter: blur(12px);
493
- border-radius: var(--radius);
494
- border: 1px solid rgba(255,255,255,0.1);
495
- display: flex;
496
- flex-direction: column;
497
- overflow: hidden;
498
  }
499
 
500
- .chat-header {
501
- padding: 1rem 1.5rem;
502
- border-bottom: 1px solid rgba(255,255,255,0.1);
503
- display: flex;
504
- justify-content: space-between;
505
- align-items: center;
506
- }
 
507
 
508
- .chat-messages {
509
- flex: 1;
510
- overflow-y: auto;
511
- padding: 1.5rem;
512
- display: flex;
513
- flex-direction: column;
514
- gap: 1rem;
515
  }
516
 
517
- .message {
518
- max-width: 70%;
519
- padding: 1rem;
520
- border-radius: var(--radius);
521
- position: relative;
522
- animation: messageSlide 0.3s ease-out;
523
- }
524
 
525
- @keyframes messageSlide {
526
- from {
527
- opacity: 0;
528
- transform: translateY(10px);
529
- }
530
- to {
531
- opacity: 1;
532
- transform: translateY(0);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
  }
534
- }
535
-
536
- .message.own {
537
- align-self: flex-end;
538
- background: linear-gradient(135deg, var(--primary), var(--primary-dark));
539
- color: white;
540
- border-bottom-right-radius: 0.25rem;
541
- }
542
-
543
- .message.other {
544
- align-self: flex-start;
545
- background: var(--surface);
546
- border-bottom-left-radius: 0.25rem;
547
- }
548
-
549
- .message-header {
550
- display: flex;
551
- align-items: center;
552
- gap: 0.5rem;
553
- margin-bottom: 0.5rem;
554
- font-size: 0.875rem;
555
- opacity: 0.9;
556
- }
557
 
558
- .message-text {
559
- line-height: 1.5;
560
- }
561
-
562
- .message-time {
563
- font-size: 0.75rem;
564
- opacity: 0.7;
565
- margin-top: 0.5rem;
566
- text-align: left;
567
- }
568
-
569
- .chat-input-area {
570
- padding: 1rem 1.5rem;
571
- border-top: 1px solid rgba(255,255,255,0.1);
572
- display: flex;
573
- gap: 0.75rem;
574
- }
575
 
576
- .chat-input {
577
- flex: 1;
578
- background: var(--surface);
579
- border: 1px solid var(--surface-light);
580
- border-radius: 2rem;
581
- padding: 0.75rem 1.25rem;
582
- color: var(--text);
583
- font-family: inherit;
584
- font-size: 1rem;
585
- transition: all 0.3s;
 
 
 
 
586
  }
587
 
588
- .chat-input:focus {
589
- outline: none;
590
- border-color: var(--primary);
591
  }
592
 
593
- .btn-icon {
594
- width: 48px;
595
- height: 48px;
596
- border-radius: 50%;
597
- display: flex;
598
- align-items: center;
599
- justify-content: center;
600
- padding: 0;
601
  }
602
 
603
- /* Settings */
604
- .settings-grid {
605
- display: grid;
606
- grid-template-columns: 250px 1fr;
607
- gap: 2rem;
608
- max-width: 900px;
609
- margin: 2rem auto;
610
- }
611
 
612
- .settings-nav {
613
- display: flex;
614
- flex-direction: column;
615
- gap: 0.5rem;
616
- }
617
 
618
- .settings-nav-item {
619
- padding: 1rem;
620
- border-radius: var(--radius);
621
- cursor: pointer;
622
- transition: all 0.3s;
623
- display: flex;
624
- align-items: center;
625
- gap: 0.75rem;
626
- color: var(--text-muted);
 
 
 
 
 
 
 
 
 
627
  }
628
 
629
- .settings-nav-item:hover,
630
- .settings-nav-item.active {
631
- background: var(--surface);
632
- color: var(--text);
633
- }
634
 
635
- .settings-nav-item.active {
636
- background: var(--primary);
637
- color: white;
638
- }
639
 
640
- .settings-content {
641
- background: var(--glass);
642
- backdrop-filter: blur(12px);
643
- border-radius: var(--radius);
644
- padding: 2rem;
645
- border: 1px solid rgba(255,255,255,0.1);
 
 
 
 
646
  }
647
 
648
- .avatar-selector {
649
- display: grid;
650
- grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));
651
- gap: 1rem;
652
- margin-top: 1rem;
653
- }
654
 
655
- .avatar-option {
656
- aspect-ratio: 1;
657
- background: var(--surface);
658
- border-radius: 1rem;
659
- display: flex;
660
- align-items: center;
661
- justify-content: center;
662
- font-size: 2.5rem;
663
- cursor: pointer;
664
- border: 2px solid transparent;
665
- transition: all 0.3s;
666
- }
667
 
668
- .avatar-option:hover {
669
- transform: scale(1.1);
670
- border-color: var(--primary);
671
- }
672
 
673
- .avatar-option.selected {
674
- border-color: var(--primary);
675
- background: rgba(99, 102, 241, 0.2);
676
- box-shadow: 0 0 20px rgba(99, 102, 241, 0.3);
677
- }
 
 
678
 
679
- /* Toast Notifications */
680
- .toast-container {
681
- position: fixed;
682
- top: 100px;
683
- left: 2rem;
684
- z-index: 1000;
685
- display: flex;
686
- flex-direction: column;
687
- gap: 0.5rem;
688
  }
689
 
690
- .toast {
691
- background: var(--surface);
692
- color: var(--text);
693
- padding: 1rem 1.5rem;
694
- border-radius: var(--radius);
695
- border-right: 4px solid var(--primary);
696
- box-shadow: var(--shadow);
697
- display: flex;
698
- align-items: center;
699
- gap: 0.75rem;
700
- animation: slideIn 0.3s ease-out;
701
- min-width: 300px;
702
  }
703
 
704
- .toast.success { border-right-color: var(--success); }
705
- .toast.error { border-right-color: var(--error); }
706
- .toast.warning { border-right-color: var(--warning); }
707
-
708
- @keyframes slideIn {
709
- from {
710
- transform: translateX(-100%);
711
- opacity: 0;
712
- }
713
- to {
714
- transform: translateX(0);
715
- opacity: 1;
 
 
 
716
  }
 
 
717
  }
718
 
719
- /* Responsive */
720
- @media (max-width: 768px) {
721
- .chat-container {
722
- grid-template-columns: 1fr;
723
- }
724
 
725
- .sidebar {
726
- display: none;
727
- }
728
 
729
- .settings-grid {
730
- grid-template-columns: 1fr;
731
- }
732
 
733
- .nav-links {
734
- display: none;
735
- }
 
 
 
 
 
 
 
 
 
 
 
736
 
737
- .message {
738
- max-width: 85%;
739
- }
740
- }
741
-
742
- /* Empty State */
743
- .empty-state {
744
- text-align: center;
745
- padding: 4rem 2rem;
746
- color: var(--text-muted);
747
- }
748
-
749
- .empty-state i {
750
- font-size: 4rem;
751
- margin-bottom: 1rem;
752
- opacity: 0.5;
753
- }
754
-
755
- /* Modal */
756
- .modal-overlay {
757
- position: fixed;
758
- top: 0;
759
- left: 0;
760
- width: 100%;
761
- height: 100%;
762
- background: rgba(0,0,0,0.8);
763
- backdrop-filter: blur(5px);
764
- display: flex;
765
- align-items: center;
766
- justify-content: center;
767
- z-index: 1000;
768
- opacity: 0;
769
- visibility: hidden;
770
- transition: all 0.3s;
771
- }
772
-
773
- .modal-overlay.active {
774
- opacity: 1;
775
- visibility: visible;
776
- }
777
-
778
- .modal {
779
- background: var(--surface);
780
- border-radius: var(--radius);
781
- padding: 2rem;
782
- width: 90%;
783
- max-width: 500px;
784
- transform: scale(0.9);
785
- transition: transform 0.3s;
786
- }
787
-
788
- .modal-overlay.active .modal {
789
- transform: scale(1);
790
- }
791
-
792
- .modal-header {
793
- display: flex;
794
- justify-content: space-between;
795
- align-items: center;
796
- margin-bottom: 1.5rem;
797
- }
798
-
799
- .modal-header h3 {
800
- font-size: 1.5rem;
801
  }
802
 
803
- .close-btn {
804
- background: none;
805
- border: none;
806
- color: var(--text-muted);
807
- font-size: 1.5rem;
808
- cursor: pointer;
809
- transition: color 0.3s;
810
- }
811
-
812
- .close-btn:hover {
813
- color: var(--text);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
814
  }
815
 
816
- /* Built with anycoder */
817
- .built-with {
818
- position: fixed;
819
- bottom: 1rem;
820
- left: 1rem;
821
- background: rgba(99, 102, 241, 0.2);
822
- color: var(--primary);
823
- padding: 0.5rem 1rem;
824
- border-radius: 2rem;
825
- font-size: 0.875rem;
826
- text-decoration: none;
827
- border: 1px solid rgba(99, 102, 241, 0.3);
828
- transition: all 0.3s;
829
- z-index: 50;
830
  }
831
 
832
- .built-with:hover {
833
- background: var(--primary);
834
- color: white;
835
- transform: translateY(-2px);
 
 
 
 
 
 
 
836
  }
837
- </style>
838
- </head>
839
- <body>
840
- <div class="bg-animation"></div>
841
-
842
- <!-- Toast Container -->
843
- <div class="toast-container" id="toastContainer"></div>
844
-
845
- <!-- Header -->
846
- <header id="mainHeader" class="hidden">
847
- <a href="#" class="logo" onclick="router.navigate('home')">
848
- <i class="ph ph-chat-circle-text"></i>
849
- <span>چت روم</span>
850
- </a>
851
-
852
- <nav class="nav-links">
853
- <a href="#" onclick="router.navigate('rooms')">
854
- <i class="ph ph-house"></i>
855
- روم‌های من
856
- </a>
857
- <a href="#" onclick="router.navigate('settings')">
858
- <i class="ph ph-gear"></i>
859
- تنظیمات
860
- </a>
861
- </nav>
862
-
863
- <div class="user-menu">
864
- <span id="userNameDisplay"></span>
865
- <div class="avatar-small" id="headerAvatar" onclick="router.navigate('settings')"></div>
866
- <button class="btn btn-ghost" onclick="auth.logout()">
867
- <i class="ph ph-sign-out"></i>
868
- </button>
869
- </div>
870
- </header>
871
-
872
- <!-- Main Container -->
873
- <div class="container">
874
-
875
- <!-- Landing Page -->
876
- <section id="page-home" class="page">
877
- <div class="hero">
878
- <h1>به <span>چت روم</span> خوش آمدید</h1>
879
- <p>پلتفرم گفتگوی آنلاین با قابلیت ایجاد روم‌های خصوصی، اشتراک‌گذاری لینک و چت لحظه‌ای با دوستان</p>
880
-
881
- <div style="display: flex; gap: 1rem; flex-wrap: wrap; justify-content: center;">
882
- <button class="btn btn-primary btn-lg" onclick="router.navigate('register')">
883
- <i class="ph ph-user-plus"></i>
884
- شروع کنید
885
- </button>
886
- <button class="btn btn-secondary" onclick="document.getElementById('features').scrollIntoView({behavior: 'smooth'})">
887
- <i class="ph ph-info"></i>
888
- بیشتر بدانید
889
- </button>
890
- </div>
891
-
892
- <div class="features" id="features">
893
- <div class="feature-card">
894
- <i class="ph ph-lock-key"></i>
895
- <h3>امنیت بالا</h3>
896
- <p>ورود با شماره تلفن و رمز عبور امن</p>
897
- </div>
898
- <div class="feature-card">
899
- <i class="ph ph-users-three"></i>
900
- <h3>روم‌های خصوصی</h3>
901
- <p>تا ۳ روم خصوصی ایجاد کنید و لینک را به اشتراک بگذارید</p>
902
- </div>
903
- <div class="feature-card">
904
- <i class="ph ph-lightning"></i>
905
- <h3>چت لحظه‌ای</h3>
906
- <p>گفتگوی آنلاین بدون تأخیر با کاربران</p>
907
- </div>
908
- </div>
909
-
910
- <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="built-with">Built with anycoder</a>
911
- </div>
912
- </section>
913
-
914
- <!-- Register Page -->
915
- <section id="page-register" class="page hidden">
916
- <div class="auth-container">
917
- <div class="auth-box card">
918
- <div class="auth-header">
919
- <h2>ثبت نام</h2>
920
- <p>برای استفاده از چت روم ثبت نام کنید</p>
921
- </div>
922
-
923
- <form id="registerForm" onsubmit="auth.register(event)">
924
- <div class="form-group">
925
- <label>شماره تلفن</label>
926
- <input type="tel" class="form-control" id="regPhone" placeholder="مثال: 09123456789" required pattern="09[0-9]{9}">
927
- </div>
928
-
929
- <div class="form-group">
930
- <label>رمز عبور</label>
931
- <input type="password" class="form-control" id="regPassword" placeholder="حداقل ۶ کاراکتر" required minlength="6">
932
- </div>
933
-
934
- <div class="form-group">
935
- <label>نام نمایشی</label>
936
- <input type="text" class="form-control" id="regName" placeholder="نام شما در چت" required>
937
- </div>
938
-
939
- <button type="submit" class="btn btn-primary" style="width: 100%;">
940
- <i class="ph ph-user-plus"></i>
941
- ثبت نام
942
- </button>
943
- </form>
944
-
945
- <div style="text-align: center; margin-top: 1.5rem; color: var(--text-muted);">
946
- قبلاً ثبت نام کرده‌اید؟
947
- <a href="#" onclick="router.navigate('login')" style="color: var(--primary); text-decoration: none;">وارد شوید</a>
948
- </div>
949
- </div>
950
- </div>
951
- </section>
952
-
953
- <!-- Login Page -->
954
- <section id="page-login" class="page hidden">
955
- <div class="auth-container">
956
- <div class="auth-box card">
957
- <div class="auth-header">
958
- <h2>ورود</h2>
959
- <p>وارد حساب کاربری خود شوید</p>
960
- </div>
961
-
962
- <form id="loginForm" onsubmit="auth.login(event)">
963
- <div class="form-group">
964
- <label>شماره تلفن</label>
965
- <input type="tel" class="form-control" id="loginPhone" placeholder="شماره تلفن" required>
966
- </div>
967
-
968
- <div class="form-group">
969
- <label>رمز عبور</label>
970
- <input type="password" class="form-control" id="loginPassword" placeholder="رمز عبور" required>
971
- </div>
972
 
973
- <button type="submit" class="btn btn-primary" style="width: 100%;">
974
- <i class="ph ph-sign-in"></i>
975
- ورود
976
- </button>
977
- </form>
978
-
979
- <div style="text-align: center; margin-top: 1.5rem; color: var(--text-muted);">
980
- حساب ندارید؟
981
- <a href="#" onclick="router.navigate('register')" style="color: var(--primary); text-decoration: none;">ثبت نام کنید</a>
982
- </div>
983
- </div>
984
- </div>
985
- </section>
986
-
987
- <!-- Rooms Page -->
988
- <section id="page-rooms" class="page hidden">
989
- <div style="max-width: 1000px; margin: 0 auto; padding: 2rem 0;">
990
- <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 2rem;">
991
- <div>
992
- <h2>روم‌های من</h2>
993
- <p style="color: var(--text-muted);">تا ۳ روم می‌توانید ایجاد کنید</p>
994
- </div>
995
- <button class="btn btn-primary" onclick="roomManager.showCreateModal()">
996
- <i class="ph ph-plus"></i>
997
- روم جدید
998
- </button>
999
- </div>
1000
-
1001
- <div id="roomsList" class="rooms-grid">
1002
- <!-- Rooms will be loaded here -->
1003
- </div>
1004
-
1005
- <div id="emptyRooms" class="empty-state hidden">
1006
- <i class="ph ph-chat-teardrop-text"></i>
1007
- <h3>هنوز رومی ایجاد نکرده‌اید</h3>
1008
- <p>با ایجاد روم، لینک را با دوستان خود به اشتراک بگذارید</p>
1009
- </div>
1010
- </div>
1011
- </section>
1012
-
1013
- <!-- Chat Page -->
1014
- <section id="page-chat" class="page hidden">
1015
- <div class="chat-container">
1016
- <aside class="sidebar">
1017
- <div class="sidebar-header">
1018
- <h3>کاربران آنلاین</h3>
1019
- </div>
1020
- <div class="users-list" id="onlineUsers">
1021
- <!-- Users will be loaded here -->
1022
- </div>
1023
- </aside>
1024
-
1025
- <div class="chat-area">
1026
- <div class="chat-header">
1027
- <div>
1028
- <h3 id="chatRoomName">نام روم</h3>
1029
- <small style="color: var(--text-muted);" id="chatRoomId">شناسه: -</small>
1030
- </div>
1031
- <div style="display: flex; gap: 0.5rem;">
1032
- <button class="btn btn-secondary btn-small" onclick="chat.copyLink()">
1033
- <i class="ph ph-link"></i>
1034
- کپی لینک
1035
- </button>
1036
- <button class="btn btn-ghost" onclick="router.navigate('rooms')">
1037
- <i class="ph ph-x"></i>
1038
- </button>
1039
- </div>
1040
- </div>
1041
-
1042
- <div class="chat-messages" id="chatMessages">
1043
- <!-- Messages will appear here -->
1044
- </div>
1045
-
1046
- <div class="chat-input-area">
1047
- <input type="text" class="chat-input" id="messageInput" placeholder="پیام خود را بنویسید..." onkeypress="if(event.key==='Enter') chat.sendMessage()">
1048
- <button class="btn btn-primary btn-icon" onclick="chat.sendMessage()">
1049
- <i class="ph ph-paper-plane-right"></i>
1050
- </button>
1051
- </div>
1052
- </div>
1053
- </div>
1054
- </section>
1055
-
1056
- <!-- Settings Page -->
1057
- <section id="page-settings" class="page hidden">
1058
- <div class="settings-grid">
1059
- <div class="settings-nav">
1060
- <div class="settings-nav-item active" onclick="settings.showTab('profile')">
1061
- <i class="ph ph-user"></i>
1062
- پروفایل
1063
- </div>
1064
- <div class="settings-nav-item" onclick="settings.showTab('account')">
1065
- <i class="ph ph-lock"></i>
1066
- حساب کاربری
1067
- </div>
1068
- </div>
1069
-
1070
- <div class="settings-content">
1071
- <div id="tab-profile">
1072
- <h2 style="margin-bottom: 1.5rem;">تنظیمات پروفایل</h2>
1073
-
1074
- <div class="form-group">
1075
- <label>نام نمایشی</label>
1076
- <input type="text" class="form-control" id="settingsName" placeholder="نام شما">
1077
- </div>
1078
-
1079
- <div class="form-group">
1080
- <label>انتخاب آواتار</label>
1081
- <div class="avatar-selector" id="avatarSelector">
1082
- <!-- Avatars will be generated here -->
1083
- </div>
1084
- </div>
1085
-
1086
- <button class="btn btn-primary" onclick="settings.saveProfile()">
1087
- <i class="ph ph-floppy-disk"></i>
1088
- ذخیره تغییرات
1089
- </button>
1090
- </div>
1091
-
1092
- <div id="tab-account" class="hidden">
1093
- <h2 style="margin-bottom: 1.5rem;">حساب کاربری</h2>
1094
-
1095
- <div style="background: rgba(239, 68, 68, 0.1); border: 1px solid var(--error); border-radius: var(--radius); padding: 1.5rem; margin-bottom: 1.5rem;">
1096
- <h4 style="color: var(--error); margin-bottom: 0.5rem;">
1097
- <i class="ph ph-warning"></i>
1098
- هشدار
1099
- </h4>
1100
- <p style="color: var(--text-muted); font-size: 0.9rem;">
1101
- حذف حساب کاربری باعث حذف تمام روم‌ها و پیام‌های شما می‌شود. این عملیات قابل بازگشت نیست.
1102
- </p>
1103
- </div>
1104
-
1105
- <button class="btn btn-danger" onclick="auth.deleteAccount()">
1106
- <i class="ph ph-trash"></i>
1107
- حذف حساب کاربری
1108
- </button>
1109
- </div>
1110
- </div>
1111
- </div>
1112
- </section>
1113
 
1114
- </div>
1115
-
1116
- <!-- Create Room Modal -->
1117
- <div class="modal-overlay" id="createRoomModal">
1118
- <div class="modal">
1119
- <div class="modal-header">
1120
- <h3>ایجاد روم جدید</h3>
1121
- <button class="close-btn" onclick="roomManager.hideCreateModal()">
1122
- <i class="ph ph-x"></i>
1123
- </button>
1124
- </div>
1125
 
1126
- <form onsubmit="roomManager.createRoom(event)">
1127
- <div class="form-group">
1128
- <label>نام روم</label>
1129
- <input type="text" class="form-control" id="newRoomName" placeholder="مثال: گفتگوی دوستانه" required>
1130
- </div>
1131
-
1132
- <div style="display: flex; justify-content: flex-end; gap: 0.5rem; margin-top: 1.5rem;">
1133
- <button type="button" class="btn btn-secondary" onclick="roomManager.hideCreateModal()">انصراف</button>
1134
- <button type="submit" class="btn btn-primary">ایجاد روم</button>
1135
- </div>
1136
- </form>
1137
- </div>
1138
- </div>
1139
 
1140
- <script>
1141
- // Data Management
1142
- const db = {
1143
- getUsers() {
1144
- return JSON.parse(localStorage.getItem('chat_users') || '[]');
1145
- },
1146
- saveUsers(users) {
1147
- localStorage.setItem('chat_users', JSON.stringify(users));
1148
- },
1149
- getRooms() {
1150
- return JSON.parse(localStorage.getItem('chat_rooms') || '[]');
1151
- },
1152
- saveRooms(rooms) {
1153
- localStorage.setItem('chat_rooms', JSON.stringify(rooms));
1154
- },
1155
- getMessages() {
1156
- return JSON.parse(localStorage.getItem('chat_messages') || '{}');
1157
- },
1158
- saveMessages(messages) {
1159
- localStorage.setItem('chat_messages', JSON.stringify(messages));
1160
- },
1161
- getCurrentUser() {
1162
- return JSON.parse(sessionStorage.getItem('current_user') || 'null');
1163
- },
1164
- setCurrentUser(user) {
1165
- sessionStorage.setItem('current_user', JSON.stringify(user));
1166
- }
1167
- };
1168
 
1169
- // Toast Notification
1170
- const toast = {
1171
- show(message, type = 'info') {
1172
- const container = document.getElementById('toastContainer');
1173
- const toast = document.createElement('div');
1174
- toast.className = `toast ${type}`;
1175
-
1176
- const icons = {
1177
- success: 'ph-check-circle',
1178
- error: 'ph-x-circle',
1179
- warning: 'ph-warning',
1180
- info: 'ph-info'
1181
- };
1182
-
1183
- toast.innerHTML = `
1184
- <i class="ph ${icons[type]}"></i>
1185
- <span>${message}</span>
1186
- `;
1187
-
1188
- container.appendChild(toast);
1189
-
1190
- setTimeout(() => {
1191
- toast.style.opacity = '0';
1192
- toast.style.transform = 'translateX(-100%)';
1193
- setTimeout(() => toast.remove(), 300);
1194
- }, 3000);
1195
- }
1196
- };
1197
 
1198
- // Router
1199
- const router = {
1200
- currentPage: '',
1201
-
1202
- navigate(page, params = {}) {
1203
- // Check auth for protected pages
1204
- const protectedPages = ['rooms', 'chat', 'settings'];
1205
- const publicPages = ['home', 'login', 'register'];
1206
-
1207
- if (protectedPages.includes(page) && !db.getCurrentUser()) {
1208
- toast.show('لطفاً ابتدا وارد شوید', 'warning');
1209
- page = 'login';
1210
- }
1211
-
1212
- if (publicPages.includes(page) && db.getCurrentUser() && (page === 'login' || page === 'register')) {
1213
- page = 'rooms';
1214
- }
1215
 
1216
- // Hide all pages
1217
- document.querySelectorAll('.page').forEach(p => p.classList.add('hidden'));
1218
-
1219
- // Show target page
1220
- const targetPage = document.getElementById(`page-${page}`);
1221
- if (targetPage) {
1222
- targetPage.classList.remove('hidden');
1223
- this.currentPage = page;
1224
-
1225
- // Update UI based on page
1226
- if (page === 'rooms') roomManager.loadRooms();
1227
- if (page === 'settings') settings.load();
1228
- if (page === 'chat' && params.roomId) chat.loadRoom(params.roomId);
1229
-
1230
- // Show/hide header
1231
- const header = document.getElementById('mainHeader');
1232
- if (page === 'home' || page === 'login' || page === 'register') {
1233
- header.classList.add('hidden');
1234
- } else {
1235
- header.classList.remove('hidden');
1236
- this.updateHeader();
1237
- }
1238
- }
1239
-
1240
- window.location.hash = page;
1241
- },
1242
-
1243
- updateHeader() {
1244
- const user = db.getCurrentUser();
1245
- if (user) {
1246
- document.getElementById('userNameDisplay').textContent = user.name;
1247
- document.getElementById('headerAvatar').textContent = user.avatar;
1248
- }
1249
- },
1250
-
1251
- init() {
1252
- const hash = window.location.hash.slice(1) || 'home';
1253
- const params = {};
1254
-
1255
- if (hash.includes('chat/')) {
1256
- const parts = hash.split('/');
1257
- params.roomId = parts[1];
1258
- this.navigate('chat', params);
1259
- } else {
1260
- this.navigate(hash);
1261
- }
1262
- }
1263
- };
1264
 
1265
- // Auth Manager
1266
- const auth = {
1267
- register(e) {
1268
- e.preventDefault();
1269
-
1270
- const phone = document.getElementById('regPhone').value;
1271
- const password = document.getElementById('regPassword').value;
1272
- const name = document.getElementById('regName').value;
1273
-
1274
- const users = db.getUsers();
1275
-
1276
- if (users.find(u => u.phone === phone)) {
1277
- toast.show('این شماره قبلاً ثبت شده است', 'error');
1278
- return;
1279
- }
1280
-
1281
- const newUser = {
1282
- id: Date.now().toString(),
1283
- phone,
1284
- password,
1285
- name,
1286
- avatar: '👤',
1287
- createdAt: new Date().toISOString()
1288
- };
1289
-
1290
- users.push(newUser);
1291
- db.saveUsers(users);
1292
- db.setCurrentUser(newUser);
1293
-
1294
- toast.show('ثبت نام با موفقیت انجام شد', 'success');
1295
- router.navigate('rooms');
1296
- },
1297
-
1298
- login(e) {
1299
- e.preventDefault();
1300
-
1301
- const phone = document.getElementById('loginPhone').value;
1302
- const password = document.get
 
3
  <head>
4
  <meta charset="UTF-8">
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>پیام رسان سریع | FastChat</title>
7
+
8
+ <!-- Tailwind CSS -->
9
+ <script src="https://cdn.tailwindcss.com"></script>
10
+
11
+ <!-- Font Awesome -->
12
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
13
 
14
  <!-- Google Fonts: Vazirmatn for Persian -->
 
 
15
  <link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@100;300;400;500;700;900&display=swap" rel="stylesheet">
 
 
 
16
 
17
+ <!-- Confetti for effects -->
18
+ <script src="https://cdn.jsdelivr.net/npm/canvas-confetti@1.6.0/dist/confetti.browser.min.js"></script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
19
 
20
+ <script>
21
+ tailwind.config = {
22
+ theme: {
23
+ extend: {
24
+ fontFamily: {
25
+ sans: ['Vazirmatn', 'sans-serif'],
26
+ },
27
+ colors: {
28
+ brand: {
29
+ 50: '#f0f9ff',
30
+ 100: '#e0f2fe',
31
+ 500: '#0ea5e9',
32
+ 600: '#0284c7',
33
+ 900: '#0c4a6e',
34
+ },
35
+ dark: {
36
+ 800: '#1e293b',
37
+ 900: '#0f172a',
38
+ }
39
+ },
40
+ animation: {
41
+ 'fade-in': 'fadeIn 0.5s ease-out',
42
+ 'slide-up': 'slideUp 0.5s ease-out',
43
+ 'pulse-slow': 'pulse 3s cubic-bezier(0.4, 0, 0.6, 1) infinite',
44
+ },
45
+ keyframes: {
46
+ fadeIn: {
47
+ '0%': { opacity: '0' },
48
+ '100%': { opacity: '1' },
49
+ },
50
+ slideUp: {
51
+ '0%': { transform: 'translateY(20px)', opacity: '0' },
52
+ '100%': { transform: 'translateY(0)', opacity: '1' },
53
+ }
54
+ }
55
+ }
56
+ }
57
  }
58
+ </script>
59
 
60
+ <style>
61
+ /* Custom Scrollbar */
62
  ::-webkit-scrollbar {
63
  width: 8px;
64
  }
65
  ::-webkit-scrollbar-track {
66
+ background: #f1f1f1;
67
  }
68
  ::-webkit-scrollbar-thumb {
69
+ background: #cbd5e1;
70
  border-radius: 4px;
71
  }
72
  ::-webkit-scrollbar-thumb:hover {
73
+ background: #94a3b8;
 
 
 
 
 
 
 
 
74
  }
75
 
76
+ /* Glassmorphism Utilities */
77
+ .glass {
78
+ background: rgba(255, 255, 255, 0.7);
79
+ backdrop-filter: blur(10px);
80
+ -webkit-backdrop-filter: blur(10px);
81
+ border: 1px solid rgba(255, 255, 255, 0.3);
82
  }
83
+ .glass-dark {
84
+ background: rgba(15, 23, 42, 0.8);
 
 
 
 
 
 
85
  backdrop-filter: blur(12px);
86
+ -webkit-backdrop-filter: blur(12px);
87
+ border: 1px solid rgba(255, 255, 255, 0.05);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  }
89
 
90
+ /* Message Bubble Animation */
91
+ .message-enter {
92
+ animation: popIn 0.3s cubic-bezier(0.175, 0.885, 0.32, 1.275) forwards;
 
93
  }
94
+ @keyframes popIn {
95
+ from { opacity: 0; transform: scale(0.8) translateY(10px); }
96
+ to { opacity: 1; transform: scale(1) translateY(0); }
 
 
 
 
 
 
 
 
 
 
 
97
  }
98
+
99
+ /* Loader */
100
+ .loader {
101
+ border: 3px solid #f3f3f3;
 
 
 
 
 
 
102
  border-radius: 50%;
103
+ border-top: 3px solid #3498db;
104
+ width: 20px;
105
+ height: 20px;
106
+ -webkit-animation: spin 1s linear infinite; /* Safari */
107
+ animation: spin 1s linear infinite;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
108
  }
109
+ @keyframes spin {
110
+ 0% { transform: rotate(0deg); }
111
+ 100% { transform: rotate(360deg); }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
112
  }
113
+ </style>
114
+ </head>
115
+ <body class="bg-slate-100 text-slate-800 font-sans h-screen overflow-hidden selection:bg-brand-200 selection:text-brand-900">
116
 
117
+ <!-- Toast Notification Container -->
118
+ <div id="toast-container" class="fixed top-5 left-1/2 transform -translate-x-1/2 z-50 flex flex-col gap-2 w-full max-w-sm px-4 pointer-events-none"></div>
 
 
 
119
 
120
+ <!-- ================= AUTHENTICATION VIEW ================= -->
121
+ <div id="auth-view" class="h-full w-full flex items-center justify-center relative overflow-hidden">
122
+ <!-- Decorative Background Blobs -->
123
+ <div class="absolute top-0 left-0 w-96 h-96 bg-brand-300 rounded-full mix-blend-multiply filter blur-3xl opacity-30 animate-pulse-slow"></div>
124
+ <div class="absolute bottom-0 right-0 w-96 h-96 bg-purple-300 rounded-full mix-blend-multiply filter blur-3xl opacity-30 animate-pulse-slow" style="animation-delay: 1s;"></div>
 
 
 
125
 
126
+ <div class="glass p-8 rounded-2xl shadow-2xl w-full max-w-md z-10 animate-slide-up mx-4">
127
+ <div class="text-center mb-8">
128
+ <div class="w-16 h-16 bg-brand-600 rounded-2xl mx-auto flex items-center justify-center text-white text-2xl shadow-lg mb-4 rotate-3 hover:rotate-6 transition-transform duration-300">
129
+ <i class="fa-solid fa-comments"></i>
130
+ </div>
131
+ <h1 class="text-3xl font-bold text-slate-800">پیام رسان سریع</h1>
132
+ <p class="text-slate-500 mt-2 text-sm">بدون نیاز به سرور، فقط با مرورگر</p>
133
+ </div>
134
 
135
+ <!-- Tabs -->
136
+ <div class="flex bg-slate-100 p-1 rounded-xl mb-6">
137
+ <button onclick="switchAuthTab('login')" id="tab-login" class="flex-1 py-2 rounded-lg text-sm font-medium transition-all duration-300 bg-white text-brand-600 shadow-sm">ورود</button>
138
+ <button onclick="switchAuthTab('register')" id="tab-register" class="flex-1 py-2 rounded-lg text-sm font-medium text-slate-500 hover:text-slate-700 transition-all duration-300">ثبت نام</button>
139
+ </div>
140
 
141
+ <!-- Login Form -->
142
+ <form id="login-form" class="space-y-4" onsubmit="handleLogin(event)">
143
+ <div>
144
+ <label class="block text-xs font-bold text-slate-500 mb-1">شماره موبایل</label>
145
+ <div class="relative">
146
+ <i class="fa-solid fa-phone absolute right-3 top-3 text-slate-400"></i>
147
+ <input type="tel" id="login-phone" placeholder="09XXXXXXXXX" class="w-full bg-slate-50 border border-slate-200 rounded-xl py-2.5 pr-10 pl-4 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition-all" required>
148
+ </div>
149
+ </div>
150
+ <div>
151
+ <label class="block text-xs font-bold text-slate-500 mb-1">رمز عبور</label>
152
+ <div class="relative">
153
+ <i class="fa-solid fa-lock absolute right-3 top-3 text-slate-400"></i>
154
+ <input type="password" id="login-password" placeholder="••••••••" class="w-full bg-slate-50 border border-slate-200 rounded-xl py-2.5 pr-10 pl-4 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition-all" required>
155
+ </div>
156
+ </div>
157
+ <button type="submit" class="w-full bg-brand-600 hover:bg-brand-700 text-white font-bold py-3 rounded-xl shadow-lg shadow-brand-500/30 transition-all transform hover:scale-[1.02] active:scale-95">
158
+ ورود به حساب
159
+ </button>
160
+ </form>
161
 
162
+ <!-- Register Form (Hidden by default) -->
163
+ <form id="register-form" class="space-y-4 hidden" onsubmit="handleRegister(event)">
164
+ <div>
165
+ <label class="block text-xs font-bold text-slate-500 mb-1">نام کامل</label>
166
+ <div class="relative">
167
+ <i class="fa-solid fa-user absolute right-3 top-3 text-slate-400"></i>
168
+ <input type="text" id="reg-name" placeholder="مثلا: علی احمدی" class="w-full bg-slate-50 border border-slate-200 rounded-xl py-2.5 pr-10 pl-4 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition-all" required>
169
+ </div>
170
+ </div>
171
+ <div>
172
+ <label class="block text-xs font-bold text-slate-500 mb-1">شماره موبایل</label>
173
+ <div class="relative">
174
+ <i class="fa-solid fa-phone absolute right-3 top-3 text-slate-400"></i>
175
+ <input type="tel" id="reg-phone" placeholder="09XXXXXXXXX" class="w-full bg-slate-50 border border-slate-200 rounded-xl py-2.5 pr-10 pl-4 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition-all" required>
176
+ </div>
177
+ </div>
178
+ <div>
179
+ <label class="block text-xs font-bold text-slate-500 mb-1">رمز عبور</label>
180
+ <div class="relative">
181
+ <i class="fa-solid fa-lock absolute right-3 top-3 text-slate-400"></i>
182
+ <input type="password" id="reg-password" placeholder="حداقل 4 کاراکتر" class="w-full bg-slate-50 border border-slate-200 rounded-xl py-2.5 pr-10 pl-4 focus:outline-none focus:ring-2 focus:ring-brand-500 focus:border-transparent transition-all" required>
183
+ </div>
184
+ </div>
185
+ <button type="submit" class="w-full bg-slate-800 hover:bg-slate-900 text-white font-bold py-3 rounded-xl shadow-lg shadow-slate-800/30 transition-all transform hover:scale-[1.02] active:scale-95">
186
+ ایجاد حساب کاربری
187
+ </button>
188
+ </form>
189
+
190
+ <div class="mt-6 text-center">
191
+ <p class="text-xs text-slate-400">
192
+ Built with <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="text-brand-600 hover:underline">anycoder</a>
193
+ </p>
194
+ </div>
195
+ </div>
196
+ </div>
197
 
198
+ <!-- ================= DASHBOARD VIEW ================= -->
199
+ <div id="dashboard-view" class="hidden h-full w-full flex flex-col md:flex-row bg-slate-50">
200
+
201
+ <!-- Sidebar -->
202
+ <aside class="w-full md:w-80 bg-white border-l border-slate-200 flex flex-col z-20 shadow-xl md:shadow-none">
203
+ <!-- User Profile Header -->
204
+ <div class="p-6 border-b border-slate-100 bg-gradient-to-br from-slate-50 to-white">
205
+ <div class="flex items-center gap-4">
206
+ <div class="relative">
207
+ <div class="w-14 h-14 rounded-full bg-gradient-to-tr from-brand-400 to-purple-500 flex items-center justify-center text-white text-xl font-bold shadow-md">
208
+ <span id="user-avatar-initial">U</span>
209
+ </div>
210
+ <div class="absolute bottom-0 right-0 w-4 h-4 bg-green-500 border-2 border-white rounded-full"></div>
211
+ </div>
212
+ <div>
213
+ <h2 id="user-name-display" class="font-bold text-slate-800 text-lg">کاربر</h2>
214
+ <p id="user-phone-display" class="text-xs text-slate-500 font-mono">09--------</p>
215
+ </div>
216
+ <button onclick="logout()" class="mr-auto text-slate-400 hover:text-red-500 transition-colors" title="خروج">
217
+ <i class="fa-solid fa-power-off text-lg"></i>
218
+ </button>
219
+ </div>
220
+ </div>
221
 
222
+ <!-- Create Room Section -->
223
+ <div class="p-6 border-b border-slate-100">
224
+ <div class="flex justify-between items-center mb-3">
225
+ <h3 class="font-bold text-slate-700">اتاق های من</h3>
226
+ <span id="room-count-badge" class="bg-slate-100 text-slate-600 text-xs font-bold px-2 py-1 rounded-md">0/3</span>
227
+ </div>
228
+ <button onclick="openCreateRoomModal()" id="btn-create-room" class="w-full py-2.5 border-2 border-dashed border-brand-200 text-brand-600 rounded-xl hover:bg-brand-50 hover:border-brand-400 transition-all flex items-center justify-center gap-2 font-medium text-sm">
229
+ <i class="fa-solid fa-plus"></i> ساخت اتاق جدید
230
+ </button>
231
+ <p id="room-limit-msg" class="text-xs text-red-500 mt-2 hidden text-center">شما به حداکثر تعداد اتاق رسیدید.</p>
232
+ </div>
233
 
234
+ <!-- Room List -->
235
+ <div class="flex-1 overflow-y-auto p-3 space-y-2" id="room-list-container">
236
+ <!-- Rooms injected via JS -->
237
+ <div class="text-center mt-10 text-slate-400 text-sm">
238
+ <i class="fa-regular fa-folder-open text-3xl mb-2 block"></i>
239
+ هنوز اتاقی نساختید
240
+ </div>
241
+ </div>
242
+ </aside>
243
+
244
+ <!-- Main Content Area -->
245
+ <main class="flex-1 flex flex-col h-full relative bg-slate-50/50">
246
+ <!-- Top Bar -->
247
+ <header class="h-16 bg-white border-b border-slate-200 flex items-center justify-between px-6 shadow-sm z-10">
248
+ <div class="flex items-center gap-3">
249
+ <div class="md:hidden text-slate-500">
250
+ <i class="fa-solid fa-bars text-xl"></i>
251
+ </div>
252
+ <h1 class="font-bold text-xl text-slate-800 hidden md:block">داشبورد</h1>
253
+ </div>
254
+ <div class="flex items-center gap-4">
255
+ <a href="https://huggingface.co/spaces/akhaliq/anycoder" target="_blank" class="text-xs bg-slate-100 hover:bg-slate-200 text-slate-600 px-3 py-1.5 rounded-full transition-colors">
256
+ Built with anycoder
257
+ </a>
258
+ </div>
259
+ </header>
260
 
261
+ <!-- Dashboard Content / Welcome -->
262
+ <div id="welcome-screen" class="flex-1 flex flex-col items-center justify-center p-8 text-center">
263
+ <div class="w-32 h-32 bg-slate-100 rounded-full flex items-center justify-center mb-6 relative">
264
+ <i class="fa-solid fa-rocket text-4xl text-slate-300"></i>
265
+ <div class="absolute inset-0 border-2 border-slate-200 border-dashed rounded-full animate-spin-slow" style="animation-duration: 10s;"></div>
266
+ </div>
267
+ <h2 class="text-2xl font-bold text-slate-800 mb-2">به پیام رسان خوش آمدید</h2>
268
+ <p class="text-slate-500 max-w-md mb-8">یک اتاق جدید بسازید یا از لیست سمت راست یکی را انتخاب کنید تا گفتگو را شروع کنید.</p>
269
+
270
+ <div class="grid grid-cols-1 md:grid-cols-3 gap-4 w-full max-w-2xl text-right">
271
+ <div class="bg-white p-4 rounded-xl shadow-sm border border-slate-100">
272
+ <div class="w-10 h-10 rounded-lg bg-blue-100 text-blue-600 flex items-center justify-center mb-3">
273
+ <i class="fa-solid fa-bolt"></i>
274
+ </div>
275
+ <h4 class="font-bold text-slate-700 mb-1">سریع و آنی</h4>
276
+ <p class="text-xs text-slate-500">بدون نیاز به سرور، داده ها در م��ورگر شما ذخیره می شوند.</p>
277
+ </div>
278
+ <div class="bg-white p-4 rounded-xl shadow-sm border border-slate-100">
279
+ <div class="w-10 h-10 rounded-lg bg-purple-100 text-purple-600 flex items-center justify-center mb-3">
280
+ <i class="fa-solid fa-link"></i>
281
+ </div>
282
+ <h4 class="font-bold text-slate-700 mb-1">اشتراک گذاری</h4>
283
+ <p class="text-xs text-slate-500">لینک اتاق را کپی کنید و برای دوستانتان بفرستید.</p>
284
+ </div>
285
+ <div class="bg-white p-4 rounded-xl shadow-sm border border-slate-100">
286
+ <div class="w-10 h-10 rounded-lg bg-green-100 text-green-600 flex items-center justify-center mb-3">
287
+ <i class="fa-solid fa-shield-halved"></i>
288
+ </div>
289
+ <h4 class="font-bold text-slate-700 mb-1">امنیت محلی</h4>
290
+ <p class="text-xs text-slate-500">هیچ داده ای به سرور ارسال نمی شود. کاملا خصوصی.</p>
291
+ </div>
292
+ </div>
293
+ </div>
294
 
295
+ <!-- Chat Interface (Hidden initially) -->
296
+ <div id="chat-interface" class="hidden flex-col h-full absolute inset-0 bg-white z-20 animate-fade-in">
297
+ <!-- Chat Header -->
298
+ <div class="h-16 border-b border-slate-100 flex items-center justify-between px-4 bg-white">
299
+ <div class="flex items-center gap-3">
300
+ <button onclick="closeChat()" class="md:hidden w-8 h-8 flex items-center justify-center rounded-full hover:bg-slate-100 text-slate-600">
301
+ <i class="fa-solid fa-arrow-right"></i>
302
+ </button>
303
+ <div class="w-10 h-10 rounded-full bg-gradient-to-br from-indigo-400 to-brand-500 flex items-center justify-center text-white font-bold shadow-sm">
304
+ <i class="fa-solid fa-hashtag"></i>
305
+ </div>
306
+ <div>
307
+ <h3 id="chat-room-name" class="font-bold text-slate-800">نام اتاق</h3>
308
+ <div class="flex items-center gap-2 text-xs text-slate-500">
309
+ <span class="w-2 h-2 bg-green-500 rounded-full"></span>
310
+ <span id="chat-user-count">2 عضو آنلاین</span>
311
+ </div>
312
+ </div>
313
+ </div>
314
+ <div class="flex items-center gap-2">
315
+ <button onclick="copyRoomLink()" class="p-2 text-slate-400 hover:text-brand-600 hover:bg-brand-50 rounded-lg transition-colors tooltip-btn" title="کپی لینک">
316
+ <i class="fa-solid fa-share-nodes"></i>
317
+ </button>
318
+ <button onclick="closeChat()" class="hidden md:block p-2 text-slate-400 hover:text-red-500 hover:bg-red-50 rounded-lg transition-colors" title="بستن">
319
+ <i class="fa-solid fa-xmark"></i>
320
+ </button>
321
+ </div>
322
+ </div>
323
 
324
+ <!-- Messages Area -->
325
+ <div id="messages-container" class="flex-1 overflow-y-auto p-4 space-y-4 bg-slate-50">
326
+ <!-- Messages injected via JS -->
327
+ </div>
 
 
328
 
329
+ <!-- Input Area -->
330
+ <div class="p-4 bg-white border-t border-slate-100">
331
+ <form onsubmit="sendMessage(event)" class="flex gap-2">
332
+ <input type="text" id="message-input" placeholder="پیام خود را بنویسید..." class="flex-1 bg-slate-100 border-0 rounded-xl px-4 py-3 focus:ring-2 focus:ring-brand-500 focus:bg-white transition-all" autocomplete="off">
333
+ <button type="submit" class="bg-brand-600 hover:bg-brand-700 text-white w-12 h-12 rounded-xl flex items-center justify-center shadow-lg shadow-brand-500/30 transition-transform active:scale-95">
334
+ <i class="fa-solid fa-paper-plane"></i>
335
+ </button>
336
+ </form>
337
+ </div>
338
+ </div>
339
+ </main>
340
+ </div>
341
 
342
+ <!-- Create Room Modal -->
343
+ <div id="create-room-modal" class="fixed inset-0 z-50 hidden">
344
+ <div class="absolute inset-0 bg-slate-900/40 backdrop-blur-sm transition-opacity" onclick="closeCreateRoomModal()"></div>
345
+ <div class="absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2 w-full max-w-md p-4">
346
+ <div class="bg-white rounded-2xl shadow-2xl p-6 animate-slide-up">
347
+ <div class="flex justify-between items-center mb-6">
348
+ <h3 class="text-xl font-bold text-slate-800">ساخت اتاق جدید</h3>
349
+ <button onclick="closeCreateRoomModal()" class="text-slate-400 hover:text-slate-600">
350
+ <i class="fa-solid fa-xmark text-xl"></i>
351
+ </button>
352
+ </div>
353
+ <form onsubmit="handleCreateRoom(event)">
354
+ <div class="mb-4">
355
+ <label class="block text-sm font-bold text-slate-700 mb-2">نام اتاق</label>
356
+ <input type="text" id="new-room-name" class="w-full border border-slate-200 rounded-xl px-4 py-3 focus:outline-none focus:ring-2 focus:ring-brand-500" placeholder="مثلا: گروه دوستان" required>
357
+ </div>
358
+ <div class="flex gap-3">
359
+ <button type="button" onclick="closeCreateRoomModal()" class="flex-1 py-3 rounded-xl border border-slate-200 text-slate-600 font-bold hover:bg-slate-50">انصراف</button>
360
+ <button type="submit" class="flex-1 py-3 rounded-xl bg-brand-600 text-white font-bold hover:bg-brand-700 shadow-lg shadow-brand-500/30">ساختن</button>
361
+ </div>
362
+ </form>
363
+ </div>
364
+ </div>
365
+ </div>
366
 
367
+ <script>
368
+ // --- DATA & STATE MANAGEMENT ---
369
+
370
+ // Simulating a database using LocalStorage
371
+ const DB_KEYS = {
372
+ USERS: 'chat_app_users',
373
+ ROOMS: 'chat_app_rooms',
374
+ MESSAGES: 'chat_app_messages',
375
+ SESSION: 'chat_app_session'
376
+ };
377
 
378
+ let currentUser = null;
379
+ let currentRoomId = null;
 
 
380
 
381
+ // --- INITIALIZATION ---
 
 
 
 
 
 
 
382
 
383
+ document.addEventListener('DOMContentLoaded', () => {
384
+ checkSession();
385
+
386
+ // Check URL for room invite
387
+ const urlParams = new URLSearchParams(window.location.search);
388
+ const inviteRoomId = urlParams.get('room');
389
+ if (inviteRoomId) {
390
+ // If user is logged in, try to join. If not, store intent.
391
+ // For this simple version, we just show a toast if they are logged in.
392
+ if(currentUser) {
393
+ joinRoomById(inviteRoomId);
394
+ } else {
395
+ showToast('لطفا ابتدا وارد شوید تا بتوانید به اتاق دعوت شده بپیوندید.', 'info');
396
+ }
397
+ }
398
+ });
399
+
400
+ function checkSession() {
401
+ const session = localStorage.getItem(DB_KEYS.SESSION);
402
+ if (session) {
403
+ currentUser = JSON.parse(session);
404
+ showDashboard();
405
+ } else {
406
+ showAuth();
407
+ }
408
  }
409
 
410
+ // --- AUTHENTICATION LOGIC ---
411
+
412
+ function switchAuthTab(tab) {
413
+ const loginForm = document.getElementById('login-form');
414
+ const registerForm = document.getElementById('register-form');
415
+ const loginTab = document.getElementById('tab-login');
416
+ const registerTab = document.getElementById('tab-register');
417
+
418
+ if (tab === 'login') {
419
+ loginForm.classList.remove('hidden');
420
+ registerForm.classList.add('hidden');
421
+ loginTab.classList.add('bg-white', 'text-brand-600', 'shadow-sm');
422
+ loginTab.classList.remove('text-slate-500');
423
+ registerTab.classList.remove('bg-white', 'text-brand-600', 'shadow-sm');
424
+ registerTab.classList.add('text-slate-500');
425
+ } else {
426
+ loginForm.classList.add('hidden');
427
+ registerForm.classList.remove('hidden');
428
+ registerTab.classList.add('bg-white', 'text-brand-600', 'shadow-sm');
429
+ registerTab.classList.remove('text-slate-500');
430
+ loginTab.classList.remove('bg-white', 'text-brand-600', 'shadow-sm');
431
+ loginTab.classList.add('text-slate-500');
432
+ }
433
  }
434
 
435
+ function handleRegister(e) {
436
+ e.preventDefault();
437
+ const name = document.getElementById('reg-name').value;
438
+ const phone = document.getElementById('reg-phone').value;
439
+ const password = document.getElementById('reg-password').value;
440
 
441
+ let users = JSON.parse(localStorage.getItem(DB_KEYS.USERS) || '[]');
 
 
 
 
 
 
 
 
442
 
443
+ if (users.find(u => u.phone === phone)) {
444
+ showToast('این شماره قبلا ثبت نام شده است.', 'error');
445
+ return;
446
+ }
447
 
448
+ const newUser = {
449
+ id: Date.now().toString(),
450
+ name,
451
+ phone,
452
+ password, // In a real app, hash this!
453
+ createdAt: new Date().toISOString()
454
+ };
 
 
 
455
 
456
+ users.push(newUser);
457
+ localStorage.setItem(DB_KEYS.USERS, JSON.stringify(users));
458
+
459
+ // Auto login
460
+ currentUser = { id: newUser.id, name: newUser.name, phone: newUser.phone };
461
+ localStorage.setItem(DB_KEYS.SESSION, JSON.stringify(currentUser));
462
+
463
+ confetti({
464
+ particleCount: 100,
465
+ spread: 70,
466
+ origin: { y: 0.6 }
467
+ });
468
+
469
+ showToast('ثبت نام با موفقیت انجام شد!', 'success');
470
+ showDashboard();
471
+ }
472
+
473
+ function handleLogin(e) {
474
+ e.preventDefault();
475
+ const phone = document.getElementById('login-phone').value;
476
+ const password = document.getElementById('login-password').value;
477
+
478
+ const users = JSON.parse(localStorage.getItem(DB_KEYS.USERS) || '[]');
479
+ const user = users.find(u => u.phone === phone && u.password === password);
480
+
481
+ if (user) {
482
+ currentUser = { id: user.id, name: user.name, phone: user.phone };
483
+ localStorage.setItem(DB_KEYS.SESSION, JSON.stringify(currentUser));
484
+ showToast(`خوش آمدید ${user.name}`, 'success');
485
+ showDashboard();
486
+ } else {
487
+ showToast('شماره یا رمز عبور اشتباه است.', 'error');
488
+ }
489
  }
490
 
491
+ function logout() {
492
+ localStorage.removeItem(DB_KEYS.SESSION);
493
+ currentUser = null;
494
+ showAuth();
495
+ showToast('از حساب کاربری خارج شدید.', 'info');
496
  }
497
 
498
+ // --- VIEW MANAGEMENT ---
 
 
 
 
 
 
499
 
500
+ function showAuth() {
501
+ document.getElementById('auth-view').classList.remove('hidden');
502
+ document.getElementById('dashboard-view').classList.add('hidden');
 
 
 
 
 
503
  }
504
 
505
+ function showDashboard() {
506
+ document.getElementById('auth-view').classList.add('hidden');
507
+ document.getElementById('dashboard-view').classList.remove('hidden');
508
+
509
+ // Update Profile Info
510
+ document.getElementById('user-name-display').innerText = currentUser.name;
511
+ document.getElementById('user-phone-display').innerText = currentUser.phone;
512
+ document.getElementById('user-avatar-initial').innerText = currentUser.name.charAt(0);
513
 
514
+ renderRoomList();
 
 
 
 
 
 
515
  }
516
 
517
+ // --- ROOM MANAGEMENT ---
 
 
 
 
 
 
518
 
519
+ function renderRoomList() {
520
+ const allRooms = JSON.parse(localStorage.getItem(DB_KEYS.ROOMS) || '[]');
521
+ // Filter rooms created by current user OR rooms where user is a member
522
+ // For this demo, we show rooms user created + rooms they joined via link (simplified logic)
523
+ const myRooms = allRooms.filter(r => r.creatorId === currentUser.id || (r.members && r.members.includes(currentUser.id)));
524
+
525
+ const container = document.getElementById('room-list-container');
526
+ const countBadge = document.getElementById('room-count-badge');
527
+ const createBtn = document.getElementById('btn-create-room');
528
+ const limitMsg = document.getElementById('room-limit-msg');
529
+
530
+ // Update Badge
531
+ const createdCount = allRooms.filter(r => r.creatorId === currentUser.id).length;
532
+ countBadge.innerText = `${createdCount}/3`;
533
+
534
+ // Handle Limit
535
+ if (createdCount >= 3) {
536
+ createBtn.disabled = true;
537
+ createBtn.classList.add('opacity-50', 'cursor-not-allowed');
538
+ limitMsg.classList.remove('hidden');
539
+ } else {
540
+ createBtn.disabled = false;
541
+ createBtn.classList.remove('opacity-50', 'cursor-not-allowed');
542
+ limitMsg.classList.add('hidden');
543
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
544
 
545
+ // Render List
546
+ if (myRooms.length === 0) {
547
+ container.innerHTML = `
548
+ <div class="text-center mt-10 text-slate-400 text-sm flex flex-col items-center">
549
+ <div class="w-16 h-16 bg-slate-100 rounded-full flex items-center justify-center mb-3">
550
+ <i class="fa-regular fa-folder-open text-2xl"></i>
551
+ </div>
552
+ <p>هنوز اتاقی نساختید</p>
553
+ </div>`;
554
+ return;
555
+ }
 
 
 
 
 
 
556
 
557
+ container.innerHTML = myRooms.map(room => `
558
+ <div onclick="openRoom('${room.id}')" class="group p-3 rounded-xl hover:bg-slate-50 cursor-pointer border border-transparent hover:border-slate-200 transition-all flex items-center justify-between">
559
+ <div class="flex items-center gap-3">
560
+ <div class="w-10 h-10 rounded-lg bg-gradient-to-br from-slate-200 to-slate-300 text-slate-600 flex items-center justify-center font-bold group-hover:from-brand-100 group-hover:to-brand-200 group-hover:text-brand-600 transition-colors">
561
+ ${room.name.charAt(0)}
562
+ </div>
563
+ <div>
564
+ <h4 class="font-bold text-slate-700 text-sm">${room.name}</h4>
565
+ <p class="text-xs text-slate-400">ایجاد شده در ${new Date(room.createdAt).toLocaleDateString('fa-IR')}</p>
566
+ </div>
567
+ </div>
568
+ <i class="fa-solid fa-chevron-left text-slate-300 text-xs group-hover:text-brand-500"></i>
569
+ </div>
570
+ `).join('');
571
  }
572
 
573
+ function openCreateRoomModal() {
574
+ document.getElementById('create-room-modal').classList.remove('hidden');
 
575
  }
576
 
577
+ function closeCreateRoomModal() {
578
+ document.getElementById('create-room-modal').classList.add('hidden');
 
 
 
 
 
 
579
  }
580
 
581
+ function handleCreateRoom(e) {
582
+ e.preventDefault();
583
+ const name = document.getElementById('new-room-name').value;
584
+
585
+ const rooms = JSON.parse(localStorage.getItem(DB_KEYS.ROOMS) || '[]');
586
+ const myRoomCount = rooms.filter(r => r.creatorId === currentUser.id).length;
 
 
587
 
588
+ if (myRoomCount >= 3) {
589
+ showToast('شما نمی توانید بیش از 3 اتاق بسازید.', 'error');
590
+ return;
591
+ }
 
592
 
593
+ const newRoom = {
594
+ id: 'room_' + Date.now(),
595
+ name: name,
596
+ creatorId: currentUser.id,
597
+ members: [currentUser.id], // Creator is first member
598
+ createdAt: new Date().toISOString()
599
+ };
600
+
601
+ rooms.push(newRoom);
602
+ localStorage.setItem(DB_KEYS.ROOMS, JSON.stringify(rooms));
603
+
604
+ closeCreateRoomModal();
605
+ document.getElementById('new-room-name').value = '';
606
+ renderRoomList();
607
+ showToast('اتاق با موفقیت ساخته شد!', 'success');
608
+
609
+ // Auto open
610
+ openRoom(newRoom.id);
611
  }
612
 
613
+ function joinRoomById(roomId) {
614
+ const rooms = JSON.parse(localStorage.getItem(DB_KEYS.ROOMS) || '[]');
615
+ const roomIndex = rooms.findIndex(r => r.id === roomId);
 
 
616
 
617
+ if (roomIndex === -1) {
618
+ showToast('اتاق مورد نظر یافت نشد.', 'error');
619
+ return;
620
+ }
621
 
622
+ // Add user to members if not already
623
+ if (!rooms[roomIndex].members) rooms[roomIndex].members = [];
624
+ if (!rooms[roomIndex].members.includes(currentUser.id)) {
625
+ rooms[roomIndex].members.push(currentUser.id);
626
+ localStorage.setItem(DB_KEYS.ROOMS, JSON.stringify(rooms));
627
+ showToast('شما به اتاق پیوستید!', 'success');
628
+ renderRoomList();
629
+ }
630
+
631
+ openRoom(roomId);
632
  }
633
 
634
+ // --- CHAT LOGIC ---
 
 
 
 
 
635
 
636
+ function openRoom(roomId) {
637
+ currentRoomId = roomId;
638
+ const rooms = JSON.parse(localStorage.getItem(DB_KEYS.ROOMS) || '[]');
639
+ const room = rooms.find(r => r.id === roomId);
 
 
 
 
 
 
 
 
640
 
641
+ if (!room) return;
 
 
 
642
 
643
+ // UI Updates
644
+ document.getElementById('welcome-screen').classList.add('hidden');
645
+ document.getElementById('chat-interface').classList.remove('hidden');
646
+ document.getElementById('chat-interface').classList.add('flex');
647
+
648
+ document.getElementById('chat-room-name').innerText = room.name;
649
+ document.getElementById('chat-user-count').innerText = `${room.members ? room.members.length : 1} عضو`;
650
 
651
+ loadMessages();
652
+
653
+ // Focus input
654
+ setTimeout(() => document.getElementById('message-input').focus(), 100);
 
 
 
 
 
655
  }
656
 
657
+ function closeChat() {
658
+ document.getElementById('chat-interface').classList.add('hidden');
659
+ document.getElementById('chat-interface').classList.remove('flex');
660
+ document.getElementById('welcome-screen').classList.remove('hidden');
661
+ currentRoomId = null;
 
 
 
 
 
 
 
662
  }
663
 
664
+ function loadMessages() {
665
+ const allMessages = JSON.parse(localStorage.getItem(DB_KEYS.MESSAGES) || '[]');
666
+ const roomMessages = allMessages.filter(m => m.roomId === currentRoomId);
667
+
668
+ const container = document.getElementById('messages-container');
669
+ container.innerHTML = '';
670
+
671
+ if (roomMessages.length === 0) {
672
+ container.innerHTML = `
673
+ <div class="text-center text-slate-400 mt-10">
674
+ <p>هنوز پیامی در این اتاق نیست.</p>
675
+ <p class="text-sm">اولین نفری باشید که پیام می دهد!</p>
676
+ </div>`;
677
+ } else {
678
+ roomMessages.forEach(msg => renderMessageBubble(msg));
679
  }
680
+
681
+ scrollToBottom();
682
  }
683
 
684
+ function renderMessageBubble(msg) {
685
+ const container = document.getElementById('messages-container');
686
+ const isMe = msg.userId === currentUser.id;
 
 
687
 
688
+ const div = document.createElement('div');
689
+ div.className = `flex w-full ${isMe ? 'justify-start' : 'justify-end'} message-enter`;
 
690
 
691
+ const bubbleColor = isMe ? 'bg-brand-600 text-white rounded-tr-none' : 'bg-white text-slate-800 border border-slate-200 rounded-tl-none';
692
+ const align = isMe ? 'items-start' : 'items-end';
 
693
 
694
+ // Get user name
695
+ const users = JSON.parse(localStorage.getItem(DB_KEYS.USERS) || '[]');
696
+ const sender = users.find(u => u.id === msg.userId);
697
+ const senderName = sender ? sender.name : 'Unknown';
698
+
699
+ div.innerHTML = `
700
+ <div class="max-w-[80%] flex flex-col ${align}">
701
+ ${!isMe ? `<span class="text-xs text-slate-500 mb-1 mr-1">${senderName}</span>` : ''}
702
+ <div class="${bubbleColor} px-4 py-2 rounded-2xl shadow-sm text-sm leading-relaxed">
703
+ ${msg.text}
704
+ </div>
705
+ <span class="text-[10px] text-slate-400 mt-1 mx-1">${new Date(msg.timestamp).toLocaleTimeString('fa-IR', {hour: '2-digit', minute:'2-digit'})}</span>
706
+ </div>
707
+ `;
708
 
709
+ container.appendChild(div);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
710
  }
711
 
712
+ function sendMessage(e) {
713
+ e.preventDefault();
714
+ const input = document.getElementById('message-input');
715
+ const text = input.value.trim();
716
+
717
+ if (!text || !currentRoomId) return;
718
+
719
+ const newMessage = {
720
+ id: Date.now().toString(),
721
+ roomId: currentRoomId,
722
+ userId: currentUser.id,
723
+ text: text,
724
+ timestamp: new Date().toISOString()
725
+ };
726
+
727
+ const allMessages = JSON.parse(localStorage.getItem(DB_KEYS.MESSAGES) || '[]');
728
+ allMessages.push(newMessage);
729
+ localStorage.setItem(DB_KEYS.MESSAGES, JSON.stringify(allMessages));
730
+
731
+ // Clear input and refresh
732
+ input.value = '';
733
+
734
+ // Remove "empty" message if exists
735
+ const container = document.getElementById('messages-container');
736
+ if (container.children.length > 0 && container.children[0].classList.contains('text-center')) {
737
+ container.innerHTML = '';
738
+ }
739
+
740
+ renderMessageBubble(newMessage);
741
+ scrollToBottom();
742
  }
743
 
744
+ function scrollToBottom() {
745
+ const container = document.getElementById('messages-container');
746
+ container.scrollTop = container.scrollHeight;
 
 
 
 
 
 
 
 
 
 
 
747
  }
748
 
749
+ function copyRoomLink() {
750
+ if(!currentRoomId) return;
751
+ // Create a shareable link (in a real app, this would be the actual URL)
752
+ // Since we are in a single file, we simulate the link structure
753
+ const dummyLink = `${window.location.origin}${window.location.pathname}?room=${currentRoomId}`;
754
+
755
+ navigator.clipboard.writeText(dummyLink).then(() => {
756
+ showToast('لینک اتاق کپی شد!', 'success');
757
+ }).catch(() => {
758
+ showToast('خطا در کپی لینک', 'error');
759
+ });
760
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
761
 
762
+ // --- UTILS ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
763
 
764
+ function showToast(message, type = 'info') {
765
+ const container = document.getElementById('toast-container');
766
+ const toast = document.createElement('div');
 
 
 
 
 
 
 
 
767
 
768
+ let colors = 'bg-slate-800 text-white';
769
+ let icon = 'fa-info-circle';
770
+
771
+ if (type === 'success') { colors = 'bg-green-600 text-white'; icon = 'fa-check-circle'; }
772
+ if (type === 'error') { colors = 'bg-red-500 text-white'; icon = 'fa-exclamation-circle'; }
 
 
 
 
 
 
 
 
773
 
774
+ toast.className = `${colors} px-4 py-3 rounded-xl shadow-lg flex items-center gap-3 transform transition-all duration-500 translate-y-10 opacity-0 pointer-events-auto`;
775
+ toast.innerHTML = `
776
+ <i class="fa-solid ${icon}"></i>
777
+ <span class="text-sm font-medium">${message}</span>
778
+ `;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
779
 
780
+ container.appendChild(toast);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
 
782
+ // Animate in
783
+ requestAnimationFrame(() => {
784
+ toast.classList.remove('translate-y-10', 'opacity-0');
785
+ });
 
 
 
 
 
 
 
 
 
 
 
 
 
786
 
787
+ // Remove after 3s
788
+ setTimeout(() => {
789
+ toast.classList.add('translate-y-10', 'opacity-0');
790
+ setTimeout(() => toast.remove(), 500);
791
+ }, 3000);
792
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
793
 
794
+ </script>
795
+ </body>
796
+ </html>