tfrere commited on
Commit
373381c
·
1 Parent(s): 8c61a14

add session clenaup and timeout messages

Browse files
backend/routes/__init__.py CHANGED
@@ -5,6 +5,7 @@ from .benchmark import router as benchmark_router, active_tasks
5
  from .questions import router as questions_router
6
  from .download import router as download_router
7
  from .evaluation import router as evaluation_router, active_evaluation_tasks
 
8
 
9
  # Exposer les routeurs
10
  routers = [
@@ -13,11 +14,13 @@ routers = [
13
  benchmark_router,
14
  questions_router,
15
  download_router,
16
- evaluation_router
 
17
  ]
18
 
19
  # Référencer les données partagées entre routes
20
  benchmark_router.session_files = session_files
 
21
 
22
  # Exposer les variables partagées pour main.py
23
  __all__ = ['routers', 'session_files', 'active_tasks', 'active_evaluation_tasks']
 
5
  from .questions import router as questions_router
6
  from .download import router as download_router
7
  from .evaluation import router as evaluation_router, active_evaluation_tasks
8
+ from .cleanup import router as cleanup_router
9
 
10
  # Exposer les routeurs
11
  routers = [
 
14
  benchmark_router,
15
  questions_router,
16
  download_router,
17
+ evaluation_router,
18
+ cleanup_router
19
  ]
20
 
21
  # Référencer les données partagées entre routes
22
  benchmark_router.session_files = session_files
23
+ cleanup_router.session_files = session_files
24
 
25
  # Exposer les variables partagées pour main.py
26
  __all__ = ['routers', 'session_files', 'active_tasks', 'active_evaluation_tasks']
backend/routes/cleanup.py ADDED
@@ -0,0 +1,58 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, HTTPException
2
+ import os
3
+ import shutil
4
+ from .upload import session_files
5
+
6
+ router = APIRouter(tags=["cleanup"])
7
+
8
+ # Dossier racine pour les uploads
9
+ UPLOAD_ROOT = "uploaded_files"
10
+
11
+ # Liste des documents de base qui ne doivent pas être supprimés
12
+ BASE_DOCUMENTS = ["the-bitter-lesson", "hurricane-faq", "pokemon-guide"]
13
+
14
+ @router.delete("/cleanup-session/{session_id}")
15
+ async def cleanup_session(session_id: str):
16
+ """
17
+ Supprime le dossier de session après que l'utilisateur a visualisé les résultats d'évaluation.
18
+ Ne supprime pas les documents de base.
19
+
20
+ Args:
21
+ session_id: ID de la session à supprimer
22
+
23
+ Returns:
24
+ Dictionary avec statut et message
25
+ """
26
+ # Vérifier si le session_id existe et n'est pas un document de base
27
+ if session_id in BASE_DOCUMENTS:
28
+ return {
29
+ "success": False,
30
+ "message": f"Cannot delete base document: {session_id}"
31
+ }
32
+
33
+ session_dir = os.path.join(UPLOAD_ROOT, session_id)
34
+
35
+ # Vérifier si le dossier existe
36
+ if not os.path.exists(session_dir):
37
+ return {
38
+ "success": False,
39
+ "message": f"Session directory not found: {session_id}"
40
+ }
41
+
42
+ try:
43
+ # Supprimer la référence du fichier de session
44
+ if session_id in session_files:
45
+ del session_files[session_id]
46
+
47
+ # Supprimer le dossier de session
48
+ shutil.rmtree(session_dir)
49
+
50
+ return {
51
+ "success": True,
52
+ "message": f"Session cleaned up successfully: {session_id}"
53
+ }
54
+ except Exception as e:
55
+ return {
56
+ "success": False,
57
+ "message": f"Error cleaning up session: {str(e)}"
58
+ }
frontend/server.js CHANGED
@@ -42,6 +42,7 @@ app.use(
42
  "/evaluation-logs",
43
  "/evaluation-results",
44
  "/download-dataset",
 
45
  ],
46
  createProxyMiddleware({
47
  target: backendUrl,
 
42
  "/evaluation-logs",
43
  "/evaluation-results",
44
  "/download-dataset",
45
+ "/cleanup-session",
46
  ],
47
  createProxyMiddleware({
48
  target: backendUrl,
frontend/src/components/BenchmarkEvaluation.jsx CHANGED
@@ -282,8 +282,35 @@ const BenchmarkEvaluation = ({ sessionId, isDefaultDocument, onComplete }) => {
282
  alignItems: "center",
283
  justifyContent: "center",
284
  minHeight: 200,
 
285
  }}
286
  >
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
287
  {error ? (
288
  <Alert severity="error" sx={{ width: "100%" }}>
289
  {error}
 
282
  alignItems: "center",
283
  justifyContent: "center",
284
  minHeight: 200,
285
+ position: "relative",
286
  }}
287
  >
288
+ {/* Temps estimé */}
289
+ <Box
290
+ sx={{
291
+ position: "absolute",
292
+ top: 12,
293
+ right: 12,
294
+ backgroundColor: "rgba(0, 0, 0, 0.04)",
295
+ borderRadius: "4px",
296
+ px: 1,
297
+ py: 0.5,
298
+ display: "inline-flex",
299
+ alignItems: "center",
300
+ }}
301
+ >
302
+ <Typography
303
+ variant="caption"
304
+ sx={{
305
+ fontSize: "0.675rem",
306
+ color: "text.secondary",
307
+ fontWeight: 500,
308
+ }}
309
+ >
310
+ Estimated time: ~1 min
311
+ </Typography>
312
+ </Box>
313
+
314
  {error ? (
315
  <Alert severity="error" sx={{ width: "100%" }}>
316
  {error}
frontend/src/components/BenchmarkGenerator.jsx CHANGED
@@ -86,12 +86,33 @@ const BenchmarkGenerator = ({ sessionId, isDefaultDocument, onComplete }) => {
86
  // Set start time
87
  startTimeRef.current = Date.now();
88
 
 
 
 
89
  // Start timer
90
  timerIntervalRef.current = setInterval(() => {
91
  const timeElapsed = Math.floor(
92
  (Date.now() - startTimeRef.current) / 1000
93
  );
94
  setElapsedTime(timeElapsed);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
95
  }, 1000);
96
 
97
  // Gestionnaire pour détecter quand la page redevient visible
@@ -483,8 +504,35 @@ const BenchmarkGenerator = ({ sessionId, isDefaultDocument, onComplete }) => {
483
  alignItems: "center",
484
  justifyContent: "center",
485
  minHeight: 200,
 
486
  }}
487
  >
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
488
  {error ? (
489
  <Alert severity="error" sx={{ width: "100%" }}>
490
  {error}
 
86
  // Set start time
87
  startTimeRef.current = Date.now();
88
 
89
+ // Référence pour le timeout
90
+ let timeoutRef = null;
91
+
92
  // Start timer
93
  timerIntervalRef.current = setInterval(() => {
94
  const timeElapsed = Math.floor(
95
  (Date.now() - startTimeRef.current) / 1000
96
  );
97
  setElapsedTime(timeElapsed);
98
+
99
+ // Vérifier si le temps écoulé dépasse 8 minutes (480 secondes) et que nous ne sommes pas en mode simulation
100
+ if (timeElapsed > 480 && !isDefault && !generationComplete) {
101
+ // Afficher un message d'erreur en cas de timeout
102
+ setError(
103
+ "The benchmark generation is taking too long. The demo is currently under heavy load, please try again later."
104
+ );
105
+ setGenerationComplete(true);
106
+
107
+ // Nettoyer les intervalles
108
+ if (pollingIntervalRef.current) {
109
+ clearInterval(pollingIntervalRef.current);
110
+ }
111
+
112
+ if (timerIntervalRef.current) {
113
+ clearInterval(timerIntervalRef.current);
114
+ }
115
+ }
116
  }, 1000);
117
 
118
  // Gestionnaire pour détecter quand la page redevient visible
 
504
  alignItems: "center",
505
  justifyContent: "center",
506
  minHeight: 200,
507
+ position: "relative",
508
  }}
509
  >
510
+ {/* Temps estimé */}
511
+ <Box
512
+ sx={{
513
+ position: "absolute",
514
+ top: 12,
515
+ right: 12,
516
+ backgroundColor: "rgba(0, 0, 0, 0.04)",
517
+ borderRadius: "4px",
518
+ px: 1,
519
+ py: 0.5,
520
+ display: "inline-flex",
521
+ alignItems: "center",
522
+ }}
523
+ >
524
+ <Typography
525
+ variant="caption"
526
+ sx={{
527
+ fontSize: "0.675rem",
528
+ color: "text.secondary",
529
+ fontWeight: 500,
530
+ }}
531
+ >
532
+ Estimated time: ~2 min
533
+ </Typography>
534
+ </Box>
535
+
536
  {error ? (
537
  <Alert severity="error" sx={{ width: "100%" }}>
538
  {error}
frontend/src/components/EvaluationDisplay.jsx CHANGED
@@ -85,47 +85,7 @@ const getMedalStyle = (rank) => {
85
  };
86
  };
87
 
88
- const EvaluationDisplay = ({ sessionId }) => {
89
- const [results, setResults] = useState(null);
90
- const [loading, setLoading] = useState(true);
91
- const [error, setError] = useState(null);
92
-
93
- useEffect(() => {
94
- const fetchEvaluationResults = async () => {
95
- if (!sessionId) {
96
- setError("No session ID provided");
97
- setLoading(false);
98
- return;
99
- }
100
-
101
- try {
102
- // Fetch evaluation results from the API
103
- const response = await fetch(
104
- `http://localhost:3001/evaluation-results/${sessionId}`
105
- );
106
-
107
- if (!response.ok) {
108
- throw new Error(`Failed to fetch results: ${response.status}`);
109
- }
110
-
111
- const data = await response.json();
112
-
113
- if (!data.success) {
114
- throw new Error(data.message || "Failed to fetch evaluation results");
115
- }
116
-
117
- setResults(data.results);
118
- } catch (err) {
119
- console.error("Error fetching evaluation results:", err);
120
- setError(err.message);
121
- } finally {
122
- setLoading(false);
123
- }
124
- };
125
-
126
- fetchEvaluationResults();
127
- }, [sessionId]);
128
-
129
  // Format accuracy as percentage
130
  const formatAccuracy = (value) => {
131
  return `${(value * 100).toFixed(2)}\u2009%`;
@@ -152,34 +112,6 @@ const EvaluationDisplay = ({ sessionId }) => {
152
  return `${seconds.toFixed(2)}s`;
153
  };
154
 
155
- if (loading) {
156
- return (
157
- <Box
158
- sx={{
159
- width: "100%",
160
- mt: 4,
161
- mb: 4,
162
- display: "flex",
163
- flexDirection: "column",
164
- alignItems: "center",
165
- }}
166
- >
167
- <Typography variant="h5" gutterBottom>
168
- Loading Evaluation Results...
169
- </Typography>
170
- <CircularProgress />
171
- </Box>
172
- );
173
- }
174
-
175
- if (error) {
176
- return (
177
- <Alert severity="error" sx={{ mt: 4, mb: 4 }}>
178
- {error}
179
- </Alert>
180
- );
181
- }
182
-
183
  if (
184
  !results ||
185
  !results.models_comparison ||
@@ -187,7 +119,21 @@ const EvaluationDisplay = ({ sessionId }) => {
187
  ) {
188
  return (
189
  <Alert severity="info" sx={{ mt: 4, mb: 4 }}>
190
- No evaluation results found for this benchmark.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
191
  </Alert>
192
  );
193
  }
@@ -241,98 +187,96 @@ const EvaluationDisplay = ({ sessionId }) => {
241
  </TableRow>
242
  </TableHead>
243
  <TableBody>
244
- {results.models_comparison
245
- .filter((model) => model.success)
246
- .map((model, index) => (
247
- <TableRow
248
- key={`${model.model_name}-${model.provider}`}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
249
  sx={{
250
- "&:nth-of-type(even)": {
251
- backgroundColor: "rgba(0, 0, 0, 0.02)",
252
- },
253
  }}
254
  >
255
- <TableCell>
256
- <Box sx={{ display: "flex", alignItems: "center" }}>
257
- <Box sx={getMedalStyle(index + 1)}>{index + 1}</Box>
258
- </Box>
259
- </TableCell>
260
- <TableCell component="th" scope="row">
261
- <Tooltip title={model.model_name} placement="top">
262
- <Link
263
- href={`https://huggingface.co/${model.model_name}`}
264
- target="_blank"
265
- rel="noopener noreferrer"
266
- sx={{
267
- textDecoration: "none",
268
- "&:hover": {
269
- textDecoration: "underline",
270
- },
271
- display: "flex",
272
- alignItems: "center",
273
- }}
274
- >
275
- {model.model_name.length > 40
276
- ? `${model.model_name.substring(0, 40)}...`
277
- : model.model_name}
278
- <OpenInNewIcon sx={{ ml: 0.5, fontSize: 16 }} />
279
- </Link>
280
- </Tooltip>
281
- </TableCell>
282
- <TableCell
283
- align="left"
284
  sx={{
285
- padding: 0,
286
- position: "relative",
287
- overflow: "hidden",
 
 
 
 
 
 
288
  }}
289
  >
290
  <Box
291
  sx={{
292
  position: "absolute",
293
- width: "100%",
294
- height: "100%",
295
  left: 0,
296
  top: 0,
297
- display: "flex",
298
- alignItems: "center",
299
- justifyContent: "flex-start",
300
- pl: 2,
 
 
 
 
 
 
 
 
 
 
301
  }}
302
  >
303
- <Box
304
- sx={{
305
- position: "absolute",
306
- left: 0,
307
- top: 0,
308
- height: "100%",
309
- width: `${model.accuracy * 100}%`,
310
- backgroundColor: getColorForScore(model.accuracy),
311
- opacity: 0.2,
312
- zIndex: 0,
313
- }}
314
- />
315
- <Typography
316
- sx={{
317
- position: "relative",
318
- zIndex: 1,
319
- fontWeight: model.accuracy > 0.7 ? "bold" : "normal",
320
- py: 1.5,
321
- textAlign: "left",
322
- }}
323
- >
324
- {formatAccuracy(model.accuracy)}
325
- </Typography>
326
- </Box>
327
- </TableCell>
328
- <TableCell align="left">
329
- {formatTime(model.evaluation_time)}
330
- </TableCell>
331
- <TableCell align="right">
332
- <span style={{ color: "green" }}>✓ Success</span>
333
- </TableCell>
334
- </TableRow>
335
- ))}
336
  </TableBody>
337
  </Table>
338
  </TableContainer>
 
85
  };
86
  };
87
 
88
+ const EvaluationDisplay = ({ sessionId, results }) => {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
  // Format accuracy as percentage
90
  const formatAccuracy = (value) => {
91
  return `${(value * 100).toFixed(2)}\u2009%`;
 
112
  return `${seconds.toFixed(2)}s`;
113
  };
114
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
115
  if (
116
  !results ||
117
  !results.models_comparison ||
 
119
  ) {
120
  return (
121
  <Alert severity="info" sx={{ mt: 4, mb: 4 }}>
122
+ No evaluation results found for this benchmark. The demo is currently
123
+ under heavy load, please try again later.
124
+ </Alert>
125
+ );
126
+ }
127
+
128
+ // Vérifier s'il n'y a aucun modèle réussi
129
+ const successfulModels = results.models_comparison.filter(
130
+ (model) => model.success
131
+ );
132
+ if (successfulModels.length === 0) {
133
+ return (
134
+ <Alert severity="warning" sx={{ mt: 4, mb: 4 }}>
135
+ All model evaluations failed. The demo is currently under heavy load,
136
+ please try again later.
137
  </Alert>
138
  );
139
  }
 
187
  </TableRow>
188
  </TableHead>
189
  <TableBody>
190
+ {successfulModels.map((model, index) => (
191
+ <TableRow
192
+ key={`${model.model_name}-${model.provider}`}
193
+ sx={{
194
+ "&:nth-of-type(even)": {
195
+ backgroundColor: "rgba(0, 0, 0, 0.02)",
196
+ },
197
+ }}
198
+ >
199
+ <TableCell>
200
+ <Box sx={{ display: "flex", alignItems: "center" }}>
201
+ <Box sx={getMedalStyle(index + 1)}>{index + 1}</Box>
202
+ </Box>
203
+ </TableCell>
204
+ <TableCell component="th" scope="row">
205
+ <Tooltip title={model.model_name} placement="top">
206
+ <Link
207
+ href={`https://huggingface.co/${model.model_name}`}
208
+ target="_blank"
209
+ rel="noopener noreferrer"
210
+ sx={{
211
+ textDecoration: "none",
212
+ "&:hover": {
213
+ textDecoration: "underline",
214
+ },
215
+ display: "flex",
216
+ alignItems: "center",
217
+ }}
218
+ >
219
+ {model.model_name.length > 40
220
+ ? `${model.model_name.substring(0, 40)}...`
221
+ : model.model_name}
222
+ <OpenInNewIcon sx={{ ml: 0.5, fontSize: 16 }} />
223
+ </Link>
224
+ </Tooltip>
225
+ </TableCell>
226
+ <TableCell
227
+ align="left"
228
  sx={{
229
+ padding: 0,
230
+ position: "relative",
231
+ overflow: "hidden",
232
  }}
233
  >
234
+ <Box
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
235
  sx={{
236
+ position: "absolute",
237
+ width: "100%",
238
+ height: "100%",
239
+ left: 0,
240
+ top: 0,
241
+ display: "flex",
242
+ alignItems: "center",
243
+ justifyContent: "flex-start",
244
+ pl: 2,
245
  }}
246
  >
247
  <Box
248
  sx={{
249
  position: "absolute",
 
 
250
  left: 0,
251
  top: 0,
252
+ height: "100%",
253
+ width: `${model.accuracy * 100}%`,
254
+ backgroundColor: getColorForScore(model.accuracy),
255
+ opacity: 0.2,
256
+ zIndex: 0,
257
+ }}
258
+ />
259
+ <Typography
260
+ sx={{
261
+ position: "relative",
262
+ zIndex: 1,
263
+ fontWeight: model.accuracy > 0.7 ? "bold" : "normal",
264
+ py: 1.5,
265
+ textAlign: "left",
266
  }}
267
  >
268
+ {formatAccuracy(model.accuracy)}
269
+ </Typography>
270
+ </Box>
271
+ </TableCell>
272
+ <TableCell align="left">
273
+ {formatTime(model.evaluation_time)}
274
+ </TableCell>
275
+ <TableCell align="right">
276
+ <span style={{ color: "green" }}>✓ Success</span>
277
+ </TableCell>
278
+ </TableRow>
279
+ ))}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
  </TableBody>
281
  </Table>
282
  </TableContainer>
frontend/src/pages/EvaluationDisplayPage.jsx CHANGED
@@ -1,19 +1,26 @@
1
  import React, { useState, useEffect } from "react";
2
- import { Box, CircularProgress } from "@mui/material";
3
  import { useSearchParams, Navigate } from "react-router-dom";
4
  import Intro from "../components/Intro";
5
  import EvaluationDisplay from "../components/EvaluationDisplay";
6
  import { useThemeMode } from "../hooks/useThemeMode";
7
  import getTheme from "../config/theme";
 
8
 
9
  function EvaluationDisplayPage() {
10
  const [searchParams] = useSearchParams();
11
  const sessionId = searchParams.get("session");
12
  const [isValidSession, setIsValidSession] = useState(true);
13
  const [isLoading, setIsLoading] = useState(true);
 
 
14
  const { mode } = useThemeMode();
15
  const theme = getTheme(mode);
16
 
 
 
 
 
17
  useEffect(() => {
18
  if (!sessionId) {
19
  console.log(
@@ -23,29 +30,88 @@ function EvaluationDisplayPage() {
23
  return;
24
  }
25
 
26
- const checkSession = async () => {
27
  try {
28
- const response = await fetch(
29
- `http://localhost:3001/benchmark-questions/${sessionId}`
 
30
  );
31
 
32
- if (!response.ok) {
33
  console.error(
34
- `Session invalide ou erreur serveur: ${response.status}`
35
  );
36
  setIsValidSession(false);
 
37
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
38
  } catch (error) {
39
- console.error("Erreur lors de la vérification de la session:", error);
40
- setIsValidSession(false);
41
  } finally {
42
  setIsLoading(false);
43
  }
44
  };
45
 
46
- checkSession();
47
  }, [sessionId]);
48
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  if (!isValidSession) {
50
  return <Navigate to="/" />;
51
  }
@@ -65,6 +131,10 @@ function EvaluationDisplayPage() {
65
  >
66
  <CircularProgress size={60} />
67
  </Box>
 
 
 
 
68
  ) : (
69
  <Box
70
  sx={{
@@ -74,7 +144,10 @@ function EvaluationDisplayPage() {
74
  bgcolor: "background.paper",
75
  }}
76
  >
77
- <EvaluationDisplay sessionId={sessionId} />
 
 
 
78
  </Box>
79
  )}
80
  </>
 
1
  import React, { useState, useEffect } from "react";
2
+ import { Box, CircularProgress, Alert } from "@mui/material";
3
  import { useSearchParams, Navigate } from "react-router-dom";
4
  import Intro from "../components/Intro";
5
  import EvaluationDisplay from "../components/EvaluationDisplay";
6
  import { useThemeMode } from "../hooks/useThemeMode";
7
  import getTheme from "../config/theme";
8
+ import API_CONFIG from "../config/api";
9
 
10
  function EvaluationDisplayPage() {
11
  const [searchParams] = useSearchParams();
12
  const sessionId = searchParams.get("session");
13
  const [isValidSession, setIsValidSession] = useState(true);
14
  const [isLoading, setIsLoading] = useState(true);
15
+ const [evaluationResults, setEvaluationResults] = useState(null);
16
+ const [error, setError] = useState(null);
17
  const { mode } = useThemeMode();
18
  const theme = getTheme(mode);
19
 
20
+ // Liste des documents de base qui ne doivent pas être supprimés
21
+ const baseDocuments = ["the-bitter-lesson", "hurricane-faq", "pokemon-guide"];
22
+ const isBaseDocument = baseDocuments.includes(sessionId);
23
+
24
  useEffect(() => {
25
  if (!sessionId) {
26
  console.log(
 
30
  return;
31
  }
32
 
33
+ const fetchEvaluationResults = async () => {
34
  try {
35
+ // Vérifier d'abord si la session existe
36
+ const sessionCheckResponse = await fetch(
37
+ `${API_CONFIG.BASE_URL}/benchmark-questions/${sessionId}`
38
  );
39
 
40
+ if (!sessionCheckResponse.ok) {
41
  console.error(
42
+ `Session invalide ou erreur serveur: ${sessionCheckResponse.status}`
43
  );
44
  setIsValidSession(false);
45
+ return;
46
  }
47
+
48
+ // Récupérer les résultats d'évaluation
49
+ const evalResponse = await fetch(
50
+ `${API_CONFIG.BASE_URL}/evaluation-results/${sessionId}`
51
+ );
52
+
53
+ if (!evalResponse.ok) {
54
+ setError(`Failed to fetch results: ${evalResponse.status}`);
55
+ setIsLoading(false);
56
+ return;
57
+ }
58
+
59
+ const data = await evalResponse.json();
60
+
61
+ if (!data.success) {
62
+ setError(data.message || "Failed to fetch evaluation results");
63
+ setIsLoading(false);
64
+ return;
65
+ }
66
+
67
+ setEvaluationResults(data.results);
68
  } catch (error) {
69
+ console.error("Error fetching evaluation results:", error);
70
+ setError(error.message);
71
  } finally {
72
  setIsLoading(false);
73
  }
74
  };
75
 
76
+ fetchEvaluationResults();
77
  }, [sessionId]);
78
 
79
+ // Effet pour nettoyer le dossier de session après avoir affiché les résultats
80
+ useEffect(() => {
81
+ // Ne pas nettoyer si c'est un document de base ou si les résultats ne sont pas encore chargés
82
+ if (isBaseDocument || isLoading || !evaluationResults) {
83
+ return;
84
+ }
85
+
86
+ // Fonction pour supprimer le dossier de session
87
+ const cleanupSession = async () => {
88
+ try {
89
+ const response = await fetch(
90
+ `${API_CONFIG.BASE_URL}/cleanup-session/${sessionId}`,
91
+ {
92
+ method: "DELETE",
93
+ }
94
+ );
95
+
96
+ if (response.ok) {
97
+ console.log(`Session ${sessionId} cleaned up successfully`);
98
+ } else {
99
+ console.warn(`Failed to clean up session ${sessionId}`);
100
+ }
101
+ } catch (error) {
102
+ console.error("Error cleaning up session:", error);
103
+ }
104
+ };
105
+
106
+ // Appeler la fonction après un délai pour s'assurer que l'utilisateur a eu le temps de voir les résultats
107
+ const cleanupTimeout = setTimeout(() => {
108
+ cleanupSession();
109
+ }, 2000);
110
+
111
+ // Nettoyer le timeout si le composant est démonté
112
+ return () => clearTimeout(cleanupTimeout);
113
+ }, [sessionId, isBaseDocument, isLoading, evaluationResults]);
114
+
115
  if (!isValidSession) {
116
  return <Navigate to="/" />;
117
  }
 
131
  >
132
  <CircularProgress size={60} />
133
  </Box>
134
+ ) : error ? (
135
+ <Alert severity="error" sx={{ mt: 4, mb: 4 }}>
136
+ {error}
137
+ </Alert>
138
  ) : (
139
  <Box
140
  sx={{
 
144
  bgcolor: "background.paper",
145
  }}
146
  >
147
+ <EvaluationDisplay
148
+ sessionId={sessionId}
149
+ results={evaluationResults}
150
+ />
151
  </Box>
152
  )}
153
  </>