Skip to content

Add filtering, export features, and fix review mode bug#163

Merged
sky-ruler merged 7 commits into
mainfrom
dev
Jul 20, 2026
Merged

Add filtering, export features, and fix review mode bug#163
sky-ruler merged 7 commits into
mainfrom
dev

Conversation

@sky-ruler

Copy link
Copy Markdown
Owner

This pull request introduces several improvements to the admin interface for managing members and question sets. The most significant updates include enhanced filtering, sorting, and export options for the members table, and improved handling of question set editing after deadlines. Additionally, form controls for editing questions and test cases are now correctly disabled when editing is restricted.

Members management enhancements:

  • Added solved problems filtering and sorting:
    • Users can now filter members by minimum and maximum number of solved problems, and sort the list by solved count in ascending or descending order. [1] [2] [3] [4] [5]
  • CSV export:
    • Added an "Export CSV" button to download the currently displayed (filtered and sorted) members as a CSV file. [1] [2]

Question set editing restrictions:

  • Past deadline handling:
    • When editing a question set past its deadline, form fields for set details and adding questions are now disabled, and a warning is displayed. Only solution updates are allowed. [1] [2]

Form control improvements:

  • Disabled state for editors:
    • The HintsEditor and TestCaseEditor components now support a disabled prop, disabling inputs and action buttons when editing is not allowed (e.g., past deadline).

These changes improve the admin experience by making member management more powerful and ensuring question set editing rules are enforced.
This pull request introduces several enhancements to the admin interface, focusing on improved filtering, sorting, and exporting capabilities for the Members tab, as well as stricter controls for editing question sets after their deadlines. Additionally, it improves the user experience by disabling editing functionality for hints and test cases when appropriate.

Admin Members Tab Improvements:

  • Filtering, Sorting, and Export:
    • Added filters for minimum and maximum solved problems, a sorting option for solved problems, and an "Export CSV" button to download the current member list. These features help admins better analyze and manage user data. [1] [2] [3]
    • The members table now displays users according to the selected sort order and filters, and updates the count and empty state message accordingly. [1] [2]

Admin Question Sets Tab Enhancements:

  • Deadline-aware Editing:
    • When editing a question set past its deadline, the form disables editing for set details and prevents adding new questions, allowing only solution updates. A warning is displayed to indicate limited editing rights. [1] [2]
    • The hints and test case editors now support a disabled state, preventing edits when the deadline has passed.

These changes streamline admin workflows and provide better control over user and question set management.

Copilot AI review requested due to automatic review settings July 20, 2026 18:13
@vercel

vercel Bot commented Jul 20, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
admin-algo-arena Ready Ready Preview, Comment Jul 20, 2026 6:13pm

@sky-ruler
sky-ruler merged commit 0cf1768 into main Jul 20, 2026
25 checks passed

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 expands admin/chief tooling around member management and question set editing, adding solved-count filters/sorting and CSV export, introducing progress filtering/export for clan set analytics, and tightening editability rules in review/deadline-restricted modes.

Changes:

  • Added min/max solved filtering, solved sorting, and CSV export to both Chief Members and Admin Members directories.
  • Added member-progress filtering and CSV export to the Chief dashboard’s question-set analytics view.
  • Prevented draft localStorage persistence during review mode and enforced deadline-based disabling of question set edit controls.

Reviewed changes

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

Show a summary per file
File Description
server/src/features/clans/clan.controller.js Includes name when populating clan members for various clan mutations.
client/src/pages/chief/ChiefMembersTab.jsx Adds solved filters/sort and CSV export for chief member management.
client/src/pages/chief/ChiefDashboardTab.jsx Adds progress-status filtering and CSV export for per-set member progress.
client/src/pages/ChallengeDetails.jsx Skips localStorage draft load/save while in review mode.
admin-client/src/pages/admin/QuestionSetsTab.jsx Disables set/question edits past deadline; adds disabled support for hints/test cases.
admin-client/src/pages/admin/MembersTab.jsx Adds solved filters/sort and CSV export to the admin member directory.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 105 to 108
const filteredMembers = members.filter(member => {
const matchesSearch = (member.username || '').toLowerCase().includes(searchTerm.toLowerCase()) ||
(member.regNo && member.regNo.toLowerCase().includes(searchTerm.toLowerCase())) ||
(member.email && member.email.toLowerCase().includes(searchTerm.toLowerCase()));
Comment on lines +112 to +115
const solved = member.solvedProblems || 0;
const matchesMin = minSolved === '' || solved >= parseInt(minSolved);
const matchesMax = maxSolved === '' || solved <= parseInt(maxSolved);

Comment on lines +127 to +145
const handleDownloadCSV = () => {
const headers = ['Name', 'Username', 'Email', 'Reg No', 'Level', 'Solved', 'XP', 'Streak', 'Status'];
const rows = sortedMembers.map(user => {
const isWarned = user.status === 'Warned';
const isInactive = user.status === 'Inactive';
const status = isWarned ? 'Warned' : isInactive ? 'Inactive' : 'Active';

return [
`"${user.name || user.username || ''}"`,
`"${user.username || ''}"`,
`"${user.email || ''}"`,
`"${user.regNo || 'N/A'}"`,
`"${user.codingLevel || 'Beginner'}"`,
user.solvedProblems || 0,
user.points || 0,
user.streak || 0,
`"${status}"`
].join(',');
});
Comment on lines +149 to +156
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', `Member_Management_${clan.name?.replace(/\s+/g, '_') || 'Clan'}.csv`);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
Comment on lines +349 to +353
<select
value={filterType}
onChange={(e) => setFilterType(e.target.value)}
className="bg-black/20 border border-white/10 text-primary text-xs rounded-lg px-3 py-1.5 focus:outline-none focus:border-accent"
>
Comment on lines +191 to +194
const solved = u.solvedProblems || 0;
const matchesMin = minSolved === '' || solved >= parseInt(minSolved);
const matchesMax = maxSolved === '' || solved <= parseInt(maxSolved);

Comment on lines +211 to +213
let status = 'Not Started';
if ((u.solvedProblems || 0) > 0) status = 'In Progress'; // Can't easily determine 'Completed all' globally without total question count

Comment on lines +206 to +226
const handleDownloadCSV = () => {
const headers = ['Name', 'Username', 'Email', 'Reg No', 'Clan', 'Level', 'Solved', 'XP', 'Streak', 'Status'];
const rows = sortedUsers.map(u => {
const activeClan = u.clan ? (clansQuery.data || []).find(c => c._id === u.clan || c._id === u.clan?._id) : null;
const clanName = activeClan ? activeClan.name : 'Unassigned';
let status = 'Not Started';
if ((u.solvedProblems || 0) > 0) status = 'In Progress'; // Can't easily determine 'Completed all' globally without total question count

return [
`"${u.name || ''}"`,
`"${u.username || ''}"`,
`"${u.email || ''}"`,
`"${u.regNo || 'N/A'}"`,
`"${clanName}"`,
`"${u.codingLevel || 'Beginner'}"`,
u.solvedProblems || 0,
u.points || 0,
u.streak || 0,
`"${u.status || 'Active'}"`
].join(',');
});
Comment on lines +230 to +237
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.setAttribute('href', url);
link.setAttribute('download', `Admin_Directory_${new Date().toISOString().split('T')[0]}.csv`);
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};
Comment on lines +294 to +295
const todayStr = new Date().toISOString().split('T')[0];
const isPastDeadline = editingSetId && form.deadline && form.deadline < todayStr;

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 994de1e640

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

const [previewQuestion, setPreviewQuestion] = useState(null);

const todayStr = new Date().toISOString().split('T')[0];
const isPastDeadline = editingSetId && form.deadline && form.deadline < todayStr;

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Enforce deadline restrictions on the update API

When a set is past its deadline, this flag only disables form controls in the browser; the submit still sends a full questions payload and the server PUT /api/sets/:id handler still copies title, weekNumber, deadline, targetLevel, questions, and status from any request body. In the past-deadline scenario, an admin with stale state/devtools or a direct API call can still move, remove, or retitle questions and invalidate existing submissions despite the UI warning, so the deadline rule needs to be enforced in updateQuestionSet as well.

Useful? React with 👍 / 👎.

`"${u.username || ''}"`,
`"${u.email || ''}"`,
`"${u.regNo || 'N/A'}"`,
`"${clanName}"`,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Escape clan names in the CSV export

When an admin-created clan name contains a double quote, this manual quoting produces malformed CSV because embedded quotes are not doubled before joining the row; the clan model only trims/limits the name, so values like Alpha "A" can be saved and will shift/corrupt columns when the exported file is opened. Please use a CSV cell escaper for this and the other string fields in the new exporters.

Useful? React with 👍 / 👎.

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.

2 participants