AiCoderv2 commited on
Commit
0e7a6a9
·
verified ·
1 Parent(s): 1f60361

Upload folder using huggingface_hub

Browse files
Files changed (3) hide show
  1. assets/css/styles.css +954 -0
  2. assets/js/app.js +619 -0
  3. index.html +425 -19
assets/css/styles.css ADDED
@@ -0,0 +1,954 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Reset and Base Styles */
2
+ * {
3
+ margin: 0;
4
+ padding: 0;
5
+ box-sizing: border-box;
6
+ }
7
+
8
+ :root {
9
+ --primary-color: #6366f1;
10
+ --primary-dark: #4f46e5;
11
+ --secondary-color: #8b5cf6;
12
+ --success-color: #10b981;
13
+ --warning-color: #f59e0b;
14
+ --danger-color: #ef4444;
15
+ --dark-bg: #0f172a;
16
+ --card-bg: #1e293b;
17
+ --border-color: #334155;
18
+ --text-primary: #f1f5f9;
19
+ --text-secondary: #94a3b8;
20
+ --text-muted: #64748b;
21
+ }
22
+
23
+ body {
24
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, sans-serif;
25
+ background: linear-gradient(135deg, #0f172a 0%, #1e293b 100%);
26
+ color: var(--text-primary);
27
+ min-height: 100vh;
28
+ line-height: 1.6;
29
+ }
30
+
31
+ /* Navigation */
32
+ .navbar {
33
+ background: rgba(30, 41, 59, 0.95);
34
+ backdrop-filter: blur(10px);
35
+ border-bottom: 1px solid var(--border-color);
36
+ position: sticky;
37
+ top: 0;
38
+ z-index: 1000;
39
+ }
40
+
41
+ .nav-container {
42
+ max-width: 1400px;
43
+ margin: 0 auto;
44
+ padding: 1rem 2rem;
45
+ display: flex;
46
+ justify-content: space-between;
47
+ align-items: center;
48
+ }
49
+
50
+ .nav-brand {
51
+ display: flex;
52
+ align-items: center;
53
+ gap: 0.5rem;
54
+ font-size: 1.5rem;
55
+ font-weight: bold;
56
+ color: var(--primary-color);
57
+ }
58
+
59
+ .nav-brand i {
60
+ font-size: 2rem;
61
+ }
62
+
63
+ .nav-links {
64
+ display: flex;
65
+ align-items: center;
66
+ gap: 2rem;
67
+ }
68
+
69
+ .nav-link {
70
+ color: var(--text-secondary);
71
+ text-decoration: none;
72
+ transition: color 0.3s;
73
+ font-weight: 500;
74
+ }
75
+
76
+ .nav-link:hover, .nav-link.active {
77
+ color: var(--primary-color);
78
+ }
79
+
80
+ .user-menu {
81
+ position: relative;
82
+ }
83
+
84
+ .user-btn {
85
+ background: none;
86
+ border: none;
87
+ color: var(--text-primary);
88
+ display: flex;
89
+ align-items: center;
90
+ gap: 0.5rem;
91
+ cursor: pointer;
92
+ font-size: 1rem;
93
+ padding: 0.5rem 1rem;
94
+ border-radius: 0.5rem;
95
+ transition: background 0.3s;
96
+ }
97
+
98
+ .user-btn:hover {
99
+ background: rgba(99, 102, 241, 0.1);
100
+ }
101
+
102
+ .user-dropdown {
103
+ position: absolute;
104
+ top: 100%;
105
+ right: 0;
106
+ background: var(--card-bg);
107
+ border: 1px solid var(--border-color);
108
+ border-radius: 0.5rem;
109
+ min-width: 200px;
110
+ display: none;
111
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
112
+ }
113
+
114
+ .user-dropdown.show {
115
+ display: block;
116
+ }
117
+
118
+ .dropdown-item {
119
+ display: block;
120
+ padding: 0.75rem 1rem;
121
+ color: var(--text-secondary);
122
+ text-decoration: none;
123
+ transition: background 0.3s;
124
+ }
125
+
126
+ .dropdown-item:hover {
127
+ background: rgba(99, 102, 241, 0.1);
128
+ color: var(--text-primary);
129
+ }
130
+
131
+ .user-dropdown hr {
132
+ border: none;
133
+ border-top: 1px solid var(--border-color);
134
+ margin: 0.5rem 0;
135
+ }
136
+
137
+ /* Main Content */
138
+ .main-content {
139
+ min-height: calc(100vh - 70px);
140
+ padding: 2rem 0;
141
+ }
142
+
143
+ .container {
144
+ max-width: 1400px;
145
+ margin: 0 auto;
146
+ padding: 0 2rem;
147
+ }
148
+
149
+ .page {
150
+ animation: fadeIn 0.3s ease-in;
151
+ }
152
+
153
+ .page.hidden {
154
+ display: none;
155
+ }
156
+
157
+ @keyframes fadeIn {
158
+ from { opacity: 0; transform: translateY(10px); }
159
+ to { opacity: 1; transform: translateY(0); }
160
+ }
161
+
162
+ .page-header {
163
+ margin-bottom: 2rem;
164
+ }
165
+
166
+ .page-header h1 {
167
+ font-size: 2.5rem;
168
+ margin-bottom: 0.5rem;
169
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
170
+ -webkit-background-clip: text;
171
+ -webkit-text-fill-color: transparent;
172
+ }
173
+
174
+ .page-subtitle {
175
+ color: var(--text-secondary);
176
+ font-size: 1.1rem;
177
+ }
178
+
179
+ /* Stats Grid */
180
+ .stats-grid {
181
+ display: grid;
182
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
183
+ gap: 1.5rem;
184
+ margin-bottom: 3rem;
185
+ }
186
+
187
+ .stat-card {
188
+ background: var(--card-bg);
189
+ padding: 1.5rem;
190
+ border-radius: 1rem;
191
+ border: 1px solid var(--border-color);
192
+ display: flex;
193
+ align-items: center;
194
+ gap: 1rem;
195
+ transition: transform 0.3s, box-shadow 0.3s;
196
+ }
197
+
198
+ .stat-card:hover {
199
+ transform: translateY(-2px);
200
+ box-shadow: 0 10px 30px rgba(99, 102, 241, 0.1);
201
+ }
202
+
203
+ .stat-icon {
204
+ width: 60px;
205
+ height: 60px;
206
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
207
+ border-radius: 1rem;
208
+ display: flex;
209
+ align-items: center;
210
+ justify-content: center;
211
+ font-size: 1.5rem;
212
+ }
213
+
214
+ .stat-info h3 {
215
+ font-size: 2rem;
216
+ margin-bottom: 0.25rem;
217
+ }
218
+
219
+ .stat-info p {
220
+ color: var(--text-secondary);
221
+ }
222
+
223
+ /* Quick Actions */
224
+ .quick-actions h2 {
225
+ margin-bottom: 1.5rem;
226
+ color: var(--text-primary);
227
+ }
228
+
229
+ .action-grid {
230
+ display: grid;
231
+ grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
232
+ gap: 1.5rem;
233
+ }
234
+
235
+ .action-card {
236
+ background: var(--card-bg);
237
+ border: 1px solid var(--border-color);
238
+ border-radius: 1rem;
239
+ padding: 2rem;
240
+ text-align: center;
241
+ cursor: pointer;
242
+ transition: all 0.3s;
243
+ color: var(--text-primary);
244
+ }
245
+
246
+ .action-card:hover {
247
+ transform: translateY(-4px);
248
+ box-shadow: 0 15px 40px rgba(99, 102, 241, 0.15);
249
+ border-color: var(--primary-color);
250
+ }
251
+
252
+ .action-card i {
253
+ font-size: 3rem;
254
+ color: var(--primary-color);
255
+ margin-bottom: 1rem;
256
+ }
257
+
258
+ .action-card h3 {
259
+ margin-bottom: 0.5rem;
260
+ font-size: 1.25rem;
261
+ }
262
+
263
+ .action-card p {
264
+ color: var(--text-secondary);
265
+ }
266
+
267
+ /* Forms */
268
+ .train-form-container {
269
+ background: var(--card-bg);
270
+ border: 1px solid var(--border-color);
271
+ border-radius: 1rem;
272
+ padding: 2rem;
273
+ max-width: 900px;
274
+ margin: 0 auto;
275
+ }
276
+
277
+ .form-section {
278
+ margin-bottom: 2rem;
279
+ }
280
+
281
+ .form-section h3 {
282
+ margin-bottom: 1rem;
283
+ color: var(--text-primary);
284
+ display: flex;
285
+ align-items: center;
286
+ gap: 0.5rem;
287
+ }
288
+
289
+ .form-row {
290
+ display: grid;
291
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
292
+ gap: 1rem;
293
+ }
294
+
295
+ .form-group {
296
+ margin-bottom: 1rem;
297
+ }
298
+
299
+ .form-group label {
300
+ display: block;
301
+ margin-bottom: 0.5rem;
302
+ color: var(--text-secondary);
303
+ font-weight: 500;
304
+ }
305
+
306
+ .form-group input,
307
+ .form-group select {
308
+ width: 100%;
309
+ padding: 0.75rem;
310
+ background: rgba(15, 23, 42, 0.5);
311
+ border: 1px solid var(--border-color);
312
+ border-radius: 0.5rem;
313
+ color: var(--text-primary);
314
+ font-size: 1rem;
315
+ transition: border-color 0.3s;
316
+ }
317
+
318
+ .form-group input:focus,
319
+ .form-group select:focus {
320
+ outline: none;
321
+ border-color: var(--primary-color);
322
+ box-shadow: 0 0 0 3px rgba(99, 102, 241, 0.1);
323
+ }
324
+
325
+ .form-group small {
326
+ display: block;
327
+ margin-top: 0.25rem;
328
+ color: var(--text-muted);
329
+ font-size: 0.875rem;
330
+ }
331
+
332
+ .checkbox-group {
333
+ display: flex;
334
+ align-items: center;
335
+ gap: 0.5rem;
336
+ }
337
+
338
+ .checkbox-group input[type="checkbox"] {
339
+ width: auto;
340
+ }
341
+
342
+ .form-actions {
343
+ display: flex;
344
+ gap: 1rem;
345
+ justify-content: flex-end;
346
+ padding-top: 1rem;
347
+ border-top: 1px solid var(--border-color);
348
+ }
349
+
350
+ /* Buttons */
351
+ .btn {
352
+ padding: 0.75rem 1.5rem;
353
+ border: none;
354
+ border-radius: 0.5rem;
355
+ font-size: 1rem;
356
+ font-weight: 500;
357
+ cursor: pointer;
358
+ transition: all 0.3s;
359
+ display: inline-flex;
360
+ align-items: center;
361
+ gap: 0.5rem;
362
+ text-decoration: none;
363
+ }
364
+
365
+ .btn-primary {
366
+ background: linear-gradient(135deg, var(--primary-color), var(--primary-dark));
367
+ color: white;
368
+ }
369
+
370
+ .btn-primary:hover {
371
+ transform: translateY(-2px);
372
+ box-shadow: 0 10px 25px rgba(99, 102, 241, 0.3);
373
+ }
374
+
375
+ .btn-secondary {
376
+ background: transparent;
377
+ color: var(--text-secondary);
378
+ border: 1px solid var(--border-color);
379
+ }
380
+
381
+ .btn-secondary:hover {
382
+ background: rgba(99, 102, 241, 0.1);
383
+ border-color: var(--primary-color);
384
+ color: var(--text-primary);
385
+ }
386
+
387
+ .btn-danger {
388
+ background: var(--danger-color);
389
+ color: white;
390
+ }
391
+
392
+ .btn-danger:hover {
393
+ background: #dc2626;
394
+ }
395
+
396
+ .btn-large {
397
+ padding: 1rem 2rem;
398
+ font-size: 1.1rem;
399
+ }
400
+
401
+ /* Models Grid */
402
+ .models-filter {
403
+ display: flex;
404
+ justify-content: space-between;
405
+ align-items: center;
406
+ margin-bottom: 2rem;
407
+ gap: 1rem;
408
+ }
409
+
410
+ .filter-group {
411
+ display: flex;
412
+ gap: 1rem;
413
+ flex: 1;
414
+ max-width: 500px;
415
+ }
416
+
417
+ .filter-group input,
418
+ .filter-group select {
419
+ flex: 1;
420
+ padding: 0.75rem;
421
+ background: rgba(30, 41, 59, 0.5);
422
+ border: 1px solid var(--border-color);
423
+ border-radius: 0.5rem;
424
+ color: var(--text-primary);
425
+ }
426
+
427
+ .models-grid {
428
+ display: grid;
429
+ grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
430
+ gap: 1.5rem;
431
+ }
432
+
433
+ .model-card {
434
+ background: var(--card-bg);
435
+ border: 1px solid var(--border-color);
436
+ border-radius: 1rem;
437
+ padding: 1.5rem;
438
+ transition: all 0.3s;
439
+ }
440
+
441
+ .model-card:hover {
442
+ transform: translateY(-2px);
443
+ box-shadow: 0 10px 30px rgba(99, 102, 241, 0.1);
444
+ }
445
+
446
+ .model-header {
447
+ display: flex;
448
+ justify-content: space-between;
449
+ align-items: start;
450
+ margin-bottom: 1rem;
451
+ }
452
+
453
+ .model-title {
454
+ font-size: 1.25rem;
455
+ font-weight: 600;
456
+ margin-bottom: 0.25rem;
457
+ }
458
+
459
+ .model-type {
460
+ color: var(--text-secondary);
461
+ font-size: 0.875rem;
462
+ }
463
+
464
+ .model-status {
465
+ padding: 0.25rem 0.75rem;
466
+ border-radius: 1rem;
467
+ font-size: 0.75rem;
468
+ font-weight: 600;
469
+ text-transform: uppercase;
470
+ }
471
+
472
+ .status-completed {
473
+ background: rgba(16, 185, 129, 0.2);
474
+ color: var(--success-color);
475
+ }
476
+
477
+ .status-training {
478
+ background: rgba(245, 158, 11, 0.2);
479
+ color: var(--warning-color);
480
+ }
481
+
482
+ .status-failed {
483
+ background: rgba(239, 68, 68, 0.2);
484
+ color: var(--danger-color);
485
+ }
486
+
487
+ .model-metrics {
488
+ display: grid;
489
+ grid-template-columns: repeat(3, 1fr);
490
+ gap: 1rem;
491
+ margin: 1rem 0;
492
+ padding: 1rem 0;
493
+ border-top: 1px solid var(--border-color);
494
+ border-bottom: 1px solid var(--border-color);
495
+ }
496
+
497
+ .model-metric {
498
+ text-align: center;
499
+ }
500
+
501
+ .model-metric h4 {
502
+ font-size: 1.25rem;
503
+ color: var(--primary-color);
504
+ }
505
+
506
+ .model-metric p {
507
+ font-size: 0.875rem;
508
+ color: var(--text-secondary);
509
+ }
510
+
511
+ .model-actions {
512
+ display: flex;
513
+ gap: 0.5rem;
514
+ margin-top: 1rem;
515
+ }
516
+
517
+ .model-actions .btn {
518
+ flex: 1;
519
+ padding: 0.5rem;
520
+ font-size: 0.875rem;
521
+ }
522
+
523
+ /* Modal */
524
+ .modal {
525
+ display: none;
526
+ position: fixed;
527
+ top: 0;
528
+ left: 0;
529
+ width: 100%;
530
+ height: 100%;
531
+ background: rgba(0, 0, 0, 0.8);
532
+ z-index: 2000;
533
+ align-items: center;
534
+ justify-content: center;
535
+ }
536
+
537
+ .modal.show {
538
+ display: flex;
539
+ }
540
+
541
+ .modal-content {
542
+ background: var(--card-bg);
543
+ border-radius: 1rem;
544
+ width: 90%;
545
+ max-width: 500px;
546
+ max-height: 90vh;
547
+ overflow-y: auto;
548
+ animation: slideUp 0.3s ease-out;
549
+ }
550
+
551
+ .modal-large {
552
+ max-width: 800px;
553
+ }
554
+
555
+ @keyframes slideUp {
556
+ from { transform: translateY(50px); opacity: 0; }
557
+ to { transform: translateY(0); opacity: 1; }
558
+ }
559
+
560
+ .modal-header {
561
+ padding: 1.5rem;
562
+ border-bottom: 1px solid var(--border-color);
563
+ display: flex;
564
+ justify-content: space-between;
565
+ align-items: center;
566
+ }
567
+
568
+ .modal-header h2 {
569
+ margin: 0;
570
+ }
571
+
572
+ .close-btn {
573
+ background: none;
574
+ border: none;
575
+ color: var(--text-secondary);
576
+ font-size: 1.5rem;
577
+ cursor: pointer;
578
+ padding: 0.25rem;
579
+ }
580
+
581
+ .close-btn:hover {
582
+ color: var(--text-primary);
583
+ }
584
+
585
+ .modal-body {
586
+ padding: 1.5rem;
587
+ }
588
+
589
+ .switch-form {
590
+ margin-top: 1rem;
591
+ text-align: center;
592
+ color: var(--text-secondary);
593
+ }
594
+
595
+ .switch-form a {
596
+ color: var(--primary-color);
597
+ text-decoration: none;
598
+ }
599
+
600
+ .switch-form a:hover {
601
+ text-decoration: underline;
602
+ }
603
+
604
+ /* Training Progress */
605
+ .training-info {
606
+ margin-bottom: 1.5rem;
607
+ }
608
+
609
+ .training-info p {
610
+ margin-bottom: 0.5rem;
611
+ }
612
+
613
+ .progress-container {
614
+ margin-bottom: 2rem;
615
+ }
616
+
617
+ .progress-bar {
618
+ width: 100%;
619
+ height: 8px;
620
+ background: rgba(99, 102, 241, 0.1);
621
+ border-radius: 4px;
622
+ overflow: hidden;
623
+ margin-bottom: 0.5rem;
624
+ }
625
+
626
+ .progress-fill {
627
+ height: 100%;
628
+ background: linear-gradient(90deg, var(--primary-color), var(--secondary-color));
629
+ border-radius: 4px;
630
+ transition: width 0.3s ease;
631
+ width: 0%;
632
+ }
633
+
634
+ .progress-text {
635
+ color: var(--text-secondary);
636
+ }
637
+
638
+ .training-metrics {
639
+ display: grid;
640
+ grid-template-columns: repeat(3, 1fr);
641
+ gap: 1rem;
642
+ margin-bottom: 2rem;
643
+ }
644
+
645
+ .metric {
646
+ background: rgba(15, 23, 42, 0.5);
647
+ padding: 1rem;
648
+ border-radius: 0.5rem;
649
+ text-align: center;
650
+ }
651
+
652
+ .metric i {
653
+ font-size: 1.5rem;
654
+ color: var(--primary-color);
655
+ margin-bottom: 0.5rem;
656
+ }
657
+
658
+ .metric h4 {
659
+ font-size: 1.25rem;
660
+ margin-top: 0.25rem;
661
+ }
662
+
663
+ .training-logs {
664
+ margin-bottom: 2rem;
665
+ }
666
+
667
+ .training-logs h4 {
668
+ margin-bottom: 1rem;
669
+ }
670
+
671
+ .log-container {
672
+ background: rgba(15, 23, 42, 0.5);
673
+ border: 1px solid var(--border-color);
674
+ border-radius: 0.5rem;
675
+ padding: 1rem;
676
+ height: 200px;
677
+ overflow-y: auto;
678
+ font-family: 'Courier New', monospace;
679
+ font-size: 0.875rem;
680
+ }
681
+
682
+ .log-entry {
683
+ margin-bottom: 0.5rem;
684
+ color: var(--text-secondary);
685
+ }
686
+
687
+ .log-entry.info {
688
+ color: var(--primary-color);
689
+ }
690
+
691
+ .log-entry.success {
692
+ color: var(--success-color);
693
+ }
694
+
695
+ .log-entry.error {
696
+ color: var(--danger-color);
697
+ }
698
+
699
+ .training-actions {
700
+ display: flex;
701
+ gap: 1rem;
702
+ justify-content: flex-end;
703
+ }
704
+
705
+ /* Profile */
706
+ .profile-card {
707
+ background: var(--card-bg);
708
+ border: 1px solid var(--border-color);
709
+ border-radius: 1rem;
710
+ padding: 2rem;
711
+ display: flex;
712
+ align-items: center;
713
+ gap: 2rem;
714
+ margin-bottom: 2rem;
715
+ }
716
+
717
+ .profile-avatar {
718
+ width: 100px;
719
+ height: 100px;
720
+ background: linear-gradient(135deg, var(--primary-color), var(--secondary-color));
721
+ border-radius: 50%;
722
+ display: flex;
723
+ align-items: center;
724
+ justify-content: center;
725
+ font-size: 3rem;
726
+ }
727
+
728
+ .profile-info h2 {
729
+ margin-bottom: 0.5rem;
730
+ }
731
+
732
+ .profile-info p {
733
+ color: var(--text-secondary);
734
+ }
735
+
736
+ .member-since {
737
+ margin-top: 0.5rem;
738
+ font-size: 0.875rem;
739
+ }
740
+
741
+ .settings-section {
742
+ background: var(--card-bg);
743
+ border: 1px solid var(--border-color);
744
+ border-radius: 1rem;
745
+ padding: 2rem;
746
+ }
747
+
748
+ .settings-section h3 {
749
+ margin-bottom: 1.5rem;
750
+ }
751
+
752
+ .setting-item {
753
+ display: flex;
754
+ justify-content: space-between;
755
+ align-items: center;
756
+ padding: 1rem 0;
757
+ border-bottom: 1px solid var(--border-color);
758
+ }
759
+
760
+ .setting-item:last-child {
761
+ border-bottom: none;
762
+ }
763
+
764
+ /* Toggle Switch */
765
+ .switch {
766
+ position: relative;
767
+ display: inline-block;
768
+ width: 50px;
769
+ height: 24px;
770
+ }
771
+
772
+ .switch input {
773
+ opacity: 0;
774
+ width: 0;
775
+ height: 0;
776
+ }
777
+
778
+ .slider {
779
+ position: absolute;
780
+ cursor: pointer;
781
+ top: 0;
782
+ left: 0;
783
+ right: 0;
784
+ bottom: 0;
785
+ background-color: var(--border-color);
786
+ transition: 0.4s;
787
+ border-radius: 24px;
788
+ }
789
+
790
+ .slider:before {
791
+ position: absolute;
792
+ content: "";
793
+ height: 18px;
794
+ width: 18px;
795
+ left: 3px;
796
+ bottom: 3px;
797
+ background-color: white;
798
+ transition: 0.4s;
799
+ border-radius: 50%;
800
+ }
801
+
802
+ input:checked + .slider {
803
+ background-color: var(--primary-color);
804
+ }
805
+
806
+ input:checked + .slider:before {
807
+ transform: translateX(26px);
808
+ }
809
+
810
+ /* Toast Notification */
811
+ .toast {
812
+ position: fixed;
813
+ bottom: 2rem;
814
+ right: 2rem;
815
+ background: var(--card-bg);
816
+ border: 1px solid var(--border-color);
817
+ border-radius: 0.5rem;
818
+ padding: 1rem 1.5rem;
819
+ display: none;
820
+ align-items: center;
821
+ gap: 0.75rem;
822
+ box-shadow: 0 10px 25px rgba(0, 0, 0, 0.5);
823
+ z-index: 3000;
824
+ animation: slideInRight 0.3s ease-out;
825
+ }
826
+
827
+ .toast.show {
828
+ display: flex;
829
+ }
830
+
831
+ @keyframes slideInRight {
832
+ from { transform: translateX(100%); }
833
+ to { transform: translateX(0); }
834
+ }
835
+
836
+ .toast-content {
837
+ display: flex;
838
+ align-items: center;
839
+ gap: 0.75rem;
840
+ }
841
+
842
+ .toast i {
843
+ color: var(--success-color);
844
+ font-size: 1.25rem;
845
+ }
846
+
847
+ /* Responsive Design */
848
+ @media (max-width: 768px) {
849
+ .nav-container {
850
+ padding: 1rem;
851
+ }
852
+
853
+ .nav-links {
854
+ gap: 1rem;
855
+ }
856
+
857
+ .nav-link span {
858
+ display: none;
859
+ }
860
+
861
+ .page-header h1 {
862
+ font-size: 2rem;
863
+ }
864
+
865
+ .stats-grid {
866
+ grid-template-columns: 1fr;
867
+ }
868
+
869
+ .action-grid {
870
+ grid-template-columns: 1fr;
871
+ }
872
+
873
+ .models-filter {
874
+ flex-direction: column;
875
+ }
876
+
877
+ .filter-group {
878
+ max-width: 100%;
879
+ }
880
+
881
+ .models-grid {
882
+ grid-template-columns: 1fr;
883
+ }
884
+
885
+ .profile-card {
886
+ flex-direction: column;
887
+ text-align: center;
888
+ }
889
+
890
+ .training-metrics {
891
+ grid-template-columns: 1fr;
892
+ }
893
+
894
+ .form-actions {
895
+ flex-direction: column;
896
+ }
897
+
898
+ .modal-content {
899
+ width: 95%;
900
+ margin: 1rem;
901
+ }
902
+ }
903
+
904
+ /* Loading Spinner */
905
+ .spinner {
906
+ border: 3px solid var(--border-color);
907
+ border-top: 3px solid var(--primary-color);
908
+ border-radius: 50%;
909
+ width: 40px;
910
+ height: 40px;
911
+ animation: spin 1s linear infinite;
912
+ margin: 0 auto;
913
+ }
914
+
915
+ @keyframes spin {
916
+ 0% { transform: rotate(0deg); }
917
+ 100% { transform: rotate(360deg); }
918
+ }
919
+
920
+ /* Empty State */
921
+ .empty-state {
922
+ text-align: center;
923
+ padding: 3rem;
924
+ color: var(--text-secondary);
925
+ }
926
+
927
+ .empty-state i {
928
+ font-size: 4rem;
929
+ color: var(--border-color);
930
+ margin-bottom: 1rem;
931
+ }
932
+
933
+ .empty-state h3 {
934
+ margin-bottom: 0.5rem;
935
+ color: var(--text-primary);
936
+ }
937
+
938
+ /* Footer */
939
+ .footer {
940
+ margin-top: 4rem;
941
+ padding: 2rem;
942
+ text-align: center;
943
+ border-top: 1px solid var(--border-color);
944
+ color: var(--text-secondary);
945
+ }
946
+
947
+ .footer a {
948
+ color: var(--primary-color);
949
+ text-decoration: none;
950
+ }
951
+
952
+ .footer a:hover {
953
+ text-decoration: underline;
954
+ }
assets/js/app.js ADDED
@@ -0,0 +1,619 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Application State
2
+ let appState = {
3
+ user: null,
4
+ currentPage: 'dashboard',
5
+ models: [],
6
+ isTraining: false,
7
+ trainingInterval: null
8
+ };
9
+
10
+ // Initialize Application
11
+ document.addEventListener('DOMContentLoaded', function() {
12
+ initializeApp();
13
+ loadStoredData();
14
+ setupEventListeners();
15
+ checkAuthStatus();
16
+ });
17
+
18
+ function initializeApp() {
19
+ // Load saved models
20
+ const savedModels = localStorage.getItem('aiModels');
21
+ if (savedModels) {
22
+ appState.models = JSON.parse(savedModels);
23
+ }
24
+
25
+ // Update UI
26
+ updateModelsList();
27
+ updateStats();
28
+ }
29
+
30
+ function loadStoredData() {
31
+ // Check for saved user session
32
+ const savedUser = localStorage.getItem('currentUser');
33
+ if (savedUser) {
34
+ appState.user = JSON.parse(savedUser);
35
+ updateUserUI();
36
+ }
37
+ }
38
+
39
+ function setupEventListeners() {
40
+ // Navigation
41
+ document.querySelectorAll('.nav-link').forEach(link => {
42
+ link.addEventListener('click', function(e) {
43
+ e.preventDefault();
44
+ const page = this.dataset.page;
45
+ if (page) {
46
+ navigateToPage(page);
47
+ }
48
+ });
49
+ });
50
+
51
+ // Action cards navigation
52
+ document.querySelectorAll('.action-card').forEach(card => {
53
+ card.addEventListener('click', function() {
54
+ const page = this.dataset.page;
55
+ if (page) {
56
+ navigateToPage(page);
57
+ }
58
+ });
59
+ });
60
+
61
+ // User menu
62
+ document.getElementById('userBtn').addEventListener('click', function() {
63
+ document.getElementById('userDropdown').classList.toggle('show');
64
+ });
65
+
66
+ // Close dropdown when clicking outside
67
+ document.addEventListener('click', function(e) {
68
+ if (!e.target.closest('.user-menu')) {
69
+ document.getElementById('userDropdown').classList.remove('show');
70
+ }
71
+ });
72
+
73
+ // Modals
74
+ document.getElementById('closeLoginModal').addEventListener('click', () => closeModal('loginModal'));
75
+ document.getElementById('closeRegisterModal').addEventListener('click', () => closeModal('registerModal'));
76
+ document.getElementById('closeTrainingModal').addEventListener('click', () => closeModal('trainingModal'));
77
+
78
+ // Login/Register forms
79
+ document.getElementById('loginForm').addEventListener('submit', handleLogin);
80
+ document.getElementById('registerForm').addEventListener('submit', handleRegister);
81
+
82
+ // Switch between login/register
83
+ document.getElementById('showRegister').addEventListener('click', function(e) {
84
+ e.preventDefault();
85
+ closeModal('loginModal');
86
+ openModal('registerModal');
87
+ });
88
+
89
+ document.getElementById('showLogin').addEventListener('click', function(e) {
90
+ e.preventDefault();
91
+ closeModal('registerModal');
92
+ openModal('loginModal');
93
+ });
94
+
95
+ // Train form
96
+ document.getElementById('trainForm').addEventListener('submit', handleTrainSubmit);
97
+
98
+ // Logout
99
+ document.getElementById('logoutBtn').addEventListener('click', handleLogout);
100
+
101
+ // Profile navigation
102
+ document.querySelectorAll('.dropdown-item').forEach(item => {
103
+ item.addEventListener('click', function(e) {
104
+ e.preventDefault();
105
+ const page = this.dataset.page;
106
+ if (page) {
107
+ navigateToPage(page);
108
+ document.getElementById('userDropdown').classList.remove('show');
109
+ }
110
+ });
111
+ });
112
+
113
+ // Model search and filter
114
+ document.getElementById('modelSearch').addEventListener('input', filterModels);
115
+ document.getElementById('modelFilter').addEventListener('change', filterModels);
116
+
117
+ // Training controls
118
+ document.getElementById('stopTraining').addEventListener('click', stopTraining);
119
+ document.getElementById('pauseTraining').addEventListener('click', pauseTraining);
120
+ }
121
+
122
+ function checkAuthStatus() {
123
+ if (!appState.user) {
124
+ openModal('loginModal');
125
+ }
126
+ }
127
+
128
+ function navigateToPage(page) {
129
+ // Hide all pages
130
+ document.querySelectorAll('.page').forEach(p => {
131
+ p.classList.add('hidden');
132
+ });
133
+
134
+ // Show selected page
135
+ const pageElement = document.getElementById(page + 'Page');
136
+ if (pageElement) {
137
+ pageElement.classList.remove('hidden');
138
+ }
139
+
140
+ // Update nav active state
141
+ document.querySelectorAll('.nav-link').forEach(link => {
142
+ link.classList.remove('active');
143
+ if (link.dataset.page === page) {
144
+ link.classList.add('active');
145
+ }
146
+ });
147
+
148
+ appState.currentPage = page;
149
+
150
+ // Page-specific actions
151
+ if (page === 'models') {
152
+ updateModelsList();
153
+ }
154
+ }
155
+
156
+ function openModal(modalId) {
157
+ document.getElementById(modalId).classList.add('show');
158
+ }
159
+
160
+ function closeModal(modalId) {
161
+ document.getElementById(modalId).classList.remove('show');
162
+ }
163
+
164
+ function handleLogin(e) {
165
+ e.preventDefault();
166
+ const email = document.getElementById('email').value;
167
+ const password = document.getElementById('password').value;
168
+
169
+ // Simulate authentication
170
+ const user = {
171
+ id: Date.now(),
172
+ email: email,
173
+ name: email.split('@')[0],
174
+ memberSince: new Date().toLocaleDateString('en-US', { month: 'long', year: 'numeric' })
175
+ };
176
+
177
+ appState.user = user;
178
+ localStorage.setItem('currentUser', JSON.stringify(user));
179
+ updateUserUI();
180
+ closeModal('loginModal');
181
+ showToast('Successfully logged in!');
182
+ }
183
+
184
+ function handleRegister(e) {
185
+ e.preventDefault();
186
+ const name = document.getElementById('regName').value;
187
+ const email = document.getElementById('regEmail').value;
188
+ const password = document.getElementById('regPassword').value;
189
+
190
+ // Simulate registration
191
+ const user = {
192
+ id: Date.now(),
193
+ email: email,
194
+ name: name,
195
+ memberSince: new Date().toLocaleDateString('en-US', { month: 'long', year: 'numeric' })
196
+ };
197
+
198
+ appState.user = user;
199
+ localStorage.setItem('currentUser', JSON.stringify(user));
200
+ updateUserUI();
201
+ closeModal('registerModal');
202
+ showToast('Account created successfully!');
203
+ }
204
+
205
+ function handleLogout() {
206
+ appState.user = null;
207
+ localStorage.removeItem('currentUser');
208
+ updateUserUI();
209
+ openModal('loginModal');
210
+ showToast('Logged out successfully');
211
+ }
212
+
213
+ function updateUserUI() {
214
+ if (appState.user) {
215
+ document.getElementById('username').textContent = appState.user.name;
216
+ document.getElementById('dashboardUsername').textContent = appState.user.name;
217
+ document.getElementById('profileName').textContent = appState.user.name;
218
+ document.getElementById('profileEmail').textContent = appState.user.email;
219
+ document.getElementById('memberSince').textContent = appState.user.memberSince;
220
+ } else {
221
+ document.getElementById('username').textContent = 'Guest';
222
+ document.getElementById('dashboardUsername').textContent = 'Guest';
223
+ }
224
+ }
225
+
226
+ function handleTrainSubmit(e) {
227
+ e.preventDefault();
228
+
229
+ if (!appState.user) {
230
+ showToast('Please login to train models');
231
+ openModal('loginModal');
232
+ return;
233
+ }
234
+
235
+ const formData = {
236
+ modelName: document.getElementById('modelName').value,
237
+ modelType: document.getElementById('modelType').value,
238
+ datasetPath: document.getElementById('datasetPath').value,
239
+ trainSplit: document.getElementById('trainSplit').value,
240
+ valSplit: document.getElementById('valSplit').value,
241
+ epochs: parseInt(document.getElementById('epochs').value),
242
+ batchSize: parseInt(document.getElementById('batchSize').value),
243
+ learningRate: parseFloat(document.getElementById('learningRate').value),
244
+ autoSave: document.getElementById('autoSave').checked,
245
+ generateConfig: document.getElementById('generateConfig').checked,
246
+ useGPU: document.getElementById('useGPU').checked,
247
+ userId: appState.user.id
248
+ };
249
+
250
+ // Create new model entry
251
+ const model = {
252
+ id: Date.now(),
253
+ ...formData,
254
+ status: 'training',
255
+ createdAt: new Date().toISOString(),
256
+ metrics: {
257
+ accuracy: 0,
258
+ loss: 1.0,
259
+ epochs: 0
260
+ }
261
+ };
262
+
263
+ appState.models.unshift(model);
264
+ localStorage.setItem('aiModels', JSON.stringify(appState.models));
265
+
266
+ // Start training simulation
267
+ startTraining(model);
268
+ }
269
+
270
+ function startTraining(model) {
271
+ appState.isTraining = true;
272
+
273
+ // Show training modal
274
+ document.getElementById('trainingModelName').textContent = model.modelName;
275
+ document.getElementById('trainingDataset').textContent = model.datasetPath;
276
+ document.getElementById('totalEpochs').textContent = model.epochs;
277
+ openModal('trainingModal');
278
+
279
+ // Clear logs
280
+ document.getElementById('logContainer').innerHTML = '';
281
+
282
+ // Simulate training progress
283
+ let currentEpoch = 0;
284
+ let progress = 0;
285
+ let startTime = Date.now();
286
+
287
+ appState.trainingInterval = setInterval(() => {
288
+ currentEpoch++;
289
+ progress = (currentEpoch / model.epochs) * 100;
290
+
291
+ // Update progress bar
292
+ document.getElementById('progressFill').style.width = progress + '%';
293
+ document.getElementById('progressPercent').textContent = Math.round(progress);
294
+ document.getElementById('currentEpoch').textContent = currentEpoch;
295
+
296
+ // Simulate metrics
297
+ const loss = Math.max(0.1, 1.0 - (currentEpoch / model.epochs) * 0.9 + Math.random() * 0.1);
298
+ const accuracy = Math.min(99, (currentEpoch / model.epochs) * 95 + Math.random() * 5);
299
+
300
+ document.getElementById('currentLoss').textContent = loss.toFixed(3);
301
+ document.getElementById('currentAccuracy').textContent = accuracy.toFixed(2) + '%';
302
+
303
+ // Update time elapsed
304
+ const elapsed = Math.floor((Date.now() - startTime) / 1000);
305
+ const minutes = Math.floor(elapsed / 60);
306
+ const seconds = elapsed % 60;
307
+ document.getElementById('timeElapsed').textContent =
308
+ `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`;
309
+
310
+ // Add log entry
311
+ addLogEntry(`Epoch ${currentEpoch}/${model.epochs} - Loss: ${loss.toFixed(3)}, Accuracy: ${accuracy.toFixed(2)}%`, 'info');
312
+
313
+ // Update model in storage
314
+ const modelIndex = appState.models.findIndex(m => m.id === model.id);
315
+ if (modelIndex !== -1) {
316
+ appState.models[modelIndex].metrics = {
317
+ accuracy: accuracy,
318
+ loss: loss,
319
+ epochs: currentEpoch
320
+ };
321
+ localStorage.setItem('aiModels', JSON.stringify(appState.models));
322
+ }
323
+
324
+ // Check if training is complete
325
+ if (currentEpoch >= model.epochs) {
326
+ completeTraining(model);
327
+ }
328
+ }, 1000); // Update every second for demo purposes
329
+ }
330
+
331
+ function completeTraining(model) {
332
+ clearInterval(appState.trainingInterval);
333
+ appState.isTraining = false;
334
+
335
+ // Update model status
336
+ const modelIndex = appState.models.findIndex(m => m.id === model.id);
337
+ if (modelIndex !== -1) {
338
+ appState.models[modelIndex].status = 'completed';
339
+ appState.models[modelIndex].completedAt = new Date().toISOString();
340
+ localStorage.setItem('aiModels', JSON.stringify(appState.models));
341
+ }
342
+
343
+ addLogEntry('Training completed successfully!', 'success');
344
+ showToast('Model training completed!');
345
+
346
+ // Generate config files if requested
347
+ if (model.generateConfig) {
348
+ setTimeout(() => {
349
+ addLogEntry('Configuration files generated and saved to your account', 'success');
350
+ }, 1000);
351
+ }
352
+
353
+ // Close modal after delay
354
+ setTimeout(() => {
355
+ closeModal('trainingModal');
356
+ navigateToPage('models');
357
+ updateModelsList();
358
+ updateStats();
359
+ }, 3000);
360
+ }
361
+
362
+ function stopTraining() {
363
+ if (appState.isTraining) {
364
+ clearInterval(appState.trainingInterval);
365
+ appState.isTraining = false;
366
+
367
+ // Find current training model
368
+ const trainingModel = appState.models.find(m => m.status === 'training');
369
+ if (trainingModel) {
370
+ trainingModel.status = 'failed';
371
+ localStorage.setItem('aiModels', JSON.stringify(appState.models));
372
+ }
373
+
374
+ addLogEntry('Training stopped by user', 'error');
375
+ showToast('Training stopped');
376
+
377
+ setTimeout(() => {
378
+ closeModal('trainingModal');
379
+ updateModelsList();
380
+ }, 1500);
381
+ }
382
+ }
383
+
384
+ function pauseTraining() {
385
+ // For demo purposes, pause just stops the interval
386
+ if (appState.isTraining) {
387
+ clearInterval(appState.trainingInterval);
388
+ appState.isTraining = false;
389
+ document.getElementById('pauseTraining').innerHTML = '<i class="fas fa-play"></i> Resume';
390
+ addLogEntry('Training paused', 'info');
391
+ } else {
392
+ // Resume logic would go here
393
+ showToast('Resume functionality not implemented in demo');
394
+ }
395
+ }
396
+
397
+ function addLogEntry(message, type = 'info') {
398
+ const logContainer = document.getElementById('logContainer');
399
+ const entry = document.createElement('div');
400
+ entry.className = `log-entry ${type}`;
401
+ const timestamp = new Date().toLocaleTimeString();
402
+ entry.textContent = `[${timestamp}] ${message}`;
403
+ logContainer.appendChild(entry);
404
+ logContainer.scrollTop = logContainer.scrollHeight;
405
+ }
406
+
407
+ function updateModelsList() {
408
+ const grid = document.getElementById('modelsGrid');
409
+ const userModels = appState.user ?
410
+ appState.models.filter(m => m.userId === appState.user.id) :
411
+ [];
412
+
413
+ if (userModels.length === 0) {
414
+ grid.innerHTML = `
415
+ <div class="empty-state" style="grid-column: 1 / -1;">
416
+ <i class="fas fa-robot"></i>
417
+ <h3>No models yet</h3>
418
+ <p>Start training your first AI model</p>
419
+ <button class="btn btn-primary" onclick="navigateToPage('train')">
420
+ <i class="fas fa-plus"></i>
421
+ Train Model
422
+ </button>
423
+ </div>
424
+ `;
425
+ return;
426
+ }
427
+
428
+ grid.innerHTML = userModels.map(model => `
429
+ <div class="model-card">
430
+ <div class="model-header">
431
+ <div>
432
+ <div class="model-title">${model.modelName}</div>
433
+ <div class="model-type">${model.modelType} • ${model.datasetPath}</div>
434
+ </div>
435
+ <div class="model-status status-${model.status}">
436
+ ${model.status}
437
+ </div>
438
+ </div>
439
+ <div class="model-metrics">
440
+ <div class="model-metric">
441
+ <h4>${model.metrics.accuracy.toFixed(1)}%</h4>
442
+ <p>Accuracy</p>
443
+ </div>
444
+ <div class="model-metric">
445
+ <h4>${model.metrics.loss.toFixed(3)}</h4>
446
+ <p>Loss</p>
447
+ </div>
448
+ <div class="model-metric">
449
+ <h4>${model.metrics.epochs}/${model.epochs}</h4>
450
+ <p>Epochs</p>
451
+ </div>
452
+ </div>
453
+ <div class="model-actions">
454
+ <button class="btn btn-secondary" onclick="downloadModel('${model.id}')">
455
+ <i class="fas fa-download"></i>
456
+ Download
457
+ </button>
458
+ <button class="btn btn-secondary" onclick="viewConfig('${model.id}')">
459
+ <i class="fas fa-cog"></i>
460
+ Config
461
+ </button>
462
+ <button class="btn btn-danger" onclick="deleteModel('${model.id}')">
463
+ <i class="fas fa-trash"></i>
464
+ Delete
465
+ </button>
466
+ </div>
467
+ </div>
468
+ `).join('');
469
+ }
470
+
471
+ function filterModels() {
472
+ const searchTerm = document.getElementById('modelSearch').value.toLowerCase();
473
+ const filterType = document.getElementById('modelFilter').value;
474
+
475
+ const cards = document.querySelectorAll('.model-card');
476
+ cards.forEach(card => {
477
+ const title = card.querySelector('.model-title').textContent.toLowerCase();
478
+ const type = card.querySelector('.model-type').textContent.toLowerCase();
479
+ const status = card.querySelector('.model-status').textContent.toLowerCase();
480
+
481
+ let matchesSearch = title.includes(searchTerm) || type.includes(searchTerm);
482
+ let matchesFilter = filterType === 'all' || status === filterType;
483
+
484
+ card.style.display = matchesSearch && matchesFilter ? 'block' : 'none';
485
+ });
486
+ }
487
+
488
+ function downloadModel(modelId) {
489
+ const model = appState.models.find(m => m.id == modelId);
490
+ if (model) {
491
+ showToast(`Downloading ${model.modelName}...`);
492
+
493
+ // Simulate download
494
+ setTimeout(() => {
495
+ showToast(`${model.modelName} downloaded successfully!`);
496
+ }, 2000);
497
+ }
498
+ }
499
+
500
+ function viewConfig(modelId) {
501
+ const model = appState.models.find(m => m.id == modelId);
502
+ if (model) {
503
+ // Create config object
504
+ const config = {
505
+ model_name: model.modelName,
506
+ model_type: model.modelType,
507
+ dataset: {
508
+ path: model.datasetPath,
509
+ train_split: model.trainSplit,
510
+ validation_split: model.valSplit
511
+ },
512
+ training: {
513
+ epochs: model.epochs,
514
+ batch_size: model.batchSize,
515
+ learning_rate: model.learningRate,
516
+ use_gpu: model.useGPU
517
+ },
518
+ metrics: model.metrics,
519
+ created_at: model.createdAt,
520
+ status: model.status
521
+ };
522
+
523
+ // Show config in a modal or new window
524
+ const configJson = JSON.stringify(config, null, 2);
525
+
526
+ // Create a temporary modal for config
527
+ const modal = document.createElement('div');
528
+ modal.className = 'modal show';
529
+ modal.innerHTML = `
530
+ <div class="modal-content modal-large">
531
+ <div class="modal-header">
532
+ <h2>Model Configuration</h2>
533
+ <button class="close-btn" onclick="this.closest('.modal').remove()">&times;</button>
534
+ </div>
535
+ <div class="modal-body">
536
+ <pre style="background: rgba(15, 23, 42, 0.5); padding: 1rem; border-radius: 0.5rem; overflow-x: auto;">${configJson}</pre>
537
+ <div style="margin-top: 1rem; display: flex; gap: 1rem;">
538
+ <button class="btn btn-primary" onclick="copyConfig('${btoa(configJson)}')">
539
+ <i class="fas fa-copy"></i>
540
+ Copy to Clipboard
541
+ </button>
542
+ <button class="btn btn-secondary" onclick="downloadConfig('${model.modelName}', '${btoa(configJson)}')">
543
+ <i class="fas fa-download"></i>
544
+ Download Config
545
+ </button>
546
+ </div>
547
+ </div>
548
+ </div>
549
+ `;
550
+ document.body.appendChild(modal);
551
+ }
552
+ }
553
+
554
+ function copyConfig(encodedConfig) {
555
+ const config = atob(encodedConfig);
556
+ navigator.clipboard.writeText(config).then(() => {
557
+ showToast('Configuration copied to clipboard!');
558
+ });
559
+ }
560
+
561
+ function downloadConfig(modelName, encodedConfig) {
562
+ const config = atob(encodedConfig);
563
+ const blob = new Blob([config], { type: 'application/json' });
564
+ const url = URL.createObjectURL(blob);
565
+ const a = document.createElement('a');
566
+ a.href = url;
567
+ a.download = `${modelName}_config.json`;
568
+ a.click();
569
+ URL.revokeObjectURL(url);
570
+ showToast('Configuration downloaded!');
571
+ }
572
+
573
+ function deleteModel(modelId) {
574
+ if (confirm('Are you sure you want to delete this model?')) {
575
+ appState.models = appState.models.filter(m => m.id != modelId);
576
+ localStorage.setItem('aiModels', JSON.stringify(appState.models));
577
+ updateModelsList();
578
+ updateStats();
579
+ showToast('Model deleted successfully');
580
+ }
581
+ }
582
+
583
+ function updateStats() {
584
+ const userModels = appState.user ?
585
+ appState.models.filter(m => m.userId === appState.user.id) :
586
+ [];
587
+
588
+ document.getElementById('totalModels').textContent = userModels.length;
589
+
590
+ const completedModels = userModels.filter(m => m.status === 'completed');
591
+ const avgAccuracy = completedModels.length > 0 ?
592
+ completedModels.reduce((sum, m) => sum + m.metrics.accuracy, 0) / completedModels.length : 0;
593
+ document.getElementById('avgAccuracy').textContent = avgAccuracy.toFixed(1) + '%';
594
+
595
+ const totalEpochs = userModels.reduce((sum, m) => sum + m.metrics.epochs, 0);
596
+ document.getElementById('trainingHours').textContent = Math.round(totalEpochs * 0.1); // Estimate
597
+
598
+ const uniqueDatasets = [...new Set(userModels.map(m => m.datasetPath))];
599
+ document.getElementById('datasetsUsed').textContent = uniqueDatasets.length;
600
+ }
601
+
602
+ function resetForm() {
603
+ document.getElementById('trainForm').reset();
604
+ showToast('Form reset');
605
+ }
606
+
607
+ function showTutorial() {
608
+ showToast('Tutorial coming soon!');
609
+ }
610
+
611
+ function showToast(message) {
612
+ const toast = document.getElementById('toast');
613
+ document.getElementById('toastMessage').textContent = message;
614
+ toast.classList.add('show');
615
+
616
+ setTimeout(() => {
617
+ toast.classList.remove('show');
618
+ }, 3000);
619
+ }
index.html CHANGED
@@ -1,19 +1,425 @@
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="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>AI Model Trainer - Train & Store Your Models</title>
7
+ <meta name="description" content="Train your own AI models with custom datasets and automatically store them in your account">
8
+ <link rel="stylesheet" href="assets/css/styles.css">
9
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
10
+ </head>
11
+ <body>
12
+ <!-- Navigation -->
13
+ <nav class="navbar">
14
+ <div class="nav-container">
15
+ <div class="nav-brand">
16
+ <i class="fas fa-brain"></i>
17
+ <span>AI Model Trainer</span>
18
+ </div>
19
+ <div class="nav-links">
20
+ <a href="#" class="nav-link" data-page="dashboard">Dashboard</a>
21
+ <a href="#" class="nav-link" data-page="train">Train Model</a>
22
+ <a href="#" class="nav-link" data-page="models">My Models</a>
23
+ <div class="user-menu">
24
+ <button class="user-btn" id="userBtn">
25
+ <i class="fas fa-user-circle"></i>
26
+ <span id="username">Guest</span>
27
+ </button>
28
+ <div class="user-dropdown" id="userDropdown">
29
+ <a href="#" class="dropdown-item" data-page="profile">Profile</a>
30
+ <a href="#" class="dropdown-item" data-page="settings">Settings</a>
31
+ <hr>
32
+ <a href="#" class="dropdown-item" id="logoutBtn">Logout</a>
33
+ </div>
34
+ </div>
35
+ </div>
36
+ </div>
37
+ </nav>
38
+
39
+ <!-- Login Modal -->
40
+ <div class="modal" id="loginModal">
41
+ <div class="modal-content">
42
+ <div class="modal-header">
43
+ <h2>Login to Your Account</h2>
44
+ <button class="close-btn" id="closeLoginModal">&times;</button>
45
+ </div>
46
+ <div class="modal-body">
47
+ <form id="loginForm">
48
+ <div class="form-group">
49
+ <label for="email">Email</label>
50
+ <input type="email" id="email" required>
51
+ </div>
52
+ <div class="form-group">
53
+ <label for="password">Password</label>
54
+ <input type="password" id="password" required>
55
+ </div>
56
+ <button type="submit" class="btn btn-primary">Login</button>
57
+ </form>
58
+ <p class="switch-form">
59
+ Don't have an account? <a href="#" id="showRegister">Register</a>
60
+ </p>
61
+ </div>
62
+ </div>
63
+ </div>
64
+
65
+ <!-- Register Modal -->
66
+ <div class="modal" id="registerModal">
67
+ <div class="modal-content">
68
+ <div class="modal-header">
69
+ <h2>Create Account</h2>
70
+ <button class="close-btn" id="closeRegisterModal">&times;</button>
71
+ </div>
72
+ <div class="modal-body">
73
+ <form id="registerForm">
74
+ <div class="form-group">
75
+ <label for="regName">Full Name</label>
76
+ <input type="text" id="regName" required>
77
+ </div>
78
+ <div class="form-group">
79
+ <label for="regEmail">Email</label>
80
+ <input type="email" id="regEmail" required>
81
+ </div>
82
+ <div class="form-group">
83
+ <label for="regPassword">Password</label>
84
+ <input type="password" id="regPassword" required>
85
+ </div>
86
+ <button type="submit" class="btn btn-primary">Create Account</button>
87
+ </form>
88
+ <p class="switch-form">
89
+ Already have an account? <a href="#" id="showLogin">Login</a>
90
+ </p>
91
+ </div>
92
+ </div>
93
+ </div>
94
+
95
+ <!-- Main Content -->
96
+ <main class="main-content">
97
+ <!-- Dashboard Page -->
98
+ <section class="page" id="dashboardPage">
99
+ <div class="container">
100
+ <div class="page-header">
101
+ <h1>Welcome back, <span id="dashboardUsername">User</span>!</h1>
102
+ <p class="page-subtitle">Start training your AI models today</p>
103
+ </div>
104
+
105
+ <div class="stats-grid">
106
+ <div class="stat-card">
107
+ <div class="stat-icon">
108
+ <i class="fas fa-robot"></i>
109
+ </div>
110
+ <div class="stat-info">
111
+ <h3 id="totalModels">0</h3>
112
+ <p>Total Models</p>
113
+ </div>
114
+ </div>
115
+ <div class="stat-card">
116
+ <div class="stat-icon">
117
+ <i class="fas fa-clock"></i>
118
+ </div>
119
+ <div class="stat-info">
120
+ <h3 id="trainingHours">0</h3>
121
+ <p>Training Hours</p>
122
+ </div>
123
+ </div>
124
+ <div class="stat-card">
125
+ <div class="stat-icon">
126
+ <i class="fas fa-database"></i>
127
+ </div>
128
+ <div class="stat-info">
129
+ <h3 id="datasetsUsed">0</h3>
130
+ <p>Datasets Used</p>
131
+ </div>
132
+ </div>
133
+ <div class="stat-card">
134
+ <div class="stat-icon">
135
+ <i class="fas fa-chart-line"></i>
136
+ </div>
137
+ <div class="stat-info">
138
+ <h3 id="avgAccuracy">0%</h3>
139
+ <p>Avg. Accuracy</p>
140
+ </div>
141
+ </div>
142
+ </div>
143
+
144
+ <div class="quick-actions">
145
+ <h2>Quick Actions</h2>
146
+ <div class="action-grid">
147
+ <button class="action-card" data-page="train">
148
+ <i class="fas fa-plus-circle"></i>
149
+ <h3>Train New Model</h3>
150
+ <p>Start training with a new dataset</p>
151
+ </button>
152
+ <button class="action-card" data-page="models">
153
+ <i class="fas fa-folder-open"></i>
154
+ <h3>View Models</h3>
155
+ <p>Browse your trained models</p>
156
+ </button>
157
+ <button class="action-card" onclick="showTutorial()">
158
+ <i class="fas fa-book"></i>
159
+ <h3>Tutorial</h3>
160
+ <p>Learn how to train models</p>
161
+ </button>
162
+ </div>
163
+ </div>
164
+ </div>
165
+ </section>
166
+
167
+ <!-- Train Model Page -->
168
+ <section class="page hidden" id="trainPage">
169
+ <div class="container">
170
+ <div class="page-header">
171
+ <h1>Train New Model</h1>
172
+ <p class="page-subtitle">Configure and train your AI model with custom datasets</p>
173
+ </div>
174
+
175
+ <div class="train-form-container">
176
+ <form id="trainForm">
177
+ <div class="form-section">
178
+ <h3>Model Configuration</h3>
179
+ <div class="form-row">
180
+ <div class="form-group">
181
+ <label for="modelName">Model Name</label>
182
+ <input type="text" id="modelName" placeholder="e.g., sentiment-analyzer-v1" required>
183
+ </div>
184
+ <div class="form-group">
185
+ <label for="modelType">Model Type</label>
186
+ <select id="modelType" required>
187
+ <option value="">Select model type</option>
188
+ <option value="classification">Classification</option>
189
+ <option value="regression">Regression</option>
190
+ <option value="nlp">Natural Language Processing</option>
191
+ <option value="cv">Computer Vision</option>
192
+ </select>
193
+ </div>
194
+ </div>
195
+ </div>
196
+
197
+ <div class="form-section">
198
+ <h3>Dataset Configuration</h3>
199
+ <div class="form-group">
200
+ <label for="datasetPath">HuggingFace Dataset Path</label>
201
+ <input type="text" id="datasetPath" placeholder="e.g., imdb/sentiment" required>
202
+ <small>Enter the HuggingFace dataset path (e.g., 'imdb/sentiment')</small>
203
+ </div>
204
+ <div class="form-row">
205
+ <div class="form-group">
206
+ <label for="trainSplit">Training Split</label>
207
+ <select id="trainSplit">
208
+ <option value="train">train</option>
209
+ <option value="train[:80%]">train[:80%]</option>
210
+ <option value="train[:60%]">train[:60%]</option>
211
+ </select>
212
+ </div>
213
+ <div class="form-group">
214
+ <label for="valSplit">Validation Split</label>
215
+ <select id="valSplit">
216
+ <option value="test">test</option>
217
+ <option value="train[-20%:]">train[-20%:]</option>
218
+ <option value="validation">validation</option>
219
+ </select>
220
+ </div>
221
+ </div>
222
+ </div>
223
+
224
+ <div class="form-section">
225
+ <h3>Training Parameters</h3>
226
+ <div class="form-row">
227
+ <div class="form-group">
228
+ <label for="epochs">Epochs</label>
229
+ <input type="number" id="epochs" min="1" max="100" value="10">
230
+ </div>
231
+ <div class="form-group">
232
+ <label for="batchSize">Batch Size</label>
233
+ <input type="number" id="batchSize" min="1" max="512" value="32">
234
+ </div>
235
+ <div class="form-group">
236
+ <label for="learningRate">Learning Rate</label>
237
+ <input type="number" id="learningRate" min="0.0001" max="1" step="0.0001" value="0.001">
238
+ </div>
239
+ </div>
240
+ </div>
241
+
242
+ <div class="form-section">
243
+ <h3>Advanced Options</h3>
244
+ <div class="form-group checkbox-group">
245
+ <label>
246
+ <input type="checkbox" id="autoSave">
247
+ Automatically save model checkpoints
248
+ </label>
249
+ </div>
250
+ <div class="form-group checkbox-group">
251
+ <label>
252
+ <input type="checkbox" id="generateConfig">
253
+ Generate configuration files
254
+ </label>
255
+ </div>
256
+ <div class="form-group checkbox-group">
257
+ <label>
258
+ <input type="checkbox" id="useGPU">
259
+ Use GPU acceleration (if available)
260
+ </label>
261
+ </div>
262
+ </div>
263
+
264
+ <div class="form-actions">
265
+ <button type="submit" class="btn btn-primary btn-large">
266
+ <i class="fas fa-play"></i>
267
+ Start Training
268
+ </button>
269
+ <button type="button" class="btn btn-secondary" onclick="resetForm()">
270
+ <i class="fas fa-redo"></i>
271
+ Reset
272
+ </button>
273
+ </div>
274
+ </form>
275
+ </div>
276
+ </div>
277
+ </section>
278
+
279
+ <!-- Models Page -->
280
+ <section class="page hidden" id="modelsPage">
281
+ <div class="container">
282
+ <div class="page-header">
283
+ <h1>My Models</h1>
284
+ <p class="page-subtitle">Manage and download your trained models</p>
285
+ </div>
286
+
287
+ <div class="models-filter">
288
+ <div class="filter-group">
289
+ <input type="text" id="modelSearch" placeholder="Search models...">
290
+ <select id="modelFilter">
291
+ <option value="all">All Models</option>
292
+ <option value="training">Training</option>
293
+ <option value="completed">Completed</option>
294
+ <option value="failed">Failed</option>
295
+ </select>
296
+ </div>
297
+ <button class="btn btn-primary" data-page="train">
298
+ <i class="fas fa-plus"></i>
299
+ Train New Model
300
+ </button>
301
+ </div>
302
+
303
+ <div class="models-grid" id="modelsGrid">
304
+ <!-- Models will be dynamically added here -->
305
+ </div>
306
+ </div>
307
+ </section>
308
+
309
+ <!-- Profile Page -->
310
+ <section class="page hidden" id="profilePage">
311
+ <div class="container">
312
+ <div class="page-header">
313
+ <h1>Profile</h1>
314
+ <p class="page-subtitle">Manage your account settings</p>
315
+ </div>
316
+
317
+ <div class="profile-card">
318
+ <div class="profile-avatar">
319
+ <i class="fas fa-user-circle"></i>
320
+ </div>
321
+ <div class="profile-info">
322
+ <h2 id="profileName">John Doe</h2>
323
+ <p id="profileEmail">[email protected]</p>
324
+ <p class="member-since">Member since: <span id="memberSince">January 2024</span></p>
325
+ </div>
326
+ </div>
327
+
328
+ <div class="settings-section">
329
+ <h3>Account Settings</h3>
330
+ <div class="setting-item">
331
+ <label>Email Notifications</label>
332
+ <label class="switch">
333
+ <input type="checkbox" checked>
334
+ <span class="slider"></span>
335
+ </label>
336
+ </div>
337
+ <div class="setting-item">
338
+ <label>Training Completion Alerts</label>
339
+ <label class="switch">
340
+ <input type="checkbox" checked>
341
+ <span class="slider"></span>
342
+ </label>
343
+ </div>
344
+ <div class="setting-item">
345
+ <label>Public Profile</label>
346
+ <label class="switch">
347
+ <input type="checkbox">
348
+ <span class="slider"></span>
349
+ </label>
350
+ </div>
351
+ </div>
352
+ </div>
353
+ </section>
354
+ </main>
355
+
356
+ <!-- Training Progress Modal -->
357
+ <div class="modal" id="trainingModal">
358
+ <div class="modal-content modal-large">
359
+ <div class="modal-header">
360
+ <h2>Training Progress</h2>
361
+ <button class="close-btn" id="closeTrainingModal">&times;</button>
362
+ </div>
363
+ <div class="modal-body">
364
+ <div class="training-info">
365
+ <p><strong>Model:</strong> <span id="trainingModelName"></span></p>
366
+ <p><strong>Dataset:</strong> <span id="trainingDataset"></span></p>
367
+ </div>
368
+ <div class="progress-container">
369
+ <div class="progress-bar">
370
+ <div class="progress-fill" id="progressFill"></div>
371
+ </div>
372
+ <p class="progress-text"><span id="progressPercent">0</span>% - Epoch <span id="currentEpoch">0</span>/<span id="totalEpochs">0</span></p>
373
+ </div>
374
+ <div class="training-metrics">
375
+ <div class="metric">
376
+ <i class="fas fa-chart-line"></i>
377
+ <div>
378
+ <p>Loss</p>
379
+ <h4 id="currentLoss">0.000</h4>
380
+ </div>
381
+ </div>
382
+ <div class="metric">
383
+ <i class="fas fa-bullseye"></i>
384
+ <div>
385
+ <p>Accuracy</p>
386
+ <h4 id="currentAccuracy">0.00%</h4>
387
+ </div>
388
+ </div>
389
+ <div class="metric">
390
+ <i class="fas fa-clock"></i>
391
+ <div>
392
+ <p>Time Elapsed</p>
393
+ <h4 id="timeElapsed">00:00</h4>
394
+ </div>
395
+ </div>
396
+ </div>
397
+ <div class="training-logs">
398
+ <h4>Training Logs</h4>
399
+ <div class="log-container" id="logContainer"></div>
400
+ </div>
401
+ <div class="training-actions">
402
+ <button class="btn btn-danger" id="stopTraining">
403
+ <i class="fas fa-stop"></i>
404
+ Stop Training
405
+ </button>
406
+ <button class="btn btn-secondary" id="pauseTraining">
407
+ <i class="fas fa-pause"></i>
408
+ Pause
409
+ </button>
410
+ </div>
411
+ </div>
412
+ </div>
413
+ </div>
414
+
415
+ <!-- Toast Notification -->
416
+ <div class="toast" id="toast">
417
+ <div class="toast-content">
418
+ <i class="fas fa-check-circle"></i>
419
+ <span id="toastMessage">Operation successful!</span>
420
+ </div>
421
+ </div>
422
+
423
+ <script src="assets/js/app.js"></script>
424
+ </body>
425
+ </html>