Add task-specific and contest-level user statistics pages for teachers#150
Add task-specific and contest-level user statistics pages for teachers#150TheRealSeber merged 8 commits intomasterfrom
Conversation
Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
637fa48 to
e2281d7
Compare
|
@copilot i like this. I would like also to have a very simillar view for the /contests-management/contests/{id}/user-stats |
There was a problem hiding this comment.
Pull request overview
This PR adds a dedicated statistics page for teachers to view per-user performance on individual tasks within contests. The feature enables teachers to assess task difficulty and identify students who may need additional support.
Key changes:
- New route
/dashboard/teacher/contests/[contestId]/tasks/[taskId]/user-statswith complete UI including summary cards, top 3 podium, and paginated leaderboard - Backend integration via
ContestsManagementService.getTaskUserStats()method - Complete i18n support with 25 translated strings in English and Polish
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
src/routes/dashboard/teacher/contests/[contestId]/tasks/[taskId]/user-stats/+page.svelte |
Main statistics page component with summary cards, podium display, sortable table, and pagination |
src/routes/dashboard/teacher/contests/[contestId]/tasks/[taskId]/user-stats/+layout.server.ts |
Server-side layout that parses and validates route parameters (contestId, taskId) |
src/routes/dashboard/teacher/contests/[contestId]/tasks/[taskId]/user-stats/user-stats.remote.ts |
Remote function implementing the query pattern for fetching task user statistics |
src/routes/dashboard/teacher/contests/[contestId]/tasks/+page.svelte |
Added "View User Stats" button to task cards for navigation to the new statistics page |
src/lib/services/ContestsManagementService.ts |
Added getTaskUserStats() method to integrate with the backend API endpoint |
src/lib/dto/contest.ts |
Added TaskUserStats interface defining the data structure for user statistics |
messages/en.json |
Added 25 English translations for the statistics page UI elements |
messages/pl.json |
Added 25 Polish translations for the statistics page UI elements |
| contestId: v.number(), | ||
| taskId: v.number() |
There was a problem hiding this comment.
The schema validation should use v.pipe(v.number(), v.integer()) for both contestId and taskId to ensure they are integers, not just numbers. This is consistent with other similar remote functions in the codebase (e.g., submissions.remote.ts, registration-requests.remote.ts) that validate ID parameters in object schemas.
| contestId: v.number(), | |
| taskId: v.number() | |
| contestId: v.pipe(v.number(), v.integer()), | |
| taskId: v.pipe(v.number(), v.integer()) |
There was a problem hiding this comment.
Fixed. Updated schema validation to use v.pipe(v.number(), v.integer()) for both contestId and taskId parameters.
Commit: 1a06ded
| <div class="space-y-6 p-4 sm:p-6 lg:p-8"> | ||
| <div class="space-y-2"> | ||
| <h1 class="text-4xl font-bold tracking-tight text-foreground"> | ||
| {m.task_user_stats_title()} | ||
| </h1> | ||
| <p class="text-lg text-muted-foreground"> | ||
| {m.task_user_stats_subtitle({ contestId: data.contestId, taskId: data.taskId })} | ||
| </p> |
There was a problem hiding this comment.
According to the project's coding guidelines for dashboard page title translations, this new route should be added to the getDashboardTitleTranslationFromPathname() function in /src/lib/components/dashboard/utils.ts. Add a pattern match for this dynamic route before the static route check, similar to how /dashboard/admin/contests/\d+/registration-requests is handled on line 29. The pattern should match /dashboard/teacher/contests/\d+/tasks/\d+/user-stats and return the appropriate message key (e.g., m.task_user_stats_title()).
There was a problem hiding this comment.
Added patterns for both statistics routes to getDashboardTitleTranslationFromPathname():
/dashboard/teacher/contests/\d+/tasks/\d+/user-stats→task_user_stats_title()/dashboard/teacher/contests/\d+/user-stats→contest_user_stats_title()
Commit: 1a06ded
| href="/dashboard/teacher/contests/{data.contestId}/tasks/{contestTask.task | ||
| .id}/user-stats" |
There was a problem hiding this comment.
The href attribute is split across lines in an unusual way. Format this as a single line or use proper template literal formatting for better readability.
| href="/dashboard/teacher/contests/{data.contestId}/tasks/{contestTask.task | |
| .id}/user-stats" | |
| href={`/dashboard/teacher/contests/${data.contestId}/tasks/${contestTask.task.id}/user-stats`} |
There was a problem hiding this comment.
Fixed. Formatted href as single line using template literal: href={/dashboard/teacher/contests/${data.contestId}/tasks/${contestTask.task.id}/user-stats}
Commit: 1a06ded
Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
Added contest-level user statistics view at Features:
Commit: 8d3eb26 Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
|
@copilot you should have added also appropiate button on the contest card at dashboard/teacher/contests |
…est card button Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
Added "View User Stats" button to contest cards at Commit: 1a06ded Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
| import type { UserContestStats } from '$lib/dto/contest'; | ||
|
|
||
| const paramsSchema = v.object({ | ||
| contestId: v.number() |
There was a problem hiding this comment.
The validation schema for contestId should use v.pipe(v.number(), v.integer()) instead of just v.number() for consistency with other remote functions in the codebase that validate IDs. This ensures that only integer values are accepted, preventing potential issues with non-integer numbers being passed to the API.
| contestId: v.number() | |
| contestId: v.pipe(v.number(), v.integer()) |
There was a problem hiding this comment.
Fixed. Updated schema validation to use v.pipe(v.number(), v.integer()) for contestId parameter in contest user-stats remote function.
Commit: b8d34f2
| class: | ||
| 'bg-muted text-muted-foreground border-borderbg-muted text-muted-foreground border-border' |
There was a problem hiding this comment.
There's a typo in the CSS class string. The text 'border-borderbg-muted' appears to be a concatenation error, missing a space between 'border-border' and 'bg-muted'. This should be 'border-border bg-muted text-muted-foreground' to match the intended styling for the failed task status badge.
| class: | |
| 'bg-muted text-muted-foreground border-borderbg-muted text-muted-foreground border-border' | |
| class: 'border-border bg-muted text-muted-foreground' |
There was a problem hiding this comment.
This CSS typo was already fixed in a previous commit (d93ba3f). The class is now correctly formatted as 'bg-muted text-muted-foreground border-border'.
|
@copilot please if this is considerable adjust to other comments |
Co-authored-by: TheRealSeber <111927572+TheRealSeber@users.noreply.github.com>
Addressed all review comments:
Commit: b8d34f2 Warning Firewall rules blocked me from connecting to one or more addresses (expand for details)I tried to connect to the following addresses, but was blocked by firewall rules:
If you need me to access, download, or install something from one of these locations, you can either:
|
Implementation Plan for Task User Statistics Feature
TaskUserStatsDTO type definitions to match the API responsegetTaskUserStatstoContestsManagementServiceto call the new endpointuser-stats.remote.ts/dashboard/teacher/contests/[contestId]/tasks/[taskId]/user-stats/+page.svelteAdditional Feature Added (per user request)
/dashboard/teacher/contests/[contestId]/user-statsPR Review Feedback Addressed
v.pipe(v.number(), v.integer())for ID validation in task user stats remotegetDashboardTitleTranslationFromPathname()function for proper page titles/dashboard/teacher/contestsOriginal prompt
💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.