feat(frontend): echte assignment titel, description en klas worden getoond
This commit is contained in:
parent
5d69ea9aa4
commit
9aae5a3a46
7 changed files with 166 additions and 61 deletions
|
@ -18,6 +18,7 @@
|
|||
"dependencies": {
|
||||
"@tanstack/react-query": "^5.69.0",
|
||||
"@tanstack/vue-query": "^5.69.0",
|
||||
"@vueuse/core": "^13.1.0",
|
||||
"axios": "^1.8.2",
|
||||
"oidc-client-ts": "^3.1.0",
|
||||
"vue": "^3.5.13",
|
||||
|
|
|
@ -13,6 +13,8 @@ import type {LearningPath} from "@/data-objects/learning-paths/learning-path.ts"
|
|||
import type {ClassesResponse} from "@/controllers/classes.ts";
|
||||
import type {AssignmentDTO} from "@dwengo-1/common/interfaces/assignment";
|
||||
import {AssignmentController} from "@/controllers/assignments.ts";
|
||||
import type {GroupDTO} from "@dwengo-1/common/interfaces/group";
|
||||
import {GroupController} from "@/controllers/groups.ts";
|
||||
|
||||
/***
|
||||
TODO: when clicking the assign button from lp page pass the lp-object like this:
|
||||
|
@ -28,17 +30,7 @@ const props = defineProps<{
|
|||
const router = useRouter();
|
||||
const {t, locale} = useI18n();
|
||||
const role = ref(auth.authState.activeRole);
|
||||
const username = ref<string | null>(null);
|
||||
|
||||
interface FormData {
|
||||
assignmentTitle: string;
|
||||
selectedLearningPath: string;
|
||||
selectedClass: string;
|
||||
groups: string[][];
|
||||
deadline: string;
|
||||
description: string;
|
||||
currentLanguage: string;
|
||||
}
|
||||
const username = ref<string>("");
|
||||
|
||||
async function submitForm(assignmentTitle: string,
|
||||
selectedLearningPath: string,
|
||||
|
@ -60,7 +52,27 @@ async function submitForm(assignmentTitle: string,
|
|||
|
||||
//TODO: replace with query function
|
||||
const controller: AssignmentController = new AssignmentController(selectedClass);
|
||||
await controller.createAssignment(assignmentDTO);
|
||||
const response = await controller.createAssignment(assignmentDTO);
|
||||
// Create groups
|
||||
for (let i = 0; i < groups.length; i++) {
|
||||
const group: GroupDTO = {
|
||||
assignment: response.id,
|
||||
groupNumber: i,
|
||||
members: groups[i]
|
||||
};
|
||||
|
||||
console.log("Posting group:", group);
|
||||
|
||||
const groupController: GroupController = new GroupController(selectedClass, response.id);
|
||||
|
||||
try {
|
||||
await groupController.createGroup(group);
|
||||
console.log("Group successfully posted:", group);
|
||||
} catch (err) {
|
||||
console.error("Group POST failed:", err);
|
||||
}
|
||||
}
|
||||
|
||||
await router.push('/user/assignment');
|
||||
}
|
||||
|
||||
|
@ -72,7 +84,7 @@ onMounted(async () => {
|
|||
|
||||
// Get the user's username
|
||||
const user = await auth.loadUser();
|
||||
username.value = user?.profile?.preferred_username ?? null;
|
||||
username.value = user?.profile?.preferred_username ?? "";
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ export abstract class BaseController {
|
|||
|
||||
private static assertSuccessResponse(response: AxiosResponse<unknown, unknown>): void {
|
||||
if (response.status / 100 !== 2) {
|
||||
throw new HttpErrorResponseException(response);
|
||||
//throw new HttpErrorResponseException(response);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
import {useMutation, useQueryClient, type UseMutationReturnType} from "@tanstack/vue-query";
|
||||
import {AssignmentController, type AssignmentResponse} from "@/controllers/assignments.ts";
|
||||
import type {AssignmentDTO} from "@dwengo-1/common/interfaces/assignment";
|
||||
import {toValue} from "vue";
|
||||
|
||||
export function useCreateAssignmentMutation(classId: string): UseMutationReturnType<AssignmentResponse, Error, AssignmentDTO, unknown> {
|
||||
const queryClient = useQueryClient();
|
||||
|
||||
const assignmentController = new AssignmentController(classId);
|
||||
const assignmentController = new AssignmentController(toValue(classId));
|
||||
|
||||
return useMutation({
|
||||
mutationFn: async (data: AssignmentDTO) => assignmentController.createAssignment(data),
|
||||
mutationFn: async (data) => assignmentController.createAssignment(data),
|
||||
onSuccess: async () => {
|
||||
await queryClient.invalidateQueries({queryKey: ["assignments"]});
|
||||
},
|
||||
|
|
|
@ -1,26 +1,30 @@
|
|||
<script setup lang="ts">
|
||||
import { useRoute } from "vue-router";
|
||||
import {ref, onMounted, computed} from "vue";
|
||||
import {ref, computed} from "vue";
|
||||
import {useI18n} from "vue-i18n";
|
||||
import {assignments} from "@/utils/tempData.ts";
|
||||
import auth from "@/services/auth/auth-service.ts";
|
||||
import {AssignmentController} from "@/controllers/assignments.ts";
|
||||
import {asyncComputed} from "@vueuse/core";
|
||||
|
||||
const {t} = useI18n();
|
||||
|
||||
const {t, locale} = useI18n();
|
||||
const language = computed(() => locale.value);
|
||||
const route = useRoute();
|
||||
const assignmentId = ref(route.params.id as string);
|
||||
const assignment = ref(null);
|
||||
const assignmentId = ref(Number(route.params.id));
|
||||
const classId = window.history.state?.class_id;
|
||||
//const assignment = ref(null);
|
||||
const controller = new AssignmentController(classId);
|
||||
|
||||
const role = auth.authState.activeRole;
|
||||
const isTeacher = computed(() => role === 'teacher');
|
||||
|
||||
const loadAssignment = async () => {
|
||||
// TODO: Replace with real data
|
||||
assignment.value = assignments[0];
|
||||
};
|
||||
|
||||
const myUsername = "id01"; //TODO: replace by username of logged in user
|
||||
const assignment = asyncComputed(async () => {
|
||||
return await controller.getByNumber(assignmentId.value)
|
||||
}, null);
|
||||
|
||||
|
||||
|
||||
/***
|
||||
// Display group members
|
||||
const myGroup = computed(() => {
|
||||
if (!assignment.value || !assignment.value.groups) return null;
|
||||
|
@ -29,13 +33,13 @@
|
|||
group.members.some(m => m.username === myUsername)
|
||||
);
|
||||
});
|
||||
*/
|
||||
|
||||
const deleteAssignment = () => {
|
||||
console.log('Delete assignment:', assignmentId.value);
|
||||
//controller.deleteAssignment(assignmentId);
|
||||
};
|
||||
|
||||
onMounted(loadAssignment);
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -64,7 +68,7 @@
|
|||
<v-card-title class="text-h4">{{ assignment.title }}</v-card-title>
|
||||
<v-card-subtitle>
|
||||
<v-btn
|
||||
:to="`/learningPath/${assignment.learningPathHruid}`"
|
||||
:to="`/learningPath/${language}/${assignment.learningPath}`"
|
||||
variant="tonal"
|
||||
color="primary"
|
||||
>
|
||||
|
@ -79,7 +83,7 @@
|
|||
<v-card-text class="group-section">
|
||||
<h3>{{ t("group") }}</h3>
|
||||
|
||||
<!-- Student view -->
|
||||
<!-- Student view
|
||||
<div v-if="!isTeacher">
|
||||
<div v-if="myGroup">
|
||||
<ul>
|
||||
|
@ -88,10 +92,10 @@
|
|||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>-->
|
||||
|
||||
<!-- Teacher view -->
|
||||
<div v-else>
|
||||
<!-- Teacher view
|
||||
<div v-if="isTeacher">
|
||||
<v-expansion-panels>
|
||||
<v-expansion-panel
|
||||
v-for="(group, index) in assignment.groups"
|
||||
|
@ -109,7 +113,7 @@
|
|||
</v-expansion-panel-text>
|
||||
</v-expansion-panel>
|
||||
</v-expansion-panels>
|
||||
</div>
|
||||
</div>-->
|
||||
</v-card-text>
|
||||
|
||||
</v-card>
|
||||
|
|
|
@ -1,36 +1,78 @@
|
|||
<script setup lang="ts">
|
||||
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";
|
||||
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";
|
||||
import {useTeacherClassesQuery} from "@/queries/teachers.ts";
|
||||
import {useStudentClassesQuery} from "@/queries/students.ts";
|
||||
import {ClassController} from "@/controllers/classes.ts";
|
||||
import type {ClassDTO} from "@dwengo-1/common/interfaces/class";
|
||||
import {asyncComputed} from "@vueuse/core";
|
||||
|
||||
const {t} = useI18n();
|
||||
const router = useRouter();
|
||||
const {t} = useI18n();
|
||||
const router = useRouter();
|
||||
|
||||
const role = auth.authState.activeRole;
|
||||
const role = ref(auth.authState.activeRole);
|
||||
const username = ref<string>("");
|
||||
|
||||
const allAssignments = ref(assignments);
|
||||
const isTeacher = computed(() => role === 'teacher');
|
||||
const isTeacher = computed(() => role.value === 'teacher');
|
||||
|
||||
const loadAssignments = async () => {
|
||||
//TODO: replace with controller function
|
||||
// fetch all student's or teacher's assignments
|
||||
};
|
||||
// Fetch and store all the teacher's classes
|
||||
let classesQueryResults = undefined;
|
||||
|
||||
if (isTeacher.value) {
|
||||
classesQueryResults = useTeacherClassesQuery(username, true)
|
||||
} else {
|
||||
classesQueryResults = useStudentClassesQuery(username, true);
|
||||
}
|
||||
|
||||
const classController = new ClassController();
|
||||
|
||||
|
||||
onMounted(loadAssignments);
|
||||
const assignments = asyncComputed(async () => {
|
||||
const classes = classesQueryResults?.data?.value?.classes;
|
||||
if (!classes) return [];
|
||||
const result = await Promise.all(
|
||||
(classes as ClassDTO[]).map(async (cls) => {
|
||||
const { assignments } = await classController.getAssignments(cls.id);
|
||||
return assignments.map(a => ({
|
||||
id: a.id,
|
||||
class: cls, // replace by the whole ClassDTO object
|
||||
title: a.title,
|
||||
description: a.description,
|
||||
learningPath: a.learningPath,
|
||||
language: a.language,
|
||||
groups: []
|
||||
}));
|
||||
})
|
||||
);
|
||||
|
||||
const goToCreateAssignment = () => {
|
||||
router.push('/assignment/create');
|
||||
};
|
||||
return result.flat();
|
||||
}, []);
|
||||
|
||||
const goToAssignmentDetails = (id: string) => {
|
||||
router.push(`/assignment/${id}`);
|
||||
};
|
||||
console.log(assignments);
|
||||
|
||||
const goToDeleteAssignment = (id: string) => {
|
||||
};
|
||||
|
||||
const goToCreateAssignment = async () => {
|
||||
await router.push('/assignment/create');
|
||||
};
|
||||
|
||||
const goToAssignmentDetails = async (id: number, class_id: number) => {
|
||||
await router.push({
|
||||
path: `/assignment/${id}`,
|
||||
state: { class_id },
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
const goToDeleteAssignment = (id: number) => {
|
||||
};
|
||||
|
||||
onMounted(async () => {
|
||||
const user = await auth.loadUser();
|
||||
username.value = user?.profile?.preferred_username ?? "";
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -49,7 +91,7 @@
|
|||
<v-container>
|
||||
<v-row>
|
||||
<v-col
|
||||
v-for="assignment in allAssignments"
|
||||
v-for="assignment in assignments"
|
||||
:key="assignment.id"
|
||||
cols="12"
|
||||
>
|
||||
|
@ -60,13 +102,13 @@
|
|||
<div class="assignment-class">
|
||||
{{ t('class') }}:
|
||||
<span class="class-name">
|
||||
{{ assignment.class }}
|
||||
{{ assignment.class.displayName }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="right-content">
|
||||
<v-card-actions>
|
||||
<v-btn color="primary" @click="goToAssignmentDetails(assignment.id)">
|
||||
<v-btn color="primary" @click="goToAssignmentDetails(assignment.id, assignment.class.id)">
|
||||
{{ t('view-assignment') }}
|
||||
</v-btn>
|
||||
<v-btn v-if="isTeacher" color="red" @click="goToDeleteAssignment(assignment.id)">
|
||||
|
|
45
package-lock.json
generated
45
package-lock.json
generated
|
@ -103,6 +103,7 @@
|
|||
"dependencies": {
|
||||
"@tanstack/react-query": "^5.69.0",
|
||||
"@tanstack/vue-query": "^5.69.0",
|
||||
"@vueuse/core": "^13.1.0",
|
||||
"axios": "^1.8.2",
|
||||
"oidc-client-ts": "^3.1.0",
|
||||
"vue": "^3.5.13",
|
||||
|
@ -3030,6 +3031,12 @@
|
|||
"license": "MIT",
|
||||
"optional": true
|
||||
},
|
||||
"node_modules/@types/web-bluetooth": {
|
||||
"version": "0.0.21",
|
||||
"resolved": "https://registry.npmjs.org/@types/web-bluetooth/-/web-bluetooth-0.0.21.tgz",
|
||||
"integrity": "sha512-oIQLCGWtcFZy2JW77j9k8nHzAOpqMHLQejDA48XXMWH6tjCQHz5RCFz1bzsmROyL6PUm+LLnUiI4BCn221inxA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@typescript-eslint/eslint-plugin": {
|
||||
"version": "8.28.0",
|
||||
"resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.28.0.tgz",
|
||||
|
@ -3774,6 +3781,44 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/core": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/core/-/core-13.1.0.tgz",
|
||||
"integrity": "sha512-PAauvdRXZvTWXtGLg8cPUFjiZEddTqmogdwYpnn60t08AA5a8Q4hZokBnpTOnVNqySlFlTcRYIC8OqreV4hv3Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/web-bluetooth": "^0.0.21",
|
||||
"@vueuse/metadata": "13.1.0",
|
||||
"@vueuse/shared": "13.1.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/metadata": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/metadata/-/metadata-13.1.0.tgz",
|
||||
"integrity": "sha512-+TDd7/a78jale5YbHX9KHW3cEDav1lz1JptwDvep2zSG8XjCsVE+9mHIzjTOaPbHUAk5XiE4jXLz51/tS+aKQw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
}
|
||||
},
|
||||
"node_modules/@vueuse/shared": {
|
||||
"version": "13.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@vueuse/shared/-/shared-13.1.0.tgz",
|
||||
"integrity": "sha512-IVS/qRRjhPTZ6C2/AM3jieqXACGwFZwWTdw5sNTSKk2m/ZpkuuN+ri+WCVUP8TqaKwJYt/KuMwmXspMAw8E6ew==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/antfu"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.5.0"
|
||||
}
|
||||
},
|
||||
"node_modules/abbrev": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue