From 509db70c73a50bebb07ebfa7c3fd18a66fc95e29 Mon Sep 17 00:00:00 2001 From: Adriaan Jacquet Date: Fri, 2 May 2025 20:23:14 +0200 Subject: [PATCH] feat: bezig met ui/ux assignment, bug in testdata --- backend/src/controllers/assignments.ts | 16 +- frontend/src/components/DwengoTable.vue | 49 ++++ .../components/assignments/AssignmentCard.vue | 0 frontend/src/controllers/assignments.ts | 2 +- frontend/src/queries/assignments.ts | 2 +- .../src/views/assignments/UserAssignments.vue | 237 ++++++++++++------ 6 files changed, 227 insertions(+), 79 deletions(-) create mode 100644 frontend/src/components/DwengoTable.vue create mode 100644 frontend/src/components/assignments/AssignmentCard.vue diff --git a/backend/src/controllers/assignments.ts b/backend/src/controllers/assignments.ts index 2ca6d2fc..bd2c7244 100644 --- a/backend/src/controllers/assignments.ts +++ b/backend/src/controllers/assignments.ts @@ -13,6 +13,7 @@ import { requireFields } from './error-helper.js'; import { BadRequestException } from '../exceptions/bad-request-exception.js'; import { Assignment } from '../entities/assignments/assignment.entity.js'; import { EntityDTO } from '@mikro-orm/core'; +import { FALLBACK_LANG } from '../config.js'; function getAssignmentParams(req: Request): { classid: string; assignmentNumber: number; full: boolean } { const classid = req.params.classid; @@ -38,14 +39,19 @@ export async function getAllAssignmentsHandler(req: Request, res: Response): Pro export async function createAssignmentHandler(req: Request, res: Response): Promise { const classid = req.params.classid; - const description = req.body.description; - const language = req.body.language; - const learningPath = req.body.learningPath; + const description = req.body.description || ""; + const language = req.body.language || FALLBACK_LANG; + const learningPath = req.body.learningPath || ""; const title = req.body.title; - requireFields({ description, language, learningPath, title }); + requireFields({ title }); - const assignmentData = req.body as AssignmentDTO; + const assignmentData = { + description: description, + language: language, + learningPath: learningPath, + title: title, + } as AssignmentDTO; const assignment = await createAssignment(classid, assignmentData); res.json({ assignment }); diff --git a/frontend/src/components/DwengoTable.vue b/frontend/src/components/DwengoTable.vue new file mode 100644 index 00000000..01490751 --- /dev/null +++ b/frontend/src/components/DwengoTable.vue @@ -0,0 +1,49 @@ + + + \ No newline at end of file diff --git a/frontend/src/components/assignments/AssignmentCard.vue b/frontend/src/components/assignments/AssignmentCard.vue new file mode 100644 index 00000000..e69de29b diff --git a/frontend/src/controllers/assignments.ts b/frontend/src/controllers/assignments.ts index 0d46e311..79da6965 100644 --- a/frontend/src/controllers/assignments.ts +++ b/frontend/src/controllers/assignments.ts @@ -25,7 +25,7 @@ export class AssignmentController extends BaseController { return this.get(`/${num}`); } - async createAssignment(data: AssignmentDTO): Promise { + async createAssignment(data: Partial): Promise { return this.post(`/`, data); } diff --git a/frontend/src/queries/assignments.ts b/frontend/src/queries/assignments.ts index 2bb0a929..eb007bab 100644 --- a/frontend/src/queries/assignments.ts +++ b/frontend/src/queries/assignments.ts @@ -117,7 +117,7 @@ export function useAssignmentQuery( export function useCreateAssignmentMutation(): UseMutationReturnType< AssignmentResponse, Error, - { cid: string; data: AssignmentDTO }, + { cid: string; data: Partial }, unknown > { const queryClient = useQueryClient(); diff --git a/frontend/src/views/assignments/UserAssignments.vue b/frontend/src/views/assignments/UserAssignments.vue index 07f02106..e8bdf6df 100644 --- a/frontend/src/views/assignments/UserAssignments.vue +++ b/frontend/src/views/assignments/UserAssignments.vue @@ -6,10 +6,10 @@ import authState from "@/services/auth/auth-service.ts"; import auth from "@/services/auth/auth-service.ts"; import { useTeacherAssignmentsQuery, useTeacherClassesQuery } from "@/queries/teachers.ts"; import { useStudentAssignmentsQuery, useStudentClassesQuery } from "@/queries/students.ts"; -import { ClassController } from "@/controllers/classes.ts"; +import { ClassController, type ClassesResponse } from "@/controllers/classes.ts"; import type { ClassDTO } from "@dwengo-1/common/interfaces/class"; import { asyncComputed } from "@vueuse/core"; -import { useDeleteAssignmentMutation } from "@/queries/assignments.ts"; +import { useCreateAssignmentMutation, useDeleteAssignmentMutation } from "@/queries/assignments.ts"; import type { AssignmentsResponse } from "@/controllers/assignments"; import type { AssignmentDTO } from "@dwengo-1/common/interfaces/assignment"; import UsingQueryResult from "@/components/UsingQueryResult.vue"; @@ -38,8 +38,14 @@ onMounted(async () => { }); const isTeacher = computed(() => role.value === "teacher"); - const assignmentsQuery = isTeacher ? useTeacherAssignmentsQuery(username, true) : useStudentAssignmentsQuery(username, true); +const { mutate: assignmentMutation, isSuccess: assignmentIsSuccess } = useCreateAssignmentMutation(); + +const classesQuery = isTeacher ? useTeacherClassesQuery(username, true) : useStudentClassesQuery(username, true); +const selectedClass = ref(undefined); +const isClassSelected = ref(false); + +const assignmentTitle = ref(""); async function goToCreateAssignment(): Promise { await router.push("/assignment/create"); @@ -65,6 +71,27 @@ onMounted(async () => { const user = await auth.loadUser(); username.value = user?.profile?.preferred_username ?? ""; }); + +async function createAssignment(): Promise { + const cid = selectedClass.value!.id; + const assignmentData: Partial = { + within: cid, + title: assignmentTitle.value!, + }; + + assignmentMutation({ cid: cid, data: assignmentData}, { + onSuccess: async (classResponse) => { + // showSnackbar(t("classCreated"), "success"); + // const createdClass: ClassDTO = classResponse.class; + // code.value = createdClass.id; + await assignmentsQuery.refetch(); + }, + onError: (err) => { + console.log(err); + // showSnackbar(t("creationFailed") + ": " + err.message, "error"); + }, + }); +} @@ -207,4 +236,68 @@ onMounted(async () => { font-weight: 500; color: #333; } + +.header { + font-weight: bold !important; + background-color: #0e6942; + color: white; + padding: 10px; +} + +h1 { + color: #0e6942; + text-transform: uppercase; + font-weight: bolder; + padding-top: 2%; + font-size: 50px; +} + +h2 { + color: #0e6942; + font-size: 30px; +} + +.join { + display: flex; + flex-direction: column; + gap: 20px; + margin-top: 50px; +} + +.link { + color: #0b75bb; + text-decoration: underline; +} + +main { + margin-left: 30px; +} + +td, +th { + border-bottom: 1px solid #0e6942; + border-top: 1px solid #0e6942; +} + +.table { + width: 90%; + padding-top: 10px; + border-collapse: collapse; +} + +table thead th:first-child { + border-top-left-radius: 10px; +} + +.table thead th:last-child { + border-top-right-radius: 10px; +} + +.table tbody tr:nth-child(odd) { + background-color: white; +} + +.table tbody tr:nth-child(even) { + background-color: #f6faf2; +}