feat(frontend): controllers integreren in assignments

This commit is contained in:
Joyelle Ndagijimana 2025-04-07 21:18:09 +02:00
parent baea0051e6
commit 23947ecd92
11 changed files with 100 additions and 65 deletions

View file

@ -16,6 +16,7 @@
"test:unit": "vitest --run"
},
"dependencies": {
"@dwengo-1/common": "^0.1.1",
"@mikro-orm/core": "6.4.9",
"@mikro-orm/knex": "6.4.9",
"@mikro-orm/postgresql": "6.4.9",

View file

@ -51,5 +51,17 @@
"noLearningPathsFoundDescription": "Es gibt keine Lernpfade, die zu Ihrem Suchbegriff passen.",
"legendNotCompletedYet": "Noch nicht fertig",
"legendCompleted": "Fertig",
"legendTeacherExclusive": "Information für Lehrkräfte"
"legendTeacherExclusive": "Information für Lehrkräfte",
"new-assignment": "Neue Aufgabe",
"edit-assignment": "Zuordnung bearbeiten",
"groups": "Gruppen",
"learning-path": "Lernpfad",
"choose-lp": "Einen lernpfad auswählen",
"choose-classes": "Klassen wählen",
"create-groups": "Gruppen erstellen",
"title": "Titel",
"pick-class": "Wählen Sie eine klasse",
"choose-students": "Studenten auswählen",
"create-group": "Gruppe erstellen",
"class": "klasse"
}

View file

@ -54,8 +54,6 @@
"read-more": "Read more",
"new-assignment": "New Assignment",
"edit-assignment": "Edit Assignment",
"next": "next",
"previous": "previous",
"groups": "Groups",
"learning-path": "Learning path",
"choose-lp": "Select a learning path",

View file

@ -54,8 +54,6 @@
"read-more": "En savoir plus",
"new-assignment": "Nouveau travail",
"edit-assignment": "Modifier le travail",
"next": "suivant",
"previous": "précédent",
"groups": "Groupes",
"learning-path": "Parcours d'apprentissage",
"choose-lp": "Choisissez un parcours d'apprentissage",

View file

@ -54,8 +54,6 @@
"read-more": "Lees meer",
"new-assignment": "Nieuwe opdracht",
"edit-assignment": "Opdracht bewerken",
"next": "volgende",
"previous": "vorige",
"groups": "Groepen",
"learning-path": "Leerpad",
"choose-lp": "Kies een leerpad",

View file

@ -9,7 +9,7 @@ import CreateDiscussion from "@/views/discussions/CreateDiscussion.vue";
import CallbackPage from "@/views/CallbackPage.vue";
import UserDiscussions from "@/views/discussions/UserDiscussions.vue";
import UserClasses from "@/views/classes/UserClasses.vue";
import UserAssignments from "@/views/classes/UserAssignments.vue";
import UserAssignments from "@/views/assignments/UserAssignments.vue";
import authState from "@/services/auth/auth-service.ts";
import LearningPathPage from "@/views/learning-paths/LearningPathPage.vue";
import LearningPathSearchPage from "@/views/learning-paths/LearningPathSearchPage.vue";
@ -79,10 +79,20 @@ const router = createRouter({
meta: { requiresAuth: true },
},
{
path: "/assignment/:id",
name: "SingleAssigment",
component: SingleAssignment,
meta: { requiresAuth: true },
path: "/assignment",
meta: {requiresAuth: true},
children: [
{
path: "create",
name: "CreateAssigment",
component: CreateAssignment,
},
{
path: ":id",
name: "SingleAssigment",
component: SingleAssignment,
},
]
},
{
path: "/class/create",

View file

@ -1,42 +1,46 @@
/**
* Submits the form data to the backend.
*
* @param assignmentTitle - The title of the assignment.
* @param selectedLearningPath - The selected learning path, containing hruid and title.
* @param selectedClasses - The selected classes, an array of class objects.
* @param selectedClass - The selected classes, an array of class objects.
* @param groups - An array of groups, each containing student IDs.
* @param deadline - The deadline of the assignment in ISO format.
* @param description - The description of the aasignment
* @param description - The description of the assignment
* Sends a POST request to the backend with the form data.
*/
import {AssignmentController} from "@/controllers/assignments.ts";
import type {AssignmentDTO} from "@dwengo-1/common/interfaces/assignment";
export const submitForm = async (
assignmentTitle: string,
selectedLearningPath: any,
selectedClasses: any[],
selectedClass: string,
groups: string[][],
deadline: string,
description: string
description: string,
currentLanguage: string
) => {
const formData = {
const formData: AssignmentDTO = {
id: 0,
class: selectedClass,
title: assignmentTitle,
hruid: selectedLearningPath?.hruid,
classes: selectedClasses.map(cl => cl.value),
groups: groups,
deadline: deadline,
description: description
description: description,
learningPath: selectedLearningPath,
language: currentLanguage,
groups: [],
//deadline: deadline,
};
try {
const response = await fetch(/*"http://localhost:3000/api/assignment"*/"", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(formData)
});
const data = await response.json();
console.log("Form submitted successfully:", data);
} catch (error) {
console.error("Error submitting form:", error);
}
console.log(formData);
const controller: AssignmentController = new AssignmentController(selectedClass);
const response = await controller.createAssignment(formData);
console.log(response);
};
/**
@ -70,9 +74,9 @@ export const learningPathRules = [
*
* Ensures that at least one class is selected.
*/
export const classesRules = [
(value: any[]) => {
if (value?.length >= 1) return true;
export const classRules = [
(value: string) => {
if (value) return true;
return 'You must select at least one class.';
},
];

View file

@ -29,7 +29,7 @@ const teacher02: Student = {username: "id12", firstName: "John", lastName: "Hiat
const teacher03: Student = {username: "id13", firstName: "Aaron", lastName: "Lewis", classes: []};
const class01: Class = {
id: "class01",
id: "34d484a1-295f-4e9f-bfdc-3e7a23d86a89",
displayName: "class 01",
teachers: [teacher01],
students: [student01, student02],

View file

@ -5,7 +5,7 @@
import {classes} from "@/utils/tempData.ts";
import {
assignmentTitleRules,
classesRules,
classRules,
descriptionRules,
learningPathRules,
submitForm
@ -97,7 +97,7 @@
const { valid } = await form.value.validate();
// Don't submit thr form if all rules don't apply
if (!valid) return;
submitForm(assignmentTitle.value, selectedLearningPath.value, selectedClass.value, groups.value, deadline.value, description.value);
submitForm(assignmentTitle.value, selectedLearningPath.value?.hruid, selectedClass.value.value, groups.value, deadline.value, description.value, locale.value);
};
</script>
@ -109,7 +109,7 @@
<v-form ref="form" class="form-container" validate-on="submit lazy" @submit.prevent="submitFormHandler">
<v-container class="step-container">
<v-card-text>
<v-text-field :v-model="assignmentTitle" :label="t('title')" :rules="assignmentTitleRules"
<v-text-field v-model="assignmentTitle" :label="t('title')" :rules="assignmentTitleRules"
density="compact" variant="outlined" clearable required></v-text-field>
</v-card-text>
@ -136,7 +136,7 @@
v-model="selectedClass"
:items="allClasses"
:label="t('pick-class')"
:rules="classesRules"
:rules="classRules"
variant="outlined"
clearable
hide-details

View file

@ -1,11 +1,11 @@
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
import {ref, computed, onMounted} from 'vue';
import {useI18n} from 'vue-i18n';
import {useRouter} from 'vue-router';
import auth from "@/services/auth/auth-service.ts";
import {assignments} from "@/utils/tempData.ts";
const { t } = useI18n();
const {t} = useI18n();
const router = useRouter();
const role = auth.authState.activeRole;
@ -19,17 +19,12 @@
};
onMounted(loadAssignments);
const goToCreateAssignment = () => {
router.push('/assignment/create');
};
const goToEditAssignment = (id: string) => {
router.push(`/assignment/${id}/edit`);
};
const goToAssignmentDetails = (id: string) => {
router.push(`/assignment/${id}`);
};
@ -45,7 +40,7 @@
<v-btn
v-if="isTeacher"
color="primary"
class="mb-4"
class="mb-4 center-btn"
@click="goToCreateAssignment"
>
{{ t('new-assignment') }}
@ -58,24 +53,26 @@
:key="assignment.id"
cols="12"
>
<v-card class="assignment-card" variant="outlined">
<v-card class="assignment-card">
<v-card-text class="card-content">
<div class="left-content">
<div class="assignment-title">{{ assignment.title }}</div>
<div class="assignment-class">
{{ t('class') }}:
<span class="class-name">
{{ assignment.class }}
</span>
{{ assignment.class }}
</span>
</div>
</div>
<div class="right-content">
<v-btn
color="primary"
@click="goToAssignmentDetails(assignment.id)"
>
{{ t('view-assignment') }}
</v-btn>
<v-card-actions>
<v-btn color="primary" @click="goToAssignmentDetails(assignment.id)">
{{ t('view-assignment') }}
</v-btn>
<v-btn v-if="isTeacher" color="red" @click="goToDeleteAssignment(assignment.id)">
{{ t('delete') }}
</v-btn>
</v-card-actions>
</div>
</v-card-text>
</v-card>
@ -94,6 +91,13 @@
box-sizing: border-box;
}
.center-btn {
display: block;
margin-left: auto;
margin-right: auto;
}
.assignment-card {
padding: 1rem;
}
@ -117,7 +121,7 @@
.assignment-title {
font-weight: bold;
font-size: 1.5rem;
margin-bottom: 0.3rem;
margin-bottom: 0.1rem;
word-break: break-word;
}
@ -133,8 +137,17 @@
.right-content {
display: flex;
align-items: center;
justify-content: flex-end;
align-items: center;
flex-shrink: 0;
flex-wrap: wrap;
width: 100%;
}
@media (min-width: 700px) {
.right-content {
width: auto;
}
}
</style>

7
package-lock.json generated
View file

@ -31,6 +31,7 @@
"name": "@dwengo-1/backend",
"version": "0.1.1",
"dependencies": {
"@dwengo-1/common": "^0.1.1",
"@mikro-orm/core": "6.4.9",
"@mikro-orm/knex": "6.4.9",
"@mikro-orm/postgresql": "6.4.9",
@ -10780,9 +10781,9 @@
}
},
"node_modules/vite": {
"version": "6.2.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.3.tgz",
"integrity": "sha512-IzwM54g4y9JA/xAeBPNaDXiBF8Jsgl3VBQ2YQ/wOY6fyW3xMdSoltIV3Bo59DErdqdE6RxUfv8W69DvUorE4Eg==",
"version": "6.2.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-6.2.5.tgz",
"integrity": "sha512-j023J/hCAa4pRIUH6J9HemwYfjB5llR2Ps0CWeikOtdR8+pAURAk0DoJC5/mm9kd+UgdnIy7d6HE4EAvlYhPhA==",
"dev": true,
"license": "MIT",
"dependencies": {