-
Notifications
You must be signed in to change notification settings - Fork 0
Add task-specific and contest-level user statistics pages for teachers #150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
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.
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 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() |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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> |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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" |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
| import type { UserContestStats } from '$lib/dto/contest'; | ||
|
|
||
| const paramsSchema = v.object({ | ||
| contestId: v.number() |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fixed. Updated schema validation to use v.pipe(v.number(), v.integer()) for contestId parameter in contest user-stats remote function.
Commit: b8d34f2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
Copilot reviewed 13 out of 13 changed files in this pull request and generated 1 comment.
| class: | ||
| 'bg-muted text-muted-foreground border-borderbg-muted text-muted-foreground border-border' |
Copilot
AI
Dec 21, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.