Docfile commited on
Commit
6350fb6
·
verified ·
1 Parent(s): 03fe7bd

Update templates/math.html

Browse files
Files changed (1) hide show
  1. templates/math.html +128 -108
templates/math.html CHANGED
@@ -1,142 +1,162 @@
1
  <!DOCTYPE html>
2
- <html>
3
  <head>
4
- <title>Résolution de problème mathématique</title>
5
- <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML"></script>
6
- <script src="https://cdnjs.cloudflare.com/ajax/libs/plotly.js/2.24.2/plotly.min.js"></script>
7
  <script src="https://cdn.tailwindcss.com"></script>
 
 
8
  <style>
9
- @keyframes spin {
10
- to { transform: rotate(360deg); }
 
 
 
 
 
11
  }
12
- .animate-spin-slow {
13
- animation: spin 1.5s linear infinite;
 
 
 
14
  }
15
  </style>
16
  </head>
17
- <body class="bg-gray-50">
18
- <div class="min-h-screen bg-gradient-to-b from-blue-50 to-white">
19
- <div class="max-w-4xl mx-auto px-4 py-8">
20
- <!-- En-tête -->
21
- <div class="text-center mb-8">
22
- <h1 class="text-3xl font-bold text-blue-800 mb-2">Résolution de Problèmes Mathématiques</h1>
23
- <p class="text-gray-600">Soumettez une image de votre problème mathématique pour obtenir une solution détaillée</p>
24
- </div>
25
 
26
- <!-- Zone de téléchargement -->
27
- <div class="bg-white rounded-lg shadow-lg p-6 mb-8">
28
- <form id="uploadForm" class="space-y-4" enctype="multipart/form-data">
29
- <!-- Zone de drop -->
30
- <div class="border-2 border-dashed border-blue-300 rounded-lg p-8 text-center hover:border-blue-500 transition-colors">
31
- <div class="flex flex-col items-center">
32
- <div class="mb-4">
33
- <svg class="w-12 h-12 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
34
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z"/>
35
- </svg>
36
- </div>
37
- <label class="cursor-pointer">
38
- <span class="bg-blue-500 text-white px-4 py-2 rounded-lg hover:bg-blue-600 transition-colors">
39
- Sélectionner une image
40
- </span>
41
- <input type="file" id="imageInput" name="image" accept="image/*" class="hidden" onchange="previewImage(event)">
42
- </label>
43
  </div>
44
- <img id="preview" class="max-h-64 mx-auto mt-4 hidden rounded-lg">
45
- </div>
46
-
47
- <!-- Bouton d'analyse -->
48
- <div class="text-center">
49
- <button type="submit" class="bg-blue-600 text-white px-8 py-3 rounded-lg hover:bg-blue-700 transition-colors focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2">
50
- Analyser l'image
51
- </button>
52
- </div>
53
- </form>
54
-
55
- <!-- Loading spinner -->
56
- <div id="loading" class="hidden">
57
- <div class="flex items-center justify-center py-8">
58
- <div class="animate-spin-slow rounded-full h-16 w-16 border-4 border-blue-500 border-t-transparent"></div>
59
  </div>
60
- <p class="text-center text-gray-600">Analyse en cours... Veuillez patienter.</p>
61
  </div>
 
 
 
 
 
 
62
 
63
- <!-- Message d'erreur -->
64
- <div id="errorMessage" class="hidden mt-4 p-4 bg-red-50 text-red-700 rounded-lg">
65
- </div>
66
- </div>
 
67
 
68
- <!-- Zone de résultat -->
69
- <div class="result-container">
70
- <div id="result" class="bg-white rounded-lg shadow-lg p-6">
71
- <!-- Les résultats seront insérés ici -->
 
 
72
  </div>
73
  </div>
74
  </div>
75
  </div>
76
 
77
  <script>
78
- function previewImage(event) {
79
- const preview = document.getElementById('preview');
80
- const file = event.target.files[0];
81
- const reader = new FileReader();
 
 
 
82
 
83
- reader.onload = function() {
84
- preview.src = reader.result;
85
- preview.classList.remove('hidden');
86
- }
 
 
 
87
 
88
- if (file) {
89
- reader.readAsDataURL(file);
90
- }
91
- }
92
 
