feat(classes): вкладка «Долги» — что висит у учеников + удаление ДЗ класса/ученика
Новый read-only эндпоинт GET /api/classes/:id/outstanding (teacher/admin, ownership): по каждому ученику класса — его незакрытые задания (классовые + личные от этого учителя) со статусом не начато / в процессе / на доработке / просрочено и дедлайном. Логика «сдано» совпадает с /homework (тест — завершён/исчерпаны попытки; учебник — всё прочитано; загрузка/файл — есть сдача не на доработке). Общий запрос вынесен в assignmentRowsForUser(uid) — им же теперь питается /assignments/my (поведение не изменилось, +поле created_by). Фронт (classes.html): вкладка «Долги» в карточке класса — сводка «должников X из Y, просрочено Z», по каждому должнику карточка со статус-чипами и списком зависших заданий; бейдж с числом просрочек на вкладке. Удаление прямо из списка: личное → «у ученика», классовое → «у всего класса» (через DELETE /assignments/:id, ownership на бэке). Verified: classOutstanding смоук на живой БД (14 учеников/58 позиций/42 просрочено, ownership 403/404/admin); node --check; lint:routes 0. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -190,6 +190,7 @@ async function deleteClass(id) { return req('DELETE', `/classes/
|
||||
async function kickMember(classId, userId) { return req('DELETE', `/classes/${classId}/members/${userId}`); }
|
||||
async function regenerateInviteCode(classId) { return req('POST', `/classes/${classId}/new-code`); }
|
||||
async function classJournal(classId) { return req('GET', `/classes/${classId}/journal`); }
|
||||
async function classOutstanding(classId) { return req('GET', `/classes/${classId}/outstanding`); }
|
||||
async function createAssignment(classId, data) { return req('POST', `/classes/${classId}/assignments`, data); }
|
||||
async function createDirectAssignment(data) { return req('POST', '/assignments', data); }
|
||||
async function updateAssignment(id, data) { return req('PUT', `/assignments/${id}`, data); }
|
||||
@@ -1125,7 +1126,7 @@ window.LS = {
|
||||
adminGetStats, adminGetOverview, adminGlobalSearch, adminGetUsers, adminUpdateRole, adminGetUserSessions, adminGetSessions, adminGetSessionDetail, adminDeleteSession, adminClearUserSessions, adminUpdateUser, adminBanUser, adminDeleteUser,
|
||||
getQuestions, createQuestion, duplicateQuestion, updateQuestion, deleteQuestion, importQuestions,
|
||||
getClasses, createClass, getClassDetail, updateClass, deleteClass, kickMember, addClassMember, createAssignment, createDirectAssignment, updateAssignment, deleteAssignment,
|
||||
regenerateInviteCode, classJournal,
|
||||
regenerateInviteCode, classJournal, classOutstanding,
|
||||
joinClass, myClasses, getStudents, classFeed,
|
||||
getAnnouncements, createAnnouncement, deleteAnnouncement,
|
||||
getNotifications, markNotifRead, markAllNotifsRead, connectSSE,
|
||||
|
||||
Reference in New Issue
Block a user