Skip to content

feat(dashboard): add student performance & productivity dashboard (timer focus persistant, filtre période calendrier and…)#284

Open
brahim1818 wants to merge 2 commits into
Open-TutorAi:mainfrom
BrahimEssaadaoui:main
Open

feat(dashboard): add student performance & productivity dashboard (timer focus persistant, filtre période calendrier and…)#284
brahim1818 wants to merge 2 commits into
Open-TutorAi:mainfrom
BrahimEssaadaoui:main

Conversation

@brahim1818

Copy link
Copy Markdown

feat: Student Dashboard — Performance & Productivity

Description

Implements a unified student dashboard that merges academic performance
tracking with a productivity/focus workspace, as described in the
"Tableau de Bord Étudiant : Performance & Productivity" user story.

The dashboard is split into two tabs:

  • Performance: subject-level progress, completion rate gauge, and an
    activity calendar.
  • Productivity: Pomodoro focus timer, study streak, and daily study
    hours chart.

This gives students a single place to see both their academic progress
and their study habits, so they can better organize their work and stay
consistent.

Added

  • Statistics card: list of active subjects with a progress bar per
    subject, plus a "Support requests created per subject" breakdown
    (count of soutiens per matière).
  • Performance card: circular "Completion Rate" gauge (0–100%) with
    "Completed Tutorials" counter, points earned display, and a
    Monthly / Weekly period selector.
  • Monthly calendar with day markers for activity (sessions,
    homework, support requests) and previous/next month navigation.
  • Focus Mode: configurable Pomodoro timer (default 17 min work /
    1 min break, adjustable via +/− controls), circular countdown
    display, Work/Pause state indicator, pause/reset controls.
  • Productivity dashboard: daily study-hours bar chart (current
    week), streak counter (consecutive days with a completed session)
    with per-day indicators, and successful (completed) Pomodoro
    sessions counter.
  • Tabs to switch between Performance and Productivity views on the
    same dashboard page.

Changed

  • Reorganized the student dashboard layout to host both academic and
    productivity data in a single page via tab navigation, instead of
    separate views.

Additional Information

  • Frontend built with SvelteKit components, following existing
    OpenWebUI UI patterns.
  • Backend data (subject progress, completion rate, sessions, streak)
    is served via the FastAPI backend.

Screenshots or Videos

Productivity tab — Focus Mode, streak, and weekly study hours
Capture d’écran de 2026-07-03 23-47-06

Performance tab — Statistics by subject and support requests
Capture d’écran de 2026-07-03 23-49-17

Performance tab — Completion rate gauge and monthly calendar
Capture d’écran de 2026-07-03 23-49-28

Performance tab — Calendar navigation (activity markers)
Capture d’écran de 2026-07-03 23-49-36

… statistiques enrichies

- Timer Pomodoro global (store Svelte) qui continue même hors de l'onglet
  Productivité, avec redirection automatique et blocage sidebar en pause
- Mini badge timer visible dans la Navbar sur toutes les pages étudiantes
- Statistiques et jauge de performance filtrées dynamiquement par mois
  ou par semaine selon la sélection dans le calendrier
- Affichage du nombre de soutiens créés par matière et du total de points
@brahim1818 brahim1818 requested a review from pr-elhajji as a code owner July 3, 2026 22:59
@brahim1818 brahim1818 changed the title feat(dashboard): timer focus persistant, filtre période calendrier et… feat(dashboard): add student performance & productivity dashboard (timer focus persistant, filtre période calendrier and…) Jul 3, 2026
@Eziane

Eziane commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Salam @brahim1818
Thanks for the contribution! It looks promising,
Please resolve the merge conflicts so we can review it

@ayman-sabir

Copy link
Copy Markdown

📋 Backend Review — Request Changes 🔴

Solid, well-structured feature — the learning/dashboard/ layering is exactly right and I like how thin the router stays. Two things block merge, then it's close:

🔴 Must fix:

  1. Committed merge-conflict residuedata/models/__init__.py:6 and :13 are bare main lines. Python raises NameError at import, so the app won't start and every test errors at collection. Delete both lines. (The pre-commit hook missed it because the <<<</>>>> markers were already gone.)
  2. No tests — please add tests/test_dashboard.py (auth, ownership, focus-settings round-trip, streak aggregation, malformed start_date → 400).

🟠 Should fix:
3. Move the StudySession/FocusSettings writes out of the service into DashboardRepository — the repository is the commit boundary (service.py:104-143).
4. Add to_dict() to both new models.
5. Guard datetime.fromisoformat(start_date) → return 400, not 500 (service.py:29,75).
6. get_streak runs up to 365 queries and get_sessions_by_day 7 — collapse into grouped aggregates (repository.py:32-81).
7. Move hardcoded French labels/subjects to the frontend/i18n.

@pr-elhajji

Copy link
Copy Markdown
Contributor

Hi, thk for contuning dev.

@pr-elhajji

Copy link
Copy Markdown
Contributor

just the design style is note aligned woth opentutorai style
style is hardcoded

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements a unified Student Dashboard (Performance + Productivity) in the SvelteKit student area, backed by new FastAPI endpoints and persistence models for focus sessions and dashboard aggregates.

Changes:

  • Add a tabbed student dashboard UI with performance stats (subjects, completion gauge, activity calendar) and productivity widgets (Pomodoro focus timer, streak, weekly study hours).
  • Introduce a global, cross-page focus timer store + orchestrator to persist timer state and record completed focus sessions.
  • Add backend dashboard/focus APIs plus new SQLAlchemy models to store focus settings and study sessions.

Reviewed changes

Copilot reviewed 21 out of 24 changed files in this pull request and generated 12 comments.