93
- document.getElementById('uploadForm').addEventListener('submit', function(e) {
94
- e.preventDefault();
95
-
96
- const formData = new FormData(this);
97
- const loading = document.getElementById('loading');
98
- const result = document.getElementById('result');
99
- const errorMessage = document.getElementById('errorMessage');
100
-
101
- // Afficher le loading
102
- loading.classList.remove('hidden');
103
- errorMessage.classList.add('hidden');
104
- result.innerHTML = '';
105
 
106
- fetch('/upload', {
107
- method: 'POST',
108
- body: formData
109
- })
110
- .then(response => response.json())
111
- .then(data => {
112
- loading.classList.add('hidden');
113
 
114
- if (data.error) {
115
- errorMessage.textContent = data.error;
116
- errorMessage.classList.remove('hidden');
117
- } else {
118
- // Injecter directement le HTML retourné par Gemini
119
- result.innerHTML = data.result;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
- // Recharger MathJax pour les nouvelles équations
122
  if (window.MathJax) {
123
- MathJax.Hub.Queue(["Typeset", MathJax.Hub, result]);
124
  }
125
 
126
- // Forcer le rafraîchissement des graphiques Plotly s'il y en a
127
- if (window.Plotly) {
128
- const plots = result.getElementsByClassName('plotly-graph-div');
129
- Array.from(plots).forEach(plot => {
130
- Plotly.relayout(plot, {});
131
- });
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  }
 
133
  }
134
- })
135
- .catch(error => {
136
- loading.classList.add('hidden');
137
- errorMessage.textContent = "Une erreur s'est produite lors de l'analyse.";
138
- errorMessage.classList.remove('hidden');
139
- console.error('Erreur:', error);
140
  });
141
  });
142
  </script>
 
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>Résolution de Problèmes Mathématiques</title>
7
  <script src="https://cdn.tailwindcss.com"></script>
8
+ <script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.7/MathJax.js?config=TeX-MML-AM_CHTML"></script>
9
+ <link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" rel="stylesheet">
10
  <style>
11
+ .dropzone {
12
+ border: 2px dashed #4F46E5;
13
+ transition: all 0.3s ease;
14
+ }
15
+ .dropzone:hover {
16
+ border-color: #312E81;
17
+ background-color: rgba(79, 70, 229, 0.1);
18
  }
19
+ .loading {
20
+ display: none;
21
+ }
22
+ .loading.active {
23
+ display: flex;
24
  }
25
  </style>
26
  </head>
27
+ <body class="min-h-screen bg-gradient-to-br from-blue-50 to-white">
28
+ <div class="container mx-auto px-4 py-8 max-w-4xl">
29
+ <!-- En-tête -->
30
+ <header class="text-center mb-12">
31
+ <h1 class="text-4xl font-bold text-blue-800 mb-4">Résolution de Problèmes Mathématiques</h1>
32
+ <p class="text-gray-600 text-lg">Soumettez une image de votre problème mathématique pour obtenir une solution détaillée</p>
33
+ </header>
 
34
 
35
+ <!-- Zone de dépôt d'image -->
36
+ <div class="mb-8">
37
+ <form id="uploadForm" class="space-y-4">
38
+ <div id="dropzone" class="dropzone rounded-lg p-8 text-center cursor-pointer">
39
+ <input type="file" id="fileInput" class="hidden" accept="image/*">
40
+ <div class="flex flex-col items-center space-y-4">
41
+ <i class="fas fa-cloud-upload-alt text-4xl text-blue-600"></i>
42
+ <div class="text-lg text-gray-700">
43
+ Glissez votre image ici ou <span class="text-blue-600 font-semibold">cliquez pour sélectionner</span>
 
 
 
 
 
 
 
 
44
  </div>
45
+ <p class="text-sm text-gray-500">Formats acceptés: PNG, JPG, JPEG</p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
  </div>
 
47
  </div>
48
+ <button type="submit" class="w-full md:w-auto px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white rounded-lg transition-colors duration-200 flex items-center justify-center space-x-2">
49
+ <i class="fas fa-paper-plane"></i>
50
+ <span>Analyser l'image</span>
51
+ </button>
52
+ </form>
53
+ </div>
54
 
