refactor: gebruik queries ipv controllers

This commit is contained in:
laurejablonski 2025-04-17 09:59:17 +02:00
parent 4b6be93e63
commit b0077e4911
2 changed files with 126 additions and 142 deletions

View file

@ -4,27 +4,28 @@
import { onMounted, ref } from "vue"; import { onMounted, ref } from "vue";
import type { ClassDTO } from "@dwengo-1/common/interfaces/class"; import type { ClassDTO } from "@dwengo-1/common/interfaces/class";
import { useRoute } from "vue-router"; import { useRoute } from "vue-router";
import { ClassController, type ClassResponse } from "@/controllers/classes"; import { type ClassResponse } from "@/controllers/classes";
import type { JoinRequestsResponse, StudentsResponse } from "@/controllers/students"; import type { JoinRequestsResponse, StudentsResponse } from "@/controllers/students";
import type { StudentDTO } from "@dwengo-1/common/interfaces/student"; import type { StudentDTO } from "@dwengo-1/common/interfaces/student";
import UsingQueryResult from "@/components/UsingQueryResult.vue"; import UsingQueryResult from "@/components/UsingQueryResult.vue";
import { useTeacherJoinRequestsQuery, useUpdateJoinRequestMutation } from "@/queries/teachers"; import { useTeacherJoinRequestsQuery, useUpdateJoinRequestMutation } from "@/queries/teachers";
import type { ClassJoinRequestDTO } from "@dwengo-1/common/interfaces/class-join-request"; import type { ClassJoinRequestDTO } from "@dwengo-1/common/interfaces/class-join-request";
import { useClassQuery, useClassStudentsQuery } from "@/queries/classes";
const { t } = useI18n(); const { t } = useI18n();
// Username of logged in teacher // Username of logged in teacher
const username = ref<string | undefined>(undefined); const username = ref<string | undefined>(undefined);
const classController: ClassController = new ClassController();
// Find class id from route // Find class id from route
const route = useRoute(); const route = useRoute();
const classId: string = route.params.id as string; const classId: string = route.params.id as string;
const isLoading = ref(true);
const currentClass = ref<ClassDTO | undefined>(undefined); const currentClass = ref<ClassDTO | undefined>(undefined);
const students = ref<StudentDTO[]>([]); const students = ref<StudentDTO[]>([]);
const getClass = useClassQuery(classId);
const getStudents = useClassStudentsQuery(classId);
const joinRequestsQuery = useTeacherJoinRequestsQuery(username, classId); const joinRequestsQuery = useTeacherJoinRequestsQuery(username, classId);
const { mutate } = useUpdateJoinRequestMutation(); const { mutate } = useUpdateJoinRequestMutation();
@ -33,17 +34,6 @@
onMounted(async () => { onMounted(async () => {
const userObject = await authState.loadUser(); const userObject = await authState.loadUser();
username.value = userObject?.profile?.preferred_username ?? undefined; username.value = userObject?.profile?.preferred_username ?? undefined;
// Get class of which information should be shown
const classResponse: ClassResponse = await classController.getById(classId);
if (classResponse && classResponse.class) {
currentClass.value = classResponse.class;
isLoading.value = false;
}
// Fetch all students of the class
const studentsResponse: StudentsResponse = await classController.getStudents(classId);
if (studentsResponse && studentsResponse.students) students.value = studentsResponse.students as StudentDTO[];
}); });
// TODO: Boolean that handles visibility for dialogs // TODO: Boolean that handles visibility for dialogs
@ -59,15 +49,10 @@
// Remove student from class // Remove student from class
async function removeStudentFromclass(): Promise<void> { async function removeStudentFromclass(): Promise<void> {
// TODO: replace by query // TODO: replace by query
if (selectedStudent.value) await classController.deleteStudent(classId, selectedStudent.value.username);
dialog.value = false;
selectedStudent.value = null;
//TODO when query; reload table so student not longer in table
} }
// TODO: query + relaoding // TODO: query + relaoding
function handleJoinRequest(c: ClassJoinRequestDTO, accepted: boolean) : void { function handleJoinRequest(c: ClassJoinRequestDTO, accepted: boolean): void {
mutate( mutate(
{ {
teacherUsername: username.value!, teacherUsername: username.value!,
@ -80,8 +65,7 @@
showSnackbar(t("sent"), "success"); showSnackbar(t("sent"), "success");
}, },
onError: (e) => { onError: (e) => {
// ShowSnackbar(t("failed") + ": " + e.message, "error"); showSnackbar(t("failed") + ": " + e.message, "error");
throw e;
}, },
}, },
); );
@ -100,132 +84,132 @@
</script> </script>
<template> <template>
<main> <main>
<div <using-query-result
v-if="isLoading" :query-result="getClass"
class="text-center py-10" v-slot="classResponse: { data: ClassResponse }"
> >
<v-progress-circular <div>
indeterminate <h1 class="title">{{ classResponse.data.class.displayName }}</h1>
color="primary" <using-query-result
/> :query-result="getStudents"
<p>Loading...</p> v-slot="studentsResponse: { data: StudentsResponse }"
</div>
<div v-else>
<h1 class="title">{{ currentClass!.displayName }}</h1>
<v-container
fluid
class="ma-4"
>
<v-row
no-gutters
fluid
> >
<v-col <v-container
cols="12" fluid
sm="6" class="ma-4"
md="6"
> >
<v-table class="table"> <v-row
<thead> no-gutters
<tr> fluid
<th class="header">{{ t("students") }}</th>
<th class="header"></th>
</tr>
</thead>
<tbody>
<tr
v-for="s in students"
:key="s.id"
>
<td>
{{ s.firstName + " " + s.lastName }}
</td>
<td>
<v-btn @click="showPopup(s)"> {{ t("remove") }} </v-btn>
</td>
</tr>
</tbody>
</v-table>
</v-col>
<using-query-result
:query-result="joinRequestsQuery"
v-slot="joinRequests: { data: JoinRequestsResponse }"
>
<v-col
cols="12"
sm="6"
md="6"
> >
<v-table class="table"> <v-col
<thead> cols="12"
<tr> sm="6"
<th class="header">{{ t("classJoinRequests") }}</th> md="6"
<th class="header">{{ t("accept") + "/" + t("reject") }}</th> >
</tr> <v-table class="table">
</thead> <thead>
<tbody> <tr>
<tr <th class="header">{{ t("students") }}</th>
v-for="jr in joinRequests.data.joinRequests as ClassJoinRequestDTO[]" <th class="header"></th>
:key="(jr.class, jr.requester, jr.status)" </tr>
> </thead>
<td> <tbody>
{{ jr.requester.firstName + " " + jr.requester.lastName }} <tr
</td> v-for="s in studentsResponse.data.students as StudentDTO[]"
<td> :key="s.id"
<v-btn >
@click="handleJoinRequest(jr, true)" <td>
class="mr-2" {{ s.firstName + " " + s.lastName }}
color="green" </td>
> <td>
{{ t("accept") }}</v-btn <v-btn @click="showPopup(s)"> {{ t("remove") }} </v-btn>
</td>
</tr>
</tbody>
</v-table>
</v-col>
<using-query-result
:query-result="joinRequestsQuery"
v-slot="joinRequests: { data: JoinRequestsResponse }"
>
<v-col
cols="12"
sm="6"
md="6"
>
<v-table class="table">
<thead>
<tr>
<th class="header">{{ t("classJoinRequests") }}</th>
<th class="header">{{ t("accept") + "/" + t("reject") }}</th>
</tr>
</thead>
<tbody>
<tr
v-for="jr in joinRequests.data.joinRequests as ClassJoinRequestDTO[]"
:key="(jr.class, jr.requester, jr.status)"
> >
<td>
{{ jr.requester.firstName + " " + jr.requester.lastName }}
</td>
<td>
<v-btn
@click="handleJoinRequest(jr, true)"
class="mr-2"
color="green"
>
{{ t("accept") }}</v-btn
>
<v-btn <v-btn
@click="handleJoinRequest(jr, false)" @click="handleJoinRequest(jr, false)"
class="mr-2" class="mr-2"
color="red" color="red"
> >
{{ t("reject") }} {{ t("reject") }}
</v-btn> </v-btn>
</td> </td>
</tr> </tr>
</tbody> </tbody>
</v-table> </v-table>
</v-col> </v-col>
</using-query-result> </using-query-result>
</v-row> </v-row>
</v-container> </v-container>
</div> </using-query-result>
<v-dialog </div>
v-model="dialog" <v-dialog
max-width="400px" v-model="dialog"
> max-width="400px"
<v-card> >
<v-card-title class="headline">{{ t("areusure") }}</v-card-title> <v-card>
<v-card-title class="headline">{{ t("areusure") }}</v-card-title>
<v-card-actions> <v-card-actions>
<v-spacer></v-spacer> <v-spacer></v-spacer>
<v-btn <v-btn
text text
@click="dialog = false" @click="dialog = false"
> >
{{ t("cancel") }} {{ t("cancel") }}
</v-btn> </v-btn>
<v-btn <v-btn
text text
@click="removeStudentFromclass" @click="removeStudentFromclass"
>{{ t("yes") }}</v-btn >{{ t("yes") }}</v-btn
> >
</v-card-actions> </v-card-actions>
</v-card> </v-card>
</v-dialog> </v-dialog>
<v-snackbar <v-snackbar
v-model="snackbar.visible" v-model="snackbar.visible"
:color="snackbar.color" :color="snackbar.color"
timeout="3000" timeout="3000"
> >
{{ snackbar.message }} {{ snackbar.message }}
</v-snackbar> </v-snackbar>
</using-query-result>
</main> </main>
</template> </template>
<style scoped> <style scoped>

View file

@ -27,7 +27,7 @@
const classesQuery = useTeacherClassesQuery(username, true); const classesQuery = useTeacherClassesQuery(username, true);
const allClassesQuery = useClassesQuery(); const allClassesQuery = useClassesQuery();
const { mutate } = useCreateClassMutation(); const { mutate } = useCreateClassMutation();
const getInvitationsQuery = useClassTeacherInvitationsQuery(username); const getInvitationsQuery = useClassTeacherInvitationsQuery(username); // TODO: use useTeacherInvitationsReceivedQuery
// Boolean that handles visibility for dialogs // Boolean that handles visibility for dialogs
// Creating a class will generate a popup with the generated code // Creating a class will generate a popup with the generated code