feat(frontend): nieuwe "cancel" knop bij create assignment
This commit is contained in:
parent
1d29adaa31
commit
800f6433d6
10 changed files with 44 additions and 238 deletions
|
@ -11,7 +11,7 @@
|
||||||
|
|
||||||
const role = auth.authState.activeRole;
|
const role = auth.authState.activeRole;
|
||||||
|
|
||||||
const name: string = "";//auth.authState.user!.profile.name!;
|
const name = "";//Auth.authState.user!.profile.name!;
|
||||||
const initials: string = name
|
const initials: string = name
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map((n) => n[0])
|
.map((n) => n[0])
|
||||||
|
|
|
@ -92,6 +92,6 @@
|
||||||
"group": "Gruppe",
|
"group": "Gruppe",
|
||||||
"description": "Beschreibung",
|
"description": "Beschreibung",
|
||||||
"no-submission": "keine vorlage",
|
"no-submission": "keine vorlage",
|
||||||
"submission": "einreichung",
|
"submission": "Einreichung",
|
||||||
"progress": "Fortschritte"
|
"progress": "Fortschritte"
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
"JoinClassExplanation": "Enter the code the teacher has given you to join the class.",
|
"JoinClassExplanation": "Enter the code the teacher has given you to join the class.",
|
||||||
"invalidFormat": "Invalid format.",
|
"invalidFormat": "Invalid format.",
|
||||||
"submitCode": "submit",
|
"submitCode": "submit",
|
||||||
"members": "members",
|
"members": "Members",
|
||||||
"themes": "Themes",
|
"themes": "Themes",
|
||||||
"choose-theme": "Select a theme",
|
"choose-theme": "Select a theme",
|
||||||
"choose-age": "Select age",
|
"choose-age": "Select age",
|
||||||
|
@ -92,6 +92,6 @@
|
||||||
"group": "Group",
|
"group": "Group",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
"no-submission": "no submission",
|
"no-submission": "no submission",
|
||||||
"submission": "submission",
|
"submission": "Submission",
|
||||||
"progress": "Progress"
|
"progress": "Progress"
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
"JoinClassExplanation": "Entrez le code que l'enseignant vous a donné pour rejoindre la classe.",
|
"JoinClassExplanation": "Entrez le code que l'enseignant vous a donné pour rejoindre la classe.",
|
||||||
"invalidFormat": "Format non valide.",
|
"invalidFormat": "Format non valide.",
|
||||||
"submitCode": "envoyer",
|
"submitCode": "envoyer",
|
||||||
"members": "membres",
|
"members": "Membres",
|
||||||
"themes": "Thèmes",
|
"themes": "Thèmes",
|
||||||
"choose-theme": "Choisis un thème",
|
"choose-theme": "Choisis un thème",
|
||||||
"choose-age": "Choisis un âge",
|
"choose-age": "Choisis un âge",
|
||||||
|
@ -92,6 +92,6 @@
|
||||||
"group": "Groupe",
|
"group": "Groupe",
|
||||||
"description": "Description",
|
"description": "Description",
|
||||||
"no-submission": "aucune soumission",
|
"no-submission": "aucune soumission",
|
||||||
"submission": "soumission",
|
"submission": "Soumission",
|
||||||
"progress": "Progrès"
|
"progress": "Progrès"
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@
|
||||||
"JoinClassExplanation": "Voer de code in die je van de docent hebt gekregen om lid te worden van de klas.",
|
"JoinClassExplanation": "Voer de code in die je van de docent hebt gekregen om lid te worden van de klas.",
|
||||||
"invalidFormat": "Ongeldig formaat.",
|
"invalidFormat": "Ongeldig formaat.",
|
||||||
"submitCode": "verzenden",
|
"submitCode": "verzenden",
|
||||||
"members": "leden",
|
"members": "Leden",
|
||||||
"themes": "Lesthema's",
|
"themes": "Lesthema's",
|
||||||
"choose-theme": "Kies een thema",
|
"choose-theme": "Kies een thema",
|
||||||
"choose-age": "Kies een leeftijd",
|
"choose-age": "Kies een leeftijd",
|
||||||
|
@ -92,6 +92,6 @@
|
||||||
"group": "Groep",
|
"group": "Groep",
|
||||||
"description": "Beschrijving",
|
"description": "Beschrijving",
|
||||||
"no-submission": "geen indiening",
|
"no-submission": "geen indiening",
|
||||||
"submission": "indiening",
|
"submission": "Indiening",
|
||||||
"progress": "Vooruitgang"
|
"progress": "Vooruitgang"
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
* Ensures that the title is not empty.
|
* Ensures that the title is not empty.
|
||||||
*/
|
*/
|
||||||
export const assignmentTitleRules = [
|
export const assignmentTitleRules = [
|
||||||
(value: string) => {
|
(value: string): string | boolean => {
|
||||||
if (value?.length >= 1) return true; // Title must not be empty
|
if (value?.length >= 1) return true; // Title must not be empty
|
||||||
return 'Title cannot be empty.';
|
return 'Title cannot be empty.';
|
||||||
},
|
},
|
||||||
|
@ -16,7 +16,7 @@ export const assignmentTitleRules = [
|
||||||
* Ensures that a valid learning path is selected.
|
* Ensures that a valid learning path is selected.
|
||||||
*/
|
*/
|
||||||
export const learningPathRules = [
|
export const learningPathRules = [
|
||||||
(value: { hruid: string; title: string }) => {
|
(value: { hruid: string; title: string }): string | boolean => {
|
||||||
if (value && value.hruid) {
|
if (value && value.hruid) {
|
||||||
return true; // Valid if hruid is present
|
return true; // Valid if hruid is present
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ export const learningPathRules = [
|
||||||
* Ensures that at least one class is selected.
|
* Ensures that at least one class is selected.
|
||||||
*/
|
*/
|
||||||
export const classRules = [
|
export const classRules = [
|
||||||
(value: string) => {
|
(value: string): string | boolean => {
|
||||||
if (value) return true;
|
if (value) return true;
|
||||||
return 'You must select at least one class.';
|
return 'You must select at least one class.';
|
||||||
},
|
},
|
||||||
|
@ -42,7 +42,7 @@ export const classRules = [
|
||||||
* Ensures that a valid deadline is selected and is in the future.
|
* Ensures that a valid deadline is selected and is in the future.
|
||||||
*/
|
*/
|
||||||
export const deadlineRules = [
|
export const deadlineRules = [
|
||||||
(value: string) => {
|
(value: string): string | boolean => {
|
||||||
if (!value) return "You must set a deadline.";
|
if (!value) return "You must set a deadline.";
|
||||||
|
|
||||||
const selectedDateTime = new Date(value);
|
const selectedDateTime = new Date(value);
|
||||||
|
@ -57,7 +57,7 @@ export const deadlineRules = [
|
||||||
];
|
];
|
||||||
|
|
||||||
export const descriptionRules = [
|
export const descriptionRules = [
|
||||||
(value: string) => {
|
(value: string): string | boolean => {
|
||||||
if (!value || value.trim() === "") return "Description cannot be empty.";
|
if (!value || value.trim() === "") return "Description cannot be empty.";
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,24 +1,24 @@
|
||||||
// TODO : temp data until frontend controllers are ready
|
// TODO : temp data until frontend controllers are ready
|
||||||
type Teacher = {
|
interface Teacher {
|
||||||
username: string;
|
username: string;
|
||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
classes: Array<Class>;
|
classes: Class[];
|
||||||
};
|
}
|
||||||
|
|
||||||
type Student = {
|
interface Student {
|
||||||
username: string;
|
username: string;
|
||||||
firstName: string;
|
firstName: string;
|
||||||
lastName: string;
|
lastName: string;
|
||||||
classes: Array<Class>;
|
classes: Class[];
|
||||||
};
|
}
|
||||||
|
|
||||||
type Class = {
|
interface Class {
|
||||||
id: string;
|
id: string;
|
||||||
displayName: string;
|
displayName: string;
|
||||||
teachers: Array<Teacher>;
|
teachers: Teacher[];
|
||||||
students: Array<Student>;
|
students: Student[];
|
||||||
};
|
}
|
||||||
|
|
||||||
const student01: Student = {username: "id01", firstName: "Mark", lastName: "Knopfler", classes: []};
|
const student01: Student = {username: "id01", firstName: "Mark", lastName: "Knopfler", classes: []};
|
||||||
const student02: Student = {username: "id02", firstName: "John", lastName: "Hiat", classes: []};
|
const student02: Student = {username: "id02", firstName: "John", lastName: "Hiat", classes: []};
|
||||||
|
@ -55,11 +55,11 @@ teacher01.classes = [class01];
|
||||||
teacher02.classes = [class02];
|
teacher02.classes = [class02];
|
||||||
teacher03.classes = [class03];
|
teacher03.classes = [class03];
|
||||||
|
|
||||||
type Assignment = {
|
interface Assignment {
|
||||||
id: string;
|
id: string;
|
||||||
title: string;
|
title: string;
|
||||||
description: string;
|
description: string;
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
export const assignments: Assignment[] = Array.from({length: 4}, (_, i) => ({
|
export const assignments: Assignment[] = Array.from({length: 4}, (_, i) => ({
|
||||||
|
@ -100,4 +100,4 @@ export const assignments: Assignment[] = Array.from({length: 4}, (_, i) => ({
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
|
||||||
export const classes: Array<Class> = [class01, class02, class03];
|
export const classes: Class[] = [class01, class02, class03];
|
||||||
|
|
|
@ -1,200 +0,0 @@
|
||||||
<script setup lang="ts">
|
|
||||||
import { useRoute } from "vue-router";
|
|
||||||
import {ref, computed} from "vue";
|
|
||||||
import {useI18n} from "vue-i18n";
|
|
||||||
import auth from "@/services/auth/auth-service.ts";
|
|
||||||
import {AssignmentController} from "@/controllers/assignments.ts";
|
|
||||||
import {asyncComputed} from "@vueuse/core";
|
|
||||||
|
|
||||||
|
|
||||||
const {t, locale} = useI18n();
|
|
||||||
const language = computed(() => locale.value);
|
|
||||||
const route = useRoute();
|
|
||||||
const assignmentId = ref(Number(route.params.id));
|
|
||||||
const classId = window.history.state?.class_id;
|
|
||||||
const controller = new AssignmentController(classId);
|
|
||||||
|
|
||||||
const role = auth.authState.activeRole;
|
|
||||||
const isTeacher = computed(() => role === 'teacher');
|
|
||||||
|
|
||||||
const assignment = asyncComputed(async () => {
|
|
||||||
return await controller.getByNumber(assignmentId.value)
|
|
||||||
}, null);
|
|
||||||
|
|
||||||
|
|
||||||
const submitted = ref(true);//TODO: update by fetching submissions and check group
|
|
||||||
|
|
||||||
const submitAssignment = async () => {
|
|
||||||
//TODO
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/***
|
|
||||||
// Display group members
|
|
||||||
const myGroup = computed(() => {
|
|
||||||
if (!assignment.value || !assignment.value.groups) return null;
|
|
||||||
console.log(assignment.value.groups)
|
|
||||||
return assignment.value.groups.find(group =>
|
|
||||||
group.members.some(m => m.username === myUsername)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
*/
|
|
||||||
|
|
||||||
const deleteAssignment = async () => {
|
|
||||||
await controller.deleteAssignment(assignmentId.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="container">
|
|
||||||
<v-card v-if="assignment" class="assignment-card">
|
|
||||||
<div class="top-buttons">
|
|
||||||
<v-btn
|
|
||||||
icon
|
|
||||||
variant="text"
|
|
||||||
class="back-btn"
|
|
||||||
to="/user/assignment"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-arrow-left</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
|
|
||||||
<v-btn
|
|
||||||
v-if="isTeacher"
|
|
||||||
icon
|
|
||||||
variant="text"
|
|
||||||
class="top-right-btn"
|
|
||||||
@click="deleteAssignment"
|
|
||||||
>
|
|
||||||
<v-icon>mdi-delete</v-icon>
|
|
||||||
</v-btn>
|
|
||||||
<v-chip
|
|
||||||
v-if="!isTeacher"
|
|
||||||
class="ma-2 top-right-btn"
|
|
||||||
label
|
|
||||||
color="success"
|
|
||||||
>
|
|
||||||
{{ t("submitted") }}
|
|
||||||
</v-chip>
|
|
||||||
</div>
|
|
||||||
<v-card-title class="text-h4">{{ assignment.title }}</v-card-title>
|
|
||||||
<v-card-subtitle class="subtitle-section">
|
|
||||||
<v-btn
|
|
||||||
:to="`/learningPath/${language}/${assignment.learningPath}`"
|
|
||||||
variant="tonal"
|
|
||||||
color="primary"
|
|
||||||
>
|
|
||||||
{{ t("learning-path") }}
|
|
||||||
</v-btn>
|
|
||||||
</v-card-subtitle>
|
|
||||||
|
|
||||||
<v-card-text class="description">
|
|
||||||
{{ assignment.description }}
|
|
||||||
</v-card-text>
|
|
||||||
|
|
||||||
<v-card-text class="group-section">
|
|
||||||
<h3>{{ t("group") }}</h3>
|
|
||||||
|
|
||||||
<!-- Student view
|
|
||||||
<div v-if="!isTeacher">
|
|
||||||
<div v-if="myGroup">
|
|
||||||
<ul>
|
|
||||||
<li v-for="student in myGroup.members" :key="student.username">
|
|
||||||
{{ student.firstName + ' ' + student.lastName}}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>-->
|
|
||||||
|
|
||||||
<!-- Teacher view
|
|
||||||
<div v-if="isTeacher">
|
|
||||||
<v-expansion-panels>
|
|
||||||
<v-expansion-panel
|
|
||||||
v-for="(group, index) in assignment.groups"
|
|
||||||
:key="group.id"
|
|
||||||
>
|
|
||||||
<v-expansion-panel-title>
|
|
||||||
{{ t("group") }} {{ index + 1 }}
|
|
||||||
</v-expansion-panel-title>
|
|
||||||
<v-expansion-panel-text>
|
|
||||||
<ul>
|
|
||||||
<li v-for="student in group.members" :key="student.username">
|
|
||||||
{{ student.firstName + ' ' + student.lastName }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</v-expansion-panel-text>
|
|
||||||
</v-expansion-panel>
|
|
||||||
</v-expansion-panels>
|
|
||||||
</div>-->
|
|
||||||
</v-card-text >
|
|
||||||
<v-card-actions class="justify-end">
|
|
||||||
<v-btn
|
|
||||||
v-if="!isTeacher"
|
|
||||||
size="large"
|
|
||||||
color="success"
|
|
||||||
variant="flat"
|
|
||||||
@click="submitAssignment"
|
|
||||||
>
|
|
||||||
{{ t("submit") }}
|
|
||||||
</v-btn>
|
|
||||||
<v-btn
|
|
||||||
v-if="isTeacher"
|
|
||||||
size="large"
|
|
||||||
color="success"
|
|
||||||
variant="text"
|
|
||||||
>
|
|
||||||
{{ t("view-submissions") }}
|
|
||||||
</v-btn>
|
|
||||||
</v-card-actions>
|
|
||||||
|
|
||||||
</v-card>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style scoped>
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
padding: 2%;
|
|
||||||
min-height: 100vh;
|
|
||||||
}
|
|
||||||
|
|
||||||
.assignment-card {
|
|
||||||
width: 85%;
|
|
||||||
padding: 2%;
|
|
||||||
border-radius: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
margin-top: 2%;
|
|
||||||
line-height: 1.6;
|
|
||||||
font-size: 1.1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-right-btn {
|
|
||||||
position: absolute;
|
|
||||||
right: 2%;
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-section {
|
|
||||||
margin-top: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-section h3 {
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-section ul {
|
|
||||||
padding-left: 1.2rem;
|
|
||||||
list-style-type: disc;
|
|
||||||
}
|
|
||||||
|
|
||||||
.subtitle-section {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
|
@ -18,12 +18,12 @@ import {useRoute} from "vue-router";
|
||||||
/***
|
/***
|
||||||
TODO: when clicking the assign button from lp page pass the lp-hruid in a query like this:
|
TODO: when clicking the assign button from lp page pass the lp-hruid in a query like this:
|
||||||
router.push({
|
router.push({
|
||||||
path: "/assignment/create,
|
path: "/assignment/create,
|
||||||
query: {
|
query: {
|
||||||
...route.query,
|
...route.query,
|
||||||
lp: hruid,
|
lp: hruid,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
|
@ -176,7 +176,12 @@ async function submitFormHandler(): Promise<void> {
|
||||||
:rules="descriptionRules"
|
:rules="descriptionRules"
|
||||||
></v-textarea>
|
></v-textarea>
|
||||||
</v-card-text>
|
</v-card-text>
|
||||||
<v-btn class="mt-2" color="secondary" type="submit" block>Submit</v-btn>
|
<v-card-text>
|
||||||
|
<v-btn class="mt-2" color="secondary" type="submit" block>{{ t("submit") }}</v-btn>
|
||||||
|
<v-btn to="/user/assignment" color="grey" block>{{ t("cancel") }}</v-btn>
|
||||||
|
</v-card-text>
|
||||||
|
|
||||||
|
|
||||||
</v-container>
|
</v-container>
|
||||||
</v-form>
|
</v-form>
|
||||||
</v-card>
|
</v-card>
|
||||||
|
|
|
@ -66,13 +66,14 @@ function openGroupDetails(group): void {
|
||||||
dialog.value = true;
|
dialog.value = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
const headers = ref([
|
const headers = computed(() => [
|
||||||
{title: t('group'), align: 'start', key: 'name'},
|
{ title: t('group'), align: 'start', key: 'name' },
|
||||||
{title: t('progress'), align: 'center', key: 'progress'},
|
{ title: t('progress'), align: 'center', key: 'progress' },
|
||||||
{title: t('submission'), align: 'center', key: 'submission'}
|
{ title: t('submission'), align: 'center', key: 'submission' }
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const {mutate, isSuccess} = useDeleteAssignmentMutation();
|
const {mutate, isSuccess} = useDeleteAssignmentMutation();
|
||||||
|
|
||||||
async function deleteAssignment(num: number, clsId: string): Promise<void> {
|
async function deleteAssignment(num: number, clsId: string): Promise<void> {
|
||||||
|
@ -177,7 +178,7 @@ async function deleteAssignment(num: number, clsId: string): Promise<void> {
|
||||||
|
|
||||||
<v-dialog v-model="dialog" max-width="50%">
|
<v-dialog v-model="dialog" max-width="50%">
|
||||||
<v-card>
|
<v-card>
|
||||||
<v-card-title class="headline">Group Members</v-card-title>
|
<v-card-title class="headline">{{t("members")}}</v-card-title>
|
||||||
<v-card-text>
|
<v-card-text>
|
||||||
<v-list>
|
<v-list>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue