diff --git a/api/source/api_modules/classroom_compliance/api.d b/api/source/api_modules/classroom_compliance/api.d index 5cc692f..ee24897 100644 --- a/api/source/api_modules/classroom_compliance/api.d +++ b/api/source/api_modules/classroom_compliance/api.d @@ -19,6 +19,7 @@ void registerApiEndpoints(PathHandler handler) { handler.addMapping(Method.GET, CLASS_PATH ~ "/notes", &getClassNotes); handler.addMapping(Method.POST, CLASS_PATH ~ "/notes", &createClassNote); handler.addMapping(Method.DELETE, CLASS_PATH ~ "/notes/:noteId:ulong", &deleteClassNote); + handler.addMapping(Method.PUT, CLASS_PATH ~ "/reset-desk-numbers", &resetStudentDesks); handler.addMapping(Method.POST, CLASS_PATH ~ "/students", &createStudent); handler.addMapping(Method.GET, CLASS_PATH ~ "/students", &getStudents); diff --git a/api/source/api_modules/classroom_compliance/api_class.d b/api/source/api_modules/classroom_compliance/api_class.d index f763baa..31568ac 100644 --- a/api/source/api_modules/classroom_compliance/api_class.d +++ b/api/source/api_modules/classroom_compliance/api_class.d @@ -141,3 +141,12 @@ void deleteClassNote(ref HttpRequestContext ctx) { const query = "DELETE FROM classroom_compliance_class_note WHERE class_id = ? AND id = ?"; update(conn, query, cls.id, noteId); } + +void resetStudentDesks(ref HttpRequestContext ctx) { + Connection conn = getDb(); + scope(exit) conn.close(); + User user = getUserOrThrow(ctx, conn); + auto cls = getClassOrThrow(ctx, conn, user); + const query = "UPDATE classroom_compliance_student SET desk_number = 0 WHERE class_id = ?"; + update(conn, query, cls.id); +} diff --git a/app/src/api/classroom_compliance.ts b/app/src/api/classroom_compliance.ts index cd14cc3..936de2e 100644 --- a/app/src/api/classroom_compliance.ts +++ b/app/src/api/classroom_compliance.ts @@ -1,4 +1,4 @@ -import { APIClient, type APIResponse, type AuthStoreType } from './base' +import { APIClient, APIResponse, type AuthStoreType } from './base' export const BASE_URL = import.meta.env.VITE_API_URL + '/classroom-compliance' @@ -140,6 +140,15 @@ export class ClassroomComplianceAPIClient extends APIClient { return super.delete(`/classes/${classId}/notes/${noteId}`) } + resetStudentDesks(classId: number): APIResponse { + const url = `/classes/${classId}/reset-desk-numbers` + const promise = fetch(this.baseUrl + url, { + headers: this.getAuthHeaders(), + method: 'PUT', + }) + return new APIResponse(this.handleAPIResponseWithNoBody(promise)) + } + getStudents(classId: number): APIResponse { return super.get(`/classes/${classId}/students`) } diff --git a/app/src/apps/classroom_compliance/ClassView.vue b/app/src/apps/classroom_compliance/ClassView.vue index fc82057..d3c5aa8 100644 --- a/app/src/apps/classroom_compliance/ClassView.vue +++ b/app/src/apps/classroom_compliance/ClassView.vue @@ -15,10 +15,17 @@ const router = useRouter() const cls: Ref = ref(null) const notes: Ref = ref([]) const noteContent: Ref = ref('') + +const entriesTable = useTemplateRef('entries-table') + const apiClient = new ClassroomComplianceAPIClient(authStore) const deleteClassDialog = useTemplateRef('deleteClassDialog') onMounted(() => { + loadClass() +}) + +function loadClass() { const idNumber = parseInt(props.id, 10) apiClient.getClass(idNumber).handleErrorsWithAlert().then(result => { if (result) { @@ -28,7 +35,7 @@ onMounted(() => { router.back(); } }) -}) +} async function deleteThisClass() { if (!cls.value || !(await deleteClassDialog.value?.show())) return @@ -61,6 +68,13 @@ function refreshNotes() { } }) } + +async function resetStudentDesks() { + if (!cls.value) return + await apiClient.resetStudentDesks(cls.value.id).handleErrorsWithAlert() + // Reload the table! + await entriesTable.value?.loadEntries() +}