Show a summary per file
File Description
ui/src/routes/student/+layout.svelte Mounts a global focus orchestrator component so the timer persists across student pages.
ui/src/lib/stores/focusTimer.ts Adds global Svelte stores + timer interval logic, events, and derived displays for focus mode.
ui/src/lib/components/student/pages/Dashboard.svelte Reworks the student dashboard into a tabbed Performance/Productivity layout and keeps support-request linkage logic.
ui/src/lib/components/student/elements/Sidebar.svelte Blocks navigation during break phase and shows a toast with remaining break time.
ui/src/lib/components/student/elements/Navbar.svelte Adds a mini focus timer pill that links back to the dashboard productivity tab.
ui/src/lib/components/student/dashboard/StudyHoursChart.svelte New SVG bar chart component for daily study hours.
ui/src/lib/components/student/dashboard/ProductivityTab.svelte New productivity tab with streak, sessions, weekly hours, chart, and focus timer widget.
ui/src/lib/components/student/dashboard/PerformanceTab.svelte New performance tab fetching stats/performance/calendar and handling monthly/weekly filtering.
ui/src/lib/components/student/dashboard/PerformanceGauge.svelte New semicircle gauge component for completion rate + points display.
ui/src/lib/components/student/dashboard/FocusTimer.svelte New Pomodoro UI wired to the global focusTimer store and focus settings API.
ui/src/lib/components/student/dashboard/FocusOrchestrator.svelte New invisible orchestrator that reacts to timer events, shows toasts, navigates, and records sessions.
ui/src/lib/components/student/dashboard/ActivityCalendar.svelte New monthly/weekly activity calendar with navigation and activity markers.
ui/src/lib/apis/focus/index.ts Adds frontend API client functions for focus sessions and focus settings.
ui/src/lib/apis/dashboard/index.ts Adds frontend API client functions for dashboard statistics/performance/calendar/productivity.
ui/src/app.d.ts Extends Window typing for the global event bus used for chat creation events.
ui/package-lock.json Updates lockfile metadata (version field).
learning/dashboard/service.py Adds dashboard service methods for statistics/performance/calendar/productivity and focus settings/session recording.
learning/dashboard/repository.py Adds repository queries/aggregations for study sessions, streaks, subject stats, and activity days.
learning/dashboard/init.py Initializes the new learning.dashboard module.
gateway/http/routers/dashboard.py Adds new /api/v1/dashboard/* and /api/v1/focus/* endpoints.
gateway/http/app.py Registers the new dashboard router under /api/v1.
data/models/study_session.py New ORM model to persist focus/work sessions.
data/models/focus_settings.py New ORM model to persist per-user focus timer settings.
data/models/init.py Registers the new ORM models for metadata/table creation.
Files not reviewed (1)
  • ui/package-lock.json: Generated file

Comment on lines +8 to +12
main
import { chatId as storeChatId, isDemo, demoData, user } from '$lib/stores';
import { dashboardTab } from '$lib/stores/focusTimer';
import { getSupportRequests, type SupportResponse, updateSupportChatId } from '$lib/apis/supports';

Comment on lines +133 to +137
if (!window.openTutorEvents) window.openTutorEvents = new EventTarget();
window.openTutorEvents.addEventListener('chatCreated', ((event: CustomEvent) => {
const newChatId = event.detail?.chatId;
if (newChatId && pendingSupportId) updateSupportWithChatId(pendingSupportId, newChatId);
}) as EventListener);
Comment on lines +344 to +348
const supportData = JSON.parse(pendingSupportData || '{}');
const attemptCount = (supportData.attempts || 0) + 1;
if (attemptCount >= 3) localStorage.removeItem('pendingSupportData');
else {
=======
Comment on lines 738 to 740
<label for="dontShow" class="text-xs text-gray-500 dark:text-gray-400"
>{$i18n.t("Don't show me again")}</label
>
Comment thread data/models/__init__.py
Comment on lines 5 to 10
from .knowledge import KnowledgeBase, KnowledgeFile
main
from .study_session import StudySession
from .focus_settings import FocusSettings

from .model import ModelConfig
Comment on lines +3 to +7
from datetime import datetime

from fastapi import APIRouter, Depends, Query
from pydantic import BaseModel
from sqlalchemy.orm import Session
Comment on lines +58 to +81
def get_streak(self, user_id: str) -> int:
"""Count consecutive days with at least one completed work session."""
streak = 0
now = datetime.utcnow()
for i in range(365):
day = now - timedelta(days=i)
start = day.replace(hour=0, minute=0, second=0, microsecond=0)
end = day.replace(hour=23, minute=59, second=59, microsecond=999999)
count = (
self.session.query(StudySession)
.filter(
StudySession.user_id == user_id,
StudySession.session_type == "work",
StudySession.completed.is_(True),
StudySession.created_at >= start,
StudySession.created_at <= end,
)
.count()
)
if count > 0:
streak += 1
elif i > 0:
break
return streak
Comment on lines +142 to +145
<button
on:click={prevMonth}
class="w-6 h-6 flex items-center justify-center rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-500 dark:text-gray-400 text-sm font-bold transition"
>‹</button>
Comment on lines +149 to +152
<button
on:click={nextMonth}
class="w-6 h-6 flex items-center justify-center rounded-full hover:bg-gray-100 dark:hover:bg-gray-700 text-gray-500 dark:text-gray-400 text-sm font-bold transition"
>›</button>
Comment on lines +24 to +33
@router.get("/dashboard/statistics")
def get_statistics(
year: int = Query(None),
month: int = Query(None),
start_date: str = Query(None),
current_user: User = Depends(get_current_user),
svc: DashboardService = Depends(_svc),
):
return svc.get_statistics(current_user.id, year, month, start_date)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants