Docfile commited on
Commit
cf03bc3
·
verified ·
1 Parent(s): 7566447

Create template/index.html

Browse files
Files changed (1) hide show
  1. template/index.html +865 -0
template/index.html ADDED
@@ -0,0 +1,865 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html lang="fr">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Mariam AI - Résolution d'exercices</title>
7
+ <!-- Font Awesome pour les icônes -->
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
9
+ <!-- Google Fonts -->
10
+ <link href="https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap" rel="stylesheet">
11
+ <style>
12
+ :root {
13
+ --primary-color: #6C63FF;
14
+ --secondary-color: #F50057;
15
+ --success-color: #4CAF50;
16
+ --warning-color: #FF9800;
17
+ --error-color: #F44336;
18
+ --dark-color: #333;
19
+ --light-color: #F5F5F5;
20
+ --white: #FFFFFF;
21
+ --transition: all 0.3s ease;
22
+ }
23
+
24
+ * {
25
+ margin: 0;
26
+ padding: 0;
27
+ box-sizing: border-box;
28
+ }
29
+
30
+ body {
31
+ font-family: 'Poppins', sans-serif;
32
+ background-color: #F9FAFB;
33
+ color: #333;
34
+ line-height: 1.6;
35
+ }
36
+
37
+ .container {
38
+ max-width: 1200px;
39
+ margin: 0 auto;
40
+ padding: 0 15px;
41
+ }
42
+
43
+ header {
44
+ background: linear-gradient(135deg, var(--primary-color), #8A84FF);
45
+ color: white;
46
+ padding: 2rem 0;
47
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
48
+ }
49
+
50
+ header .container {
51
+ display: flex;
52
+ justify-content: space-between;
53
+ align-items: center;
54
+ }
55
+
56
+ .logo {
57
+ display: flex;
58
+ align-items: center;
59
+ font-size: 1.8rem;
60
+ font-weight: 700;
61
+ color: white;
62
+ text-decoration: none;
63
+ }
64
+
65
+ .logo i {
66
+ margin-right: 10px;
67
+ font-size: 2rem;
68
+ }
69
+
70
+ nav ul {
71
+ display: flex;
72
+ list-style: none;
73
+ }
74
+
75
+ nav ul li {
76
+ margin-left: 20px;
77
+ }
78
+
79
+ nav ul li a {
80
+ color: white;
81
+ text-decoration: none;
82
+ font-weight: 500;
83
+ transition: var(--transition);
84
+ }
85
+
86
+ nav ul li a:hover {
87
+ color: #FFD166;
88
+ }
89
+
90
+ .hero {
91
+ text-align: center;
92
+ padding: 3rem 1rem;
93
+ }
94
+
95
+ .hero h1 {
96
+ font-size: 2.5rem;
97
+ margin-bottom: 1rem;
98
+ color: var(--dark-color);
99
+ }
100
+
101
+ .hero p {
102
+ font-size: 1.2rem;
103
+ color: #666;
104
+ max-width: 800px;
105
+ margin: 0 auto 2rem auto;
106
+ }
107
+
108
+ main {
109
+ padding: 2rem 0;
110
+ }
111
+
112
+ .status-checks {
113
+ display: flex;
114
+ justify-content: center;
115
+ margin-bottom: 2rem;
116
+ }
117
+
118
+ .status-check {
119
+ background-color: var(--white);
120
+ border-radius: 8px;
121
+ padding: 15px;
122
+ margin: 0 10px;
123
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
124
+ width: 250px;
125
+ text-align: center;
126
+ transition: var(--transition);
127
+ }
128
+
129
+ .status-check.loading {
130
+ border: 2px dashed #ccc;
131
+ }
132
+
133
+ .status-check.success {
134
+ border-left: 4px solid var(--success-color);
135
+ }
136
+
137
+ .status-check.error {
138
+ border-left: 4px solid var(--error-color);
139
+ }
140
+
141
+ .status-check i {
142
+ font-size: 2rem;
143
+ margin-bottom: 10px;
144
+ }
145
+
146
+ .status-check .loading-icon {
147
+ color: #ccc;
148
+ animation: spin 1s linear infinite;
149
+ }
150
+
151
+ .status-check .success-icon {
152
+ color: var(--success-color);
153
+ }
154
+
155
+ .status-check .error-icon {
156
+ color: var(--error-color);
157
+ }
158
+
159
+ .status-check h3 {
160
+ margin-bottom: 5px;
161
+ font-size: 1.1rem;
162
+ }
163
+
164
+ .status-check p {
165
+ font-size: 0.9rem;
166
+ color: #666;
167
+ }
168
+
169
+ .upload-container {
170
+ background-color: var(--white);
171
+ border-radius: 12px;
172
+ padding: 2rem;
173
+ margin-bottom: 2rem;
174
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
175
+ text-align: center;
176
+ }
177
+
178
+ .upload-area {
179
+ border: 2px dashed #ccc;
180
+ border-radius: 8px;
181
+ padding: 3rem 2rem;
182
+ text-align: center;
183
+ cursor: pointer;
184
+ transition: var(--transition);
185
+ margin-bottom: 1.5rem;
186
+ position: relative;
187
+ }
188
+
189
+ .upload-area:hover {
190
+ border-color: var(--primary-color);
191
+ background-color: rgba(108, 99, 255, 0.05);
192
+ }
193
+
194
+ .upload-area.drag-over {
195
+ border-color: var(--primary-color);
196
+ background-color: rgba(108, 99, 255, 0.1);
197
+ }
198
+
199
+ .upload-area i {
200
+ font-size: 3rem;
201
+ color: #ccc;
202
+ margin-bottom: 1rem;
203
+ }
204
+
205
+ .upload-area h3 {
206
+ margin-bottom: 0.5rem;
207
+ color: #444;
208
+ }
209
+
210
+ .upload-area p {
211
+ color: #888;
212
+ font-size: 0.9rem;
213
+ margin-bottom: 1rem;
214
+ }
215
+
216
+ .upload-area input[type="file"] {
217
+ position: absolute;
218
+ top: 0;
219
+ left: 0;
220
+ width: 100%;
221
+ height: 100%;
222
+ opacity: 0;
223
+ cursor: pointer;
224
+ }
225
+
226
+ .btn {
227
+ display: inline-block;
228
+ padding: 0.8rem 1.5rem;
229
+ border-radius: 50px;
230
+ font-weight: 500;
231
+ text-decoration: none;
232
+ cursor: pointer;
233
+ transition: var(--transition);
234
+ border: none;
235
+ font-size: 1rem;
236
+ }
237
+
238
+ .btn-primary {
239
+ background-color: var(--primary-color);
240
+ color: white;
241
+ }
242
+
243
+ .btn-primary:hover {
244
+ background-color: #5A52E0;
245
+ transform: translateY(-2px);
246
+ box-shadow: 0 4px 12px rgba(108, 99, 255, 0.3);
247
+ }
248
+
249
+ .btn-primary:disabled {
250
+ background-color: #ccc;
251
+ cursor: not-allowed;
252
+ transform: none;
253
+ box-shadow: none;
254
+ }
255
+
256
+ .btn-secondary {
257
+ background-color: var(--secondary-color);
258
+ color: white;
259
+ }
260
+
261
+ .btn-secondary:hover {
262
+ background-color: #E80051;
263
+ transform: translateY(-2px);
264
+ box-shadow: 0 4px 12px rgba(245, 0, 87, 0.3);
265
+ }
266
+
267
+ .preview-container {
268
+ display: none;
269
+ margin-top: 2rem;
270
+ }
271
+
272
+ .preview-image {
273
+ max-width: 100%;
274
+ max-height: 400px;
275
+ border-radius: 8px;
276
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
277
+ }
278
+
279
+ .process-btn-container {
280
+ margin-top: 2rem;
281
+ }
282
+
283
+ .result-container {
284
+ display: none;
285
+ margin-top: 3rem;
286
+ padding: 2rem;
287
+ background-color: var(--white);
288
+ border-radius: 12px;
289
+ box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);
290
+ }
291
+
292
+ .result-tabs {
293
+ display: flex;
294
+ margin-bottom: 1.5rem;
295
+ border-bottom: 1px solid #ddd;
296
+ }
297
+
298
+ .result-tab {
299
+ padding: 10px 20px;
300
+ cursor: pointer;
301
+ background: none;
302
+ border: none;
303
+ border-bottom: 3px solid transparent;
304
+ font-weight: 500;
305
+ transition: var(--transition);
306
+ }
307
+
308
+ .result-tab.active {
309
+ border-bottom-color: var(--primary-color);
310
+ color: var(--primary-color);
311
+ }
312
+
313
+ .result-tab:hover:not(.active) {
314
+ border-bottom-color: #ddd;
315
+ }
316
+
317
+ .result-content {
318
+ display: none;
319
+ }
320
+
321
+ .result-content.active {
322
+ display: block;
323
+ }
324
+
325
+ .pdf-preview {
326
+ width: 100%;
327
+ height: 500px;
328
+ border: 1px solid #ddd;
329
+ border-radius: 8px;
330
+ }
331
+
332
+ .latex-code {
333
+ background-color: #f4f4f4;
334
+ padding: 15px;
335
+ border-radius: 8px;
336
+ white-space: pre-wrap;
337
+ font-family: monospace;
338
+ max-height: 400px;
339
+ overflow-y: auto;
340
+ }
341
+
342
+ .thinking-process {
343
+ background-color: #f9f9f9;
344
+ padding: 15px;
345
+ border-radius: 8px;
346
+ white-space: pre-wrap;
347
+ font-size: 0.9rem;
348
+ max-height: 400px;
349
+ overflow-y: auto;
350
+ border-left: 4px solid #ccc;
351
+ }
352
+
353
+ .download-btn {
354
+ display: flex;
355
+ align-items: center;
356
+ justify-content: center;
357
+ margin-top: 1.5rem;
358
+ }
359
+
360
+ .download-btn i {
361
+ margin-right: 10px;
362
+ }
363
+
364
+ .loader {
365
+ display: none;
366
+ text-align: center;
367
+ padding: 2rem;
368
+ }
369
+
370
+ .loader-icon {
371
+ font-size: 3rem;
372
+ color: var(--primary-color);
373
+ animation: spin 1s linear infinite;
374
+ }
375
+
376
+ .loader p {
377
+ margin-top: 1rem;
378
+ color: #666;
379
+ }
380
+
381
+ @keyframes spin {
382
+ 0% { transform: rotate(0deg); }
383
+ 100% { transform: rotate(360deg); }
384
+ }
385
+
386
+ footer {
387
+ background-color: var(--dark-color);
388
+ color: white;
389
+ padding: 2rem 0;
390
+ margin-top: 3rem;
391
+ }
392
+
393
+ footer .container {
394
+ display: flex;
395
+ justify-content: space-between;
396
+ align-items: center;
397
+ }
398
+
399
+ .footer-links {
400
+ display: flex;
401
+ }
402
+
403
+ .footer-links a {
404
+ color: white;
405
+ margin-left: 15px;
406
+ text-decoration: none;
407
+ transition: var(--transition);
408
+ }
409
+
410
+ .footer-links a:hover {
411
+ color: var(--primary-color);
412
+ }
413
+
414
+ /* Alert styles */
415
+ .alert {
416
+ padding: 15px;
417
+ border-radius: 8px;
418
+ margin-bottom: 1rem;
419
+ display: flex;
420
+ align-items: center;
421
+ }
422
+
423
+ .alert i {
424
+ margin-right: 10px;
425
+ font-size: 1.2rem;
426
+ }
427
+
428
+ .alert-success {
429
+ background-color: rgba(76, 175, 80, 0.1);
430
+ color: var(--success-color);
431
+ border-left: 4px solid var(--success-color);
432
+ }
433
+
434
+ .alert-error {
435
+ background-color: rgba(244, 67, 54, 0.1);
436
+ color: var(--error-color);
437
+ border-left: 4px solid var(--error-color);
438
+ }
439
+
440
+ .alert-warning {
441
+ background-color: rgba(255, 152, 0, 0.1);
442
+ color: var(--warning-color);
443
+ border-left: 4px solid var(--warning-color);
444
+ }
445
+
446
+ /* Responsive styles */
447
+ @media (max-width: 768px) {
448
+ .status-checks {
449
+ flex-direction: column;
450
+ align-items: center;
451
+ }
452
+
453
+ .status-check {
454
+ width: 100%;
455
+ max-width: 400px;
456
+ margin-bottom: 15px;
457
+ }
458
+
459
+ .hero h1 {
460
+ font-size: 2rem;
461
+ }
462
+
463
+ .hero p {
464
+ font-size: 1rem;
465
+ }
466
+
467
+ footer .container {
468
+ flex-direction: column;
469
+ text-align: center;
470
+ }
471
+
472
+ .footer-links {
473
+ margin-top: 1rem;
474
+ justify-content: center;
475
+ }
476
+
477
+ .footer-links a:first-child {
478
+ margin-left: 0;
479
+ }
480
+ }
481
+ </style>
482
+ </head>
483
+ <body>
484
+ <header>
485
+ <div class="container">
486
+ <a href="/" class="logo">
487
+ <i class="fas fa-brain"></i>
488
+ Mariam AI
489
+ </a>
490
+ <nav>
491
+ <ul>
492
+ <li><a href="/">Accueil</a></li>
493
+ <li><a href="#" title="À venir">Historique</a></li>
494
+ <li><a href="#" title="À venir">À propos</a></li>
495
+ </ul>
496
+ </nav>
497
+ </div>
498
+ </header>
499
+
500
+ <section class="hero">
501
+ <div class="container">
502
+ <h1>Résolution d'exercices scientifiques avec l'IA</h1>
503
+ <p>Téléchargez une image d'un exercice de mathématiques, physique ou chimie et obtenez une solution détaillée générée par l'intelligence artificielle, prête à télécharger en PDF.</p>
504
+ </div>
505
+ </section>
506
+
507
+ <main class="container">
508
+ <div class="status-checks">
509
+ <div class="status-check loading" id="latex-check">
510
+ <i class="fas fa-spinner loading-icon"></i>
511
+ <h3>Vérification LaTeX</h3>
512
+ <p>Vérification de l'installation LaTeX...</p>
513
+ </div>
514
+
515
+ <div class="status-check loading" id="api-check">
516
+ <i class="fas fa-spinner loading-icon"></i>
517
+ <h3>API Mariam AI</h3>
518
+ <p>Vérification de la connexion API...</p>
519
+ </div>
520
+ </div>
521
+
522
+ <div class="upload-container">
523
+ <h2>Téléchargez votre exercice</h2>
524
+ <p>Format accepté: JPEG, PNG, JPG</p>
525
+
526
+ <div class="upload-area" id="upload-area">
527
+ <i class="fas fa-cloud-upload-alt"></i>
528
+ <h3>Glissez-déposez votre image ici</h3>
529
+ <p>ou</p>
530
+ <button class="btn btn-primary">Parcourir les fichiers</button>
531
+ <input type="file" id="file-input" accept="image/png, image/jpeg, image/jpg">
532
+ </div>
533
+
534
+ <div class="preview-container" id="preview-container">
535
+ <h3>Aperçu de l'image</h3>
536
+ <img src="#" alt="Aperçu de l'exercice" class="preview-image" id="preview-image">
537
+
538
+ <div class="process-btn-container">
539
+ <button class="btn btn-primary" id="process-btn" disabled>
540
+ <i class="fas fa-magic"></i> Résoudre l'exercice
541
+ </button>
542
+ <button class="btn btn-secondary" id="cancel-btn">
543
+ <i class="fas fa-times"></i> Annuler
544
+ </button>
545
+ </div>
546
+ </div>
547
+ </div>
548
+
549
+ <div class="loader" id="loader">
550
+ <i class="fas fa-cog loader-icon"></i>
551
+ <p id="loader-message">Analyse de l'exercice et génération de la solution...</p>
552
+ </div>
553
+
554
+ <div class="result-container" id="result-container">
555
+ <h2>Résultat</h2>
556
+
557
+ <div class="result-tabs">
558
+ <button class="result-tab active" data-content="pdf-content">Solution PDF</button>
559
+ <button class="result-tab" data-content="latex-content">Code LaTeX</button>
560
+ <button class="result-tab" data-content="thinking-content">Processus de réflexion</button>
561
+ </div>
562
+
563
+ <div class="result-content active" id="pdf-content">
564
+ <iframe class="pdf-preview" id="pdf-preview" src=""></iframe>
565
+
566
+ <div class="download-btn">
567
+ <a href="#" class="btn btn-primary" id="download-btn">
568
+ <i class="fas fa-download"></i> Télécharger la solution en PDF
569
+ </a>
570
+ </div>
571
+ </div>
572
+
573
+ <div class="result-content" id="latex-content">
574
+ <div class="latex-code" id="latex-code-display"></div>
575
+ </div>
576
+
577
+ <div class="result-content" id="thinking-content">
578
+ <div class="thinking-process" id="thinking-process-display"></div>
579
+ </div>
580
+ </div>
581
+ </main>
582
+
583
+ <footer>
584
+ <div class="container">
585
+ <p>&copy; 2025 Mariam AI - Version expérimentale</p>
586
+ <div class="footer-links">
587
+ <a href="#">Conditions d'utilisation</a>
588
+ <a href="#">Confidentialité</a>
589
+ <a href="#">Contact</a>
590
+ </div>
591
+ </div>
592
+ </footer>
593
+
594
+ <script>
595
+ document.addEventListener('DOMContentLoaded', function() {
596
+ // Éléments DOM
597
+ const uploadArea = document.getElementById('upload-area');
598
+ const fileInput = document.getElementById('file-input');
599
+ const previewContainer = document.getElementById('preview-container');
600
+ const previewImage = document.getElementById('preview-image');
601
+ const processBtn = document.getElementById('process-btn');
602
+ const cancelBtn = document.getElementById('cancel-btn');
603
+ const latexCheck = document.getElementById('latex-check');
604
+ const apiCheck = document.getElementById('api-check');
605
+ const loader = document.getElementById('loader');
606
+ const loaderMessage = document.getElementById('loader-message');
607
+ const resultContainer = document.getElementById('result-container');
608
+ const pdfPreview = document.getElementById('pdf-preview');
609
+ const downloadBtn = document.getElementById('download-btn');
610
+ const latexCodeDisplay = document.getElementById('latex-code-display');
611
+ const thinkingProcessDisplay = document.getElementById('thinking-process-display');
612
+ const resultTabs = document.querySelectorAll('.result-tab');
613
+ const resultContents = document.querySelectorAll('.result-content');
614
+
615
+ // Variables globales
616
+ let selectedFile = null;
617
+
618
+ // Vérifications initiales
619
+ checkLatexInstallation();
620
+ checkApiConnection();
621
+
622
+ // Gestion des événements de glisser-déposer
623
+ uploadArea.addEventListener('dragover', function(e) {
624
+ e.preventDefault();
625
+ uploadArea.classList.add('drag-over');
626
+ });
627
+
628
+ uploadArea.addEventListener('dragleave', function() {
629
+ uploadArea.classList.remove('drag-over');
630
+ });
631
+
632
+ uploadArea.addEventListener('drop', function(e) {
633
+ e.preventDefault();
634
+ uploadArea.classList.remove('drag-over');
635
+
636
+ if (e.dataTransfer.files.length > 0) {
637
+ handleFileSelection(e.dataTransfer.files[0]);
638
+ }
639
+ });
640
+
641
+ // Gestion du clic sur le bouton de parcours
642
+ fileInput.addEventListener('change', function() {
643
+ if (fileInput.files.length > 0) {
644
+ handleFileSelection(fileInput.files[0]);
645
+ }
646
+ });
647
+
648
+ // Gestion du clic sur le bouton d'annulation
649
+ cancelBtn.addEventListener('click', function() {
650
+ resetUploadArea();
651
+ });
652
+
653
+ // Gestion du clic sur le bouton de traitement
654
+ processBtn.addEventListener('click', function() {
655
+ if (selectedFile) {
656
+ processImage(selectedFile);
657
+ }
658
+ });
659
+
660
+ // Gestion des onglets de résultat
661
+ resultTabs.forEach(tab => {
662
+ tab.addEventListener('click', function() {
663
+ const contentId = this.getAttribute('data-content');
664
+
665
+ // Désactiver tous les onglets et contenus
666
+ resultTabs.forEach(t => t.classList.remove('active'));
667
+ resultContents.forEach(c => c.classList.remove('active'));
668
+
669
+ // Activer l'onglet cliqué et son contenu
670
+ this.classList.add('active');
671
+ document.getElementById(contentId).classList.add('active');
672
+ });
673
+ });
674
+
675
+ // Fonctions
676
+ function checkLatexInstallation() {
677
+ fetch('/check_latex')
678
+ .then(response => response.json())
679
+ .then(data => {
680
+ latexCheck.classList.remove('loading');
681
+ if (data.success) {
682
+ latexCheck.classList.add('success');
683
+ latexCheck.innerHTML = `
684
+ <i class="fas fa-check-circle success-icon"></i>
685
+ <h3>LaTeX installé</h3>
686
+ <p>${data.message}</p>
687
+ `;
688
+ } else {
689
+ latexCheck.classList.add('error');
690
+ latexCheck.innerHTML = `
691
+ <i class="fas fa-exclamation-circle error-icon"></i>
692
+ <h3>LaTeX non détecté</h3>
693
+ <p>${data.message}</p>
694
+ `;
695
+ }
696
+ })
697
+ .catch(error => {
698
+ latexCheck.classList.remove('loading');
699
+ latexCheck.classList.add('error');
700
+ latexCheck.innerHTML = `
701
+ <i class="fas fa-exclamation-circle error-icon"></i>
702
+ <h3>Erreur de vérification</h3>
703
+ <p>Impossible de vérifier l'installation LaTeX.</p>
704
+ `;
705
+ });
706
+ }
707
+
708
+ function checkApiConnection() {
709
+ fetch('/check_api')
710
+ .then(response => response.json())
711
+ .then(data => {
712
+ apiCheck.classList.remove('loading');
713
+ if (data.success) {
714
+ apiCheck.classList.add('success');
715
+ apiCheck.innerHTML = `
716
+ <i class="fas fa-check-circle success-icon"></i>
717
+ <h3>API connectée</h3>
718
+ <p>${data.message}</p>
719
+ `;
720
+ } else {
721
+ apiCheck.classList.add('error');
722
+ apiCheck.innerHTML = `
723
+ <i class="fas fa-exclamation-circle error-icon"></i>
724
+ <h3>API non connectée</h3>
725
+ <p>${data.message}</p>
726
+ `;
727
+ }
728
+ })
729
+ .catch(error => {
730
+ apiCheck.classList.remove('loading');
731
+ apiCheck.classList.add('error');
732
+ apiCheck.innerHTML = `
733
+ <i class="fas fa-exclamation-circle error-icon"></i>
734
+ <h3>Erreur de connexion</h3>
735
+ <p>Impossible de vérifier la connexion à l'API.</p>
736
+ `;
737
+ });
738
+ }
739
+
740
+ function handleFileSelection(file) {
741
+ // Vérifier si c'est bien une image
742
+ if (!file.type.match('image.*')) {
743
+ showAlert('Veuillez sélectionner une image valide (JPEG, PNG, JPG).', 'error');
744
+ return;
745
+ }
746
+
747
+ // Stocker le fichier
748
+ selectedFile = file;
749
+
750
+ // Afficher l'aperçu
751
+ const reader = new FileReader();
752
+ reader.onload = function(e) {
753
+ previewImage.src = e.target.result;
754
+ previewContainer.style.display = 'block';
755
+ processBtn.disabled = false;
756
+ };
757
+ reader.readAsDataURL(file);
758
+ }
759
+
760
+ function resetUploadArea() {
761
+ selectedFile = null;
762
+ fileInput.value = '';
763
+ previewContainer.style.display = 'none';
764
+ previewImage.src = '';
765
+ processBtn.disabled = true;
766
+ }
767
+
768
+ function showAlert(message, type) {
769
+ // Créer l'alerte
770
+ const alertElement = document.createElement('div');
771
+ alertElement.className = `alert alert-${type}`;
772
+
773
+ // Ajouter l'icône en fonction du type
774
+ let icon = 'info-circle';
775
+ if (type === 'success') icon = 'check-circle';
776
+ if (type === 'error') icon = 'exclamation-circle';
777
+ if (type === 'warning') icon = 'exclamation-triangle';
778
+
779
+ alertElement.innerHTML = `
780
+ <i class="fas fa-${icon}"></i>
781
+ <span>${message}</span>
782
+ `;
783
+
784
+ // Insérer avant le conteneur d'upload
785
+ document.querySelector('.upload-container').insertAdjacentElement('beforebegin', alertElement);
786
+
787
+ // Supprimer après 5 secondes
788
+ setTimeout(() => {
789
+ alertElement.remove();
790
+ }, 5000);
791
+ }
792
+
793
+ function processImage(file) {
794
+ // Préparer les données
795
+ const formData = new FormData();
796
+ formData.append('image', file);
797
+
798
+ // Afficher le loader
799
+ uploadArea.style.display = 'none';
800
+ previewContainer.style.display = 'none';
801
+ loader.style.display = 'block';
802
+ resultContainer.style.display = 'none';
803
+
804
+ // Envoyer la requête
805
+ fetch('/process_image', {
806
+ method: 'POST',
807
+ body: formData
808
+ })
809
+ .then(response => response.json())
810
+ .then(data => {
811
+ // Cacher le loader
812
+ loader.style.display = 'none';
813
+
814
+ if (data.success) {
815
+ // Afficher le résultat
816
+ resultContainer.style.display = 'block';
817
+
818
+ // Afficher le PDF
819
+ pdfPreview.src = data.pdf_url;
820
+ downloadBtn.href = data.pdf_url;
821
+
822
+ // Afficher le code LaTeX
823
+ latexCodeDisplay.textContent = data.latex || 'Aucun code LaTeX disponible.';
824
+
825
+ // Afficher le processus de réflexion
826
+ thinkingProcessDisplay.textContent = data.thinking || 'Aucun processus de réflexion disponible.';
827
+
828
+ showAlert('Exercice résolu avec succès ! Vous pouvez maintenant télécharger la solution en PDF.', 'success');
829
+ } else {
830
+ // Afficher l'erreur
831
+ uploadArea.style.display = 'block';
832
+ showAlert(`Erreur : ${data.message}`, 'error');
833
+
834
+ // Si latex disponible mais pas de PDF, afficher quand même les résultats
835
+ if (data.latex) {
836
+ resultContainer.style.display = 'block';
837
+ latexCodeDisplay.textContent = data.latex;
838
+ thinkingProcessDisplay.textContent = data.thinking || 'Aucun processus de réflexion disponible.';
839
+
840
+ // Activer l'onglet LaTeX par défaut
841
+ resultTabs.forEach(t => t.classList.remove('active'));
842
+ resultContents.forEach(c => c.classList.remove('active'));
843
+ document.querySelector('[data-content="latex-content"]').classList.add('active');
844
+ document.getElementById('latex-content').classList.add('active');
845
+ }
846
+ }
847
+ })
848
+ .catch(error => {
849
+ // Cacher le loader et afficher l'erreur
850
+ loader.style.display = 'none';
851
+ uploadArea.style.display = 'block';
852
+ showAlert('Une erreur s\'est produite lors du traitement de l\'image.', 'error');
853
+ console.error('Erreur:', error);
854
+ });
855
+ }
856
+
857
+ // Rendre le bouton de parcours fonctionnel
858
+ uploadArea.querySelector('.btn').addEventListener('click', function(e) {
859
+ e.preventDefault();
860
+ fileInput.click();
861
+ });
862
+ });
863
+ </script>
864
+ </body>
865
+ </html>