hamba-ho commited on
Commit
654ec26
·
1 Parent(s): 236f475

Ajout des statistiques globales sur la page d'accueil

Browse files
backend/api/routes/questions.py CHANGED
@@ -5,6 +5,7 @@ from models.question import QuestionRequest, QuestionResponse
5
  from services.question_handler import QuestionHandler
6
 
7
  from models.interaction import InteractionLog
 
8
 
9
  router = APIRouter()
10
  handler = QuestionHandler()
@@ -30,6 +31,21 @@ def ask_question(request: QuestionRequest, db: Session = Depends(get_db)):
30
 
31
  return answer_data
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  @router.get("/stats/{session_id}")
34
  def get_stats(session_id: str, db: Session = Depends(get_db)):
35
  """
 
5
  from services.question_handler import QuestionHandler
6
 
7
  from models.interaction import InteractionLog
8
+ from models.document import Document
9
 
10
  router = APIRouter()
11
  handler = QuestionHandler()
 
31
 
32
  return answer_data
33
 
34
+ @router.get("/stats/global")
35
+ def get_global_stats(db: Session = Depends(get_db)):
36
+ """
37
+ Retourne les statistiques globales de toute la plateforme pour la page d'accueil.
38
+ """
39
+ total_sessions = db.query(Document.session_id).distinct().count()
40
+ total_documents = db.query(Document).count()
41
+ total_questions = db.query(InteractionLog).count()
42
+
43
+ return {
44
+ "total_sessions": total_sessions,
45
+ "total_documents": total_documents,
46
+ "total_questions": total_questions
47
+ }
48
+
49
  @router.get("/stats/{session_id}")
50
  def get_stats(session_id: str, db: Session = Depends(get_db)):
51
  """
frontend/app.js CHANGED
@@ -338,3 +338,38 @@ function escapeHtml(str) {
338
  .replace(/>/g, ">")
339
  .replace(/"/g, """);
340
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
  .replace(/>/g, ">")
339
  .replace(/"/g, """);
340
  }
341
+
342
+ function animateValue(id, start, end, duration) {
343
+ if (start === end) return;
344
+ const obj = document.getElementById(id);
345
+ let startTimestamp = null;
346
+ const step = (timestamp) => {
347
+ if (!startTimestamp) startTimestamp = timestamp;
348
+ const progress = Math.min((timestamp - startTimestamp) / duration, 1);
349
+ obj.innerHTML = Math.floor(progress * (end - start) + start);
350
+ if (progress < 1) {
351
+ window.requestAnimationFrame(step);
352
+ }
353
+ };
354
+ window.requestAnimationFrame(step);
355
+ }
356
+
357
+ async function loadGlobalStats() {
358
+ try {
359
+ const resp = await fetch(`${API_BASE}/stats/global`);
360
+ if (resp.ok) {
361
+ const data = await resp.json();
362
+ document.getElementById("global-stats").classList.remove("hidden");
363
+ animateValue("stat-sessions", 0, data.total_sessions, 1500);
364
+ animateValue("stat-docs", 0, data.total_documents, 1500);
365
+ animateValue("stat-questions", 0, data.total_questions, 1500);
366
+ }
367
+ } catch (e) {
368
+ console.error("Erreur stats globales", e);
369
+ }
370
+ }
371
+
372
+ // Initialisation au démarrage
373
+ document.addEventListener("DOMContentLoaded", () => {
374
+ loadGlobalStats();
375
+ });
frontend/index.html CHANGED
@@ -30,6 +30,21 @@
30
  Interrogez vos cours PDF en français ou en langue locale.<br />
31
  Réponses sourcées, fonctionne sur smartphone, sans connexion stable.
32
  </p>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  <div id="role-selection" class="role-cards">
34
  <button class="role-card" onclick="showTeacherLogin()">
35
  <div class="role-icon"></div>
 
30
  Interrogez vos cours PDF en français ou en langue locale.<br />
31
  Réponses sourcées, fonctionne sur smartphone, sans connexion stable.
32
  </p>
33
+ <div id="global-stats" class="global-stats hidden">
34
+ <div class="stat-item">
35
+ <div class="stat-value" id="stat-sessions">0</div>
36
+ <div class="stat-label">Cours Interactifs Créés</div>
37
+ </div>
38
+ <div class="stat-item">
39
+ <div class="stat-value" id="stat-docs">0</div>
40
+ <div class="stat-label">Ressources Indexées</div>
41
+ </div>
42
+ <div class="stat-item">
43
+ <div class="stat-value" id="stat-questions">0</div>
44
+ <div class="stat-label">Questions Résolues</div>
45
+ </div>
46
+ </div>
47
+
48
  <div id="role-selection" class="role-cards">
49
  <button class="role-card" onclick="showTeacherLogin()">
50
  <div class="role-icon"></div>
frontend/style.css CHANGED
@@ -525,3 +525,39 @@ body {
525
  .message-bubble { max-width: 92%; }
526
  .chat-header { padding: 16px; }
527
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
  .message-bubble { max-width: 92%; }
526
  .chat-header { padding: 16px; }
527
  }
528
+
529
+ /* ========== GLOBAL STATS ========== */
530
+ .global-stats {
531
+ display: flex;
532
+ justify-content: center;
533
+ gap: 32px;
534
+ background: rgba(255, 255, 255, 0.03);
535
+ border: 1px solid var(--border);
536
+ backdrop-filter: blur(10px);
537
+ border-radius: var(--radius);
538
+ padding: 16px 24px;
539
+ margin-bottom: 32px;
540
+ }
541
+ @media(max-width:640px) {
542
+ .global-stats { flex-direction: column; gap: 16px; padding: 16px; }
543
+ }
544
+ .stat-item {
545
+ display: flex;
546
+ flex-direction: column;
547
+ align-items: center;
548
+ text-align: center;
549
+ }
550
+ .stat-value {
551
+ font-size: 1.8rem;
552
+ font-weight: 800;
553
+ color: var(--accent-3);
554
+ margin-bottom: 4px;
555
+ font-variant-numeric: tabular-nums;
556
+ }
557
+ .stat-label {
558
+ font-size: 0.8rem;
559
+ text-transform: uppercase;
560
+ letter-spacing: 0.05em;
561
+ color: var(--text-muted);
562
+ font-weight: 600;
563
+ }