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
				
			
		|  | @ -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)"> | ||||
|  |  | |||
		Reference in a new issue
	
	 Joyelle Ndagijimana
						Joyelle Ndagijimana