Spaces:
Running
Running
Update templates/index.html
Browse files- templates/index.html +100 -22
templates/index.html
CHANGED
@@ -77,6 +77,20 @@
|
|
77 |
from { text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #60A5FA; }
|
78 |
to { text-shadow: 0 0 20px #fff, 0 0 30px #4F46E5, 0 0 40px #4F46E5; }
|
79 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
</style>
|
81 |
</head>
|
82 |
<body class="p-4 md:p-8">
|
@@ -87,10 +101,10 @@
|
|
87 |
<p class="text-blue-200 text-lg">Solution Mathématique Intelligente</p>
|
88 |
</div>
|
89 |
|
90 |
-
<form id="problemForm" class="space-y-8">
|
91 |
<div class="relative">
|
92 |
<div class="uploadArea rounded-2xl p-12 text-center transition-all duration-300 cursor-pointer">
|
93 |
-
<input type="file" id="imageInput" accept="image/*" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer">
|
94 |
<div class="space-y-4">
|
95 |
<div class="w-20 h-20 mx-auto border-2 border-blue-400 rounded-full flex items-center justify-center">
|
96 |
<svg class="w-10 h-10 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
@@ -101,6 +115,9 @@
|
|
101 |
<div class="text-blue-300/60 text-sm">ou cliquez pour sélectionner</div>
|
102 |
</div>
|
103 |
</div>
|
|
|
|
|
|
|
104 |
</div>
|
105 |
|
106 |
<button type="submit" class="neon-button w-full py-4 rounded-xl text-white font-medium text-lg transition-all duration-300">
|
@@ -141,11 +158,13 @@
|
|
141 |
const form = document.getElementById('problemForm');
|
142 |
const imageInput = document.getElementById('imageInput');
|
143 |
const loader = document.getElementById('loader');
|
144 |
-
const
|
145 |
const thoughtsContent = document.getElementById('thoughtsContent');
|
146 |
const answerContent = document.getElementById('answerContent');
|
147 |
const thoughtsToggle = document.getElementById('thoughtsToggle');
|
148 |
const thoughtsBox = document.getElementById('thoughtsBox');
|
|
|
|
|
149 |
|
150 |
thoughtsToggle.addEventListener('click', () => {
|
151 |
thoughtsBox.classList.toggle('open');
|
@@ -153,16 +172,23 @@
|
|
153 |
});
|
154 |
|
155 |
imageInput.addEventListener('change', function(e) {
|
156 |
-
const
|
157 |
-
if (
|
158 |
-
const
|
159 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
160 |
}
|
161 |
});
|
162 |
|
163 |
// Drag and drop effects
|
164 |
const dropZone = document.querySelector('.uploadArea');
|
165 |
-
|
166 |
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
167 |
dropZone.addEventListener(eventName, preventDefaults, false);
|
168 |
});
|
@@ -188,6 +214,24 @@
|
|
188 |
dropZone.classList.remove('border-blue-400');
|
189 |
}
|
190 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
191 |
form.addEventListener('submit', async (event) => {
|
192 |
event.preventDefault();
|
193 |
const file = imageInput.files[0];
|
@@ -197,7 +241,9 @@
|
|
197 |
}
|
198 |
|
199 |
loader.classList.remove('hidden');
|
200 |
-
|
|
|
|
|
201 |
|
202 |
const formData = new FormData();
|
203 |
formData.append('image', file);
|
@@ -207,24 +253,56 @@
|
|
207 |
method: 'POST',
|
208 |
body: formData,
|
209 |
});
|
210 |
-
|
|
|
|
|
|
|
211 |
|
212 |
-
|
213 |
-
|
214 |
-
|
215 |
-
|
216 |
-
|
217 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
218 |
}
|
|
|
219 |
|
220 |
-
|
221 |
-
|
222 |
-
} else {
|
223 |
-
throw new Error(data.error || 'Une erreur est survenue');
|
224 |
}
|
|
|
|
|
|
|
|
|
225 |
} catch (error) {
|
226 |
-
console.error('
|
227 |
-
alert(
|
228 |
loader.classList.add('hidden');
|
229 |
}
|
230 |
});
|
|
|
77 |
from { text-shadow: 0 0 10px #fff, 0 0 20px #fff, 0 0 30px #60A5FA; }
|
78 |
to { text-shadow: 0 0 20px #fff, 0 0 30px #4F46E5, 0 0 40px #4F46E5; }
|
79 |
}
|
80 |
+
|
81 |
+
.preview-container {
|
82 |
+
display: flex;
|
83 |
+
justify-content: center;
|
84 |
+
align-items: center;
|
85 |
+
margin-top: 20px;
|
86 |
+
}
|
87 |
+
|
88 |
+
.preview-image {
|
89 |
+
max-width: 300px;
|
90 |
+
max-height: 300px;
|
91 |
+
border-radius: 8px;
|
92 |
+
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
93 |
+
}
|
94 |
</style>
|
95 |
</head>
|
96 |
<body class="p-4 md:p-8">
|
|
|
101 |
<p class="text-blue-200 text-lg">Solution Mathématique Intelligente</p>
|
102 |
</div>
|
103 |
|
104 |
+
<form id="problemForm" class="space-y-8" enctype="multipart/form-data">
|
105 |
<div class="relative">
|
106 |
<div class="uploadArea rounded-2xl p-12 text-center transition-all duration-300 cursor-pointer">
|
107 |
+
<input type="file" id="imageInput" name="image" accept="image/*" class="absolute inset-0 w-full h-full opacity-0 cursor-pointer">
|
108 |
<div class="space-y-4">
|
109 |
<div class="w-20 h-20 mx-auto border-2 border-blue-400 rounded-full flex items-center justify-center">
|
110 |
<svg class="w-10 h-10 text-blue-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
|
|
|
115 |
<div class="text-blue-300/60 text-sm">ou cliquez pour sélectionner</div>
|
116 |
</div>
|
117 |
</div>
|
118 |
+
<div id="imagePreview" class="preview-container hidden">
|
119 |
+
<img id="previewImage" src="#" alt="Prévisualisation de l'image" class="preview-image">
|
120 |
+
</div>
|
121 |
</div>
|
122 |
|
123 |
<button type="submit" class="neon-button w-full py-4 rounded-xl text-white font-medium text-lg transition-all duration-300">
|
|
|
158 |
const form = document.getElementById('problemForm');
|
159 |
const imageInput = document.getElementById('imageInput');
|
160 |
const loader = document.getElementById('loader');
|
161 |
+
const solutionDiv = document.getElementById('solution');
|
162 |
const thoughtsContent = document.getElementById('thoughtsContent');
|
163 |
const answerContent = document.getElementById('answerContent');
|
164 |
const thoughtsToggle = document.getElementById('thoughtsToggle');
|
165 |
const thoughtsBox = document.getElementById('thoughtsBox');
|
166 |
+
const imagePreview = document.getElementById('imagePreview');
|
167 |
+
const previewImage = document.getElementById('previewImage');
|
168 |
|
169 |
thoughtsToggle.addEventListener('click', () => {
|
170 |
thoughtsBox.classList.toggle('open');
|
|
|
172 |
});
|
173 |
|
174 |
imageInput.addEventListener('change', function(e) {
|
175 |
+
const file = this.files[0];
|
176 |
+
if (file) {
|
177 |
+
const reader = new FileReader();
|
178 |
+
reader.onload = function(e) {
|
179 |
+
previewImage.src = e.target.result;
|
180 |
+
imagePreview.classList.remove('hidden');
|
181 |
+
}
|
182 |
+
reader.readAsDataURL(file);
|
183 |
+
} else {
|
184 |
+
previewImage.src = "";
|
185 |
+
imagePreview.classList.add('hidden');
|
186 |
}
|
187 |
});
|
188 |
|
189 |
// Drag and drop effects
|
190 |
const dropZone = document.querySelector('.uploadArea');
|
191 |
+
|
192 |
['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
193 |
dropZone.addEventListener(eventName, preventDefaults, false);
|
194 |
});
|
|
|
214 |
dropZone.classList.remove('border-blue-400');
|
215 |
}
|
216 |
|
217 |
+
dropZone.addEventListener('drop', handleDrop, false);
|
218 |
+
|
219 |
+
function handleDrop(e) {
|
220 |
+
let dt = e.dataTransfer;
|
221 |
+
let files = dt.files;
|
222 |
+
|
223 |
+
if (files.length) {
|
224 |
+
imageInput.files = files;
|
225 |
+
const file = files[0];
|
226 |
+
const reader = new FileReader();
|
227 |
+
reader.onload = function(e) {
|
228 |
+
previewImage.src = e.target.result;
|
229 |
+
imagePreview.classList.remove('hidden');
|
230 |
+
}
|
231 |
+
reader.readAsDataURL(file);
|
232 |
+
}
|
233 |
+
}
|
234 |
+
|
235 |
form.addEventListener('submit', async (event) => {
|
236 |
event.preventDefault();
|
237 |
const file = imageInput.files[0];
|
|
|
241 |
}
|
242 |
|
243 |
loader.classList.remove('hidden');
|
244 |
+
solutionDiv.classList.add('hidden');
|
245 |
+
thoughtsContent.innerHTML = '';
|
246 |
+
answerContent.innerHTML = '';
|
247 |
|
248 |
const formData = new FormData();
|
249 |
formData.append('image', file);
|
|
|
253 |
method: 'POST',
|
254 |
body: formData,
|
255 |
});
|
256 |
+
|
257 |
+
if (!response.ok) {
|
258 |
+
throw new Error('Erreur lors de la requête.');
|
259 |
+
}
|
260 |
|
261 |
+
const reader = response.body.getReader();
|
262 |
+
const decoder = new TextDecoder();
|
263 |
+
let buffer = '';
|
264 |
+
|
265 |
+
while (true) {
|
266 |
+
const { done, value } = await reader.read();
|
267 |
+
if (done) break;
|
268 |
+
|
269 |
+
buffer += decoder.decode(value, { stream: true });
|
270 |
+
let eolIndex;
|
271 |
+
|
272 |
+
while ((eolIndex = buffer.indexOf('\n\n')) >= 0) {
|
273 |
+
const line = buffer.slice(0, eolIndex).trim();
|
274 |
+
buffer = buffer.slice(eolIndex + 2);
|
275 |
+
|
276 |
+
if (line.startsWith('data:')) {
|
277 |
+
const jsonData = line.substring(5);
|
278 |
+
try {
|
279 |
+
const data = JSON.parse(jsonData);
|
280 |
+
if (data.thought) {
|
281 |
+
thoughtsContent.innerHTML += data.thought;
|
282 |
+
} else if (data.answer) {
|
283 |
+
answerContent.innerHTML += data.answer;
|
284 |
+
}
|
285 |
+
|
286 |
+
if (window.MathJax) {
|
287 |
+
MathJax.Hub.Queue(["Typeset", MathJax.Hub, answerContent]);
|
288 |
+
}
|
289 |
+
} catch (error) {
|
290 |
+
console.error('Erreur lors du parsing JSON:', error);
|
291 |
+
}
|
292 |
+
}
|
293 |
}
|
294 |
+
}
|
295 |
|
296 |
+
if (window.MathJax) {
|
297 |
+
MathJax.Hub.Queue(["Typeset", MathJax.Hub]);
|
|
|
|
|
298 |
}
|
299 |
+
|
300 |
+
loader.classList.add('hidden');
|
301 |
+
solutionDiv.classList.remove('hidden');
|
302 |
+
|
303 |
} catch (error) {
|
304 |
+
console.error('Erreur:', error);
|
305 |
+
alert('Une erreur est survenue lors du traitement de la requête.');
|
306 |
loader.classList.add('hidden');
|
307 |
}
|
308 |
});
|