55
+ <!-- Indicateur de chargement -->
56
+ <div id="loading" class="loading flex-col items-center justify-center space-y-4 my-8">
57
+ <div class="animate-spin rounded-full h-12 w-12 border-b-2 border-blue-600"></div>
58
+ <p class="text-gray-700">Analyse en cours...</p>
59
+ </div>
60
 
61
+ <!-- Zone de réponse -->
62
+ <div id="response" class="hidden">
63
+ <div class="bg-white rounded-lg shadow-lg p-6 mb-8">
64
+ <h2 class="text-2xl font-semibold text-blue-800 mb-4">Solution</h2>
65
+ <div id="latexContent" class="prose max-w-none">
66
+ <!-- Le contenu LaTeX sera inséré ici -->
67
  </div>
68
  </div>
69
  </div>
70
  </div>
71
 
72
  <script>
73
+ document.addEventListener('DOMContentLoaded', function() {
74
+ const dropzone = document.getElementById('dropzone');
75
+ const fileInput = document.getElementById('fileInput');
76
+ const uploadForm = document.getElementById('uploadForm');
77
+ const loading = document.getElementById('loading');
78
+ const response = document.getElementById('response');
79
+ const latexContent = document.getElementById('latexContent');
80
 
81
+ // Gestion du drag & drop
82
+ dropzone.addEventListener('click', () => fileInput.click());
83
+
84
+ dropzone.addEventListener('dragover', (e) => {
85
+ e.preventDefault();
86
+ dropzone.classList.add('bg-blue-50');
87
+ });
88
 
89
+ dropzone.addEventListener('dragleave', () => {
90
+ dropzone.classList.remove('bg-blue-50');
91
+ });
 
92
 
93
+ dropzone.addEventListener('drop', (e) => {
94
+ e.preventDefault();
95
+ dropzone.classList.remove('bg-blue-50');
96
+
97
+ if (e.dataTransfer.files.length) {
98
+ fileInput.files = e.dataTransfer.files;
99
+ const event = new Event('change');
100
+ fileInput.dispatchEvent(event);
101
+ }
102
+ });
 
 
103
 
104
+ // Gestion du formulaire
105
+ uploadForm.addEventListener('submit', async (e) => {
106
+ e.preventDefault();
 
 
 
 
107
 
108
+ const formData = new FormData();
109
+ formData.append('image', fileInput.files[0]);
110
+
111
+ try {
112
+ loading.classList.add('active');
113
+ response.classList.add('hidden');
114
+
115
+ const res = await fetch('/upload', {
116
+ method: 'POST',
117
+ body: formData
118
+ });
119
+
120
+ const data = await res.json();
121
+
122
+ if (data.error) {
123
+ throw new Error(data.error);
124
+ }
125
+
126
+ latexContent.innerHTML = data.result;
127
+ response.classList.remove('hidden');
128
 
129
+ // Rafraîchir le rendu LaTeX
130
  if (window.MathJax) {
131
+ MathJax.Hub.Queue(["Typeset", MathJax.Hub, latexContent]);
132
  }
133
 
134
+ } catch (error) {
135
+ alert('Erreur: ' + error.message);
136
+ } finally {
137
+ loading.classList.remove('active');
138
+ }
139
+ });
140
+
141
+ // Aperçu de l'image sélectionnée
142
+ fileInput.addEventListener('change', function() {
143
+ if (this.files && this.files[0]) {
144
+ const reader = new FileReader();
145
+ reader.onload = function(e) {
146
+ const preview = document.createElement('img');
147
+ preview.src = e.target.result;
148
+ preview.classList.add('max-h-48', 'mx-auto', 'mt-4', 'rounded-lg');
149
+
150
+ // Supprimer l'aperçu précédent s'il existe
151
+ const oldPreview = dropzone.querySelector('img');
152
+ if (oldPreview) {
153
+ oldPreview.remove();
154
+ }
155
+
156
+ dropzone.appendChild(preview);
157
  }
158
+ reader.readAsDataURL(this.files[0]);
159
  }
 
 
 
 
 
 
160
  });
161
  });
162
  </script>