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 name: string = "";//auth.authState.user!.profile.name!; | ||||
|     const name = "";//Auth.authState.user!.profile.name!; | ||||
|     const initials: string = name | ||||
|         .split(" ") | ||||
|         .map((n) => n[0]) | ||||
|  |  | |||
|  | @ -92,6 +92,6 @@ | |||
|     "group": "Gruppe", | ||||
|     "description": "Beschreibung", | ||||
|     "no-submission": "keine vorlage", | ||||
|     "submission": "einreichung", | ||||
|     "submission": "Einreichung", | ||||
|     "progress": "Fortschritte" | ||||
| } | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ | |||
|     "JoinClassExplanation": "Enter the code the teacher has given you to join the class.", | ||||
|     "invalidFormat": "Invalid format.", | ||||
|     "submitCode": "submit", | ||||
|     "members": "members", | ||||
|     "members": "Members", | ||||
|     "themes": "Themes", | ||||
|     "choose-theme": "Select a theme", | ||||
|     "choose-age": "Select age", | ||||
|  | @ -92,6 +92,6 @@ | |||
|     "group": "Group", | ||||
|     "description": "Description", | ||||
|     "no-submission": "no submission", | ||||
|     "submission": "submission", | ||||
|     "submission": "Submission", | ||||
|     "progress": "Progress" | ||||
| } | ||||
|  |  | |||
|  | @ -33,7 +33,7 @@ | |||
|     "JoinClassExplanation": "Entrez le code que l'enseignant vous a donné pour rejoindre la classe.", | ||||
|     "invalidFormat": "Format non valide.", | ||||
|     "submitCode": "envoyer", | ||||
|     "members": "membres", | ||||
|     "members": "Membres", | ||||
|     "themes": "Thèmes", | ||||
|     "choose-theme": "Choisis un thème", | ||||
|     "choose-age": "Choisis un âge", | ||||
|  | @ -92,6 +92,6 @@ | |||
|     "group": "Groupe", | ||||
|     "description": "Description", | ||||
|     "no-submission": "aucune soumission", | ||||
|     "submission": "soumission", | ||||
|     "submission": "Soumission", | ||||
|     "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.", | ||||
|     "invalidFormat": "Ongeldig formaat.", | ||||
|     "submitCode": "verzenden", | ||||
|     "members": "leden", | ||||
|     "members": "Leden", | ||||
|     "themes": "Lesthema's", | ||||
|     "choose-theme": "Kies een thema", | ||||
|     "choose-age": "Kies een leeftijd", | ||||
|  | @ -92,6 +92,6 @@ | |||
|     "group": "Groep", | ||||
|     "description": "Beschrijving", | ||||
|     "no-submission": "geen indiening", | ||||
|     "submission": "indiening", | ||||
|     "submission": "Indiening", | ||||
|     "progress": "Vooruitgang" | ||||
| } | ||||
|  |  | |||
|  | @ -4,7 +4,7 @@ | |||
|  * Ensures that the title is not empty. | ||||
|  */ | ||||
| export const assignmentTitleRules = [ | ||||
|     (value: string) => { | ||||
|     (value: string): string | boolean => { | ||||
|         if (value?.length >= 1) return true;  // Title must not be empty
 | ||||
|         return 'Title cannot be empty.'; | ||||
|     }, | ||||
|  | @ -16,7 +16,7 @@ export const assignmentTitleRules = [ | |||
|  * Ensures that a valid learning path is selected. | ||||
|  */ | ||||
| export const learningPathRules = [ | ||||
|     (value: { hruid: string; title: string }) => { | ||||
|     (value: { hruid: string; title: string }): string | boolean => { | ||||
|         if (value && value.hruid) { | ||||
|             return true;  // Valid if hruid is present
 | ||||
|         } | ||||
|  | @ -30,7 +30,7 @@ export const learningPathRules = [ | |||
|  * Ensures that at least one class is selected. | ||||
|  */ | ||||
| export const classRules = [ | ||||
|     (value: string) => { | ||||
|     (value: string): string | boolean => { | ||||
|         if (value) return true; | ||||
|         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. | ||||
|  */ | ||||
| export const deadlineRules = [ | ||||
|     (value: string) => { | ||||
|     (value: string): string | boolean => { | ||||
|         if (!value) return "You must set a deadline."; | ||||
| 
 | ||||
|         const selectedDateTime = new Date(value); | ||||
|  | @ -57,7 +57,7 @@ export const deadlineRules = [ | |||
| ]; | ||||
| 
 | ||||
| export const descriptionRules = [ | ||||
|     (value: string) => { | ||||
|     (value: string): string | boolean => { | ||||
|         if (!value || value.trim() === "") return "Description cannot be empty."; | ||||
|         return true; | ||||
|     }, | ||||
|  |  | |||
|  | @ -1,24 +1,24 @@ | |||
| // TODO : temp data until frontend controllers are ready
 | ||||
| type Teacher = { | ||||
| interface Teacher { | ||||
|     username: string; | ||||
|     firstName: string; | ||||
|     lastName: string; | ||||
|     classes: Array<Class>; | ||||
| }; | ||||
|     classes: Class[]; | ||||
| } | ||||
| 
 | ||||
| type Student = { | ||||
| interface Student { | ||||
|     username: string; | ||||
|     firstName: string; | ||||
|     lastName: string; | ||||
|     classes: Array<Class>; | ||||
| }; | ||||
|     classes: Class[]; | ||||
| } | ||||
| 
 | ||||
| type Class = { | ||||
| interface Class { | ||||
|     id: string; | ||||
|     displayName: string; | ||||
|     teachers: Array<Teacher>; | ||||
|     students: Array<Student>; | ||||
| }; | ||||
|     teachers: Teacher[]; | ||||
|     students: Student[]; | ||||
| } | ||||
| 
 | ||||
| const student01: Student = {username: "id01", firstName: "Mark", lastName: "Knopfler", classes: []}; | ||||
| const student02: Student = {username: "id02", firstName: "John", lastName: "Hiat", classes: []}; | ||||
|  | @ -55,11 +55,11 @@ teacher01.classes = [class01]; | |||
| teacher02.classes = [class02]; | ||||
| teacher03.classes = [class03]; | ||||
| 
 | ||||
| type Assignment = { | ||||
| interface Assignment { | ||||
|     id: string; | ||||
|     title: string; | ||||
|     description: string; | ||||
| }; | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 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> | ||||
| 
 | ||||
|  | @ -176,7 +176,12 @@ async function submitFormHandler(): Promise<void> { | |||
|                             :rules="descriptionRules" | ||||
|                         ></v-textarea> | ||||
|                     </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-form> | ||||
|         </v-card> | ||||
|  |  | |||
|  | @ -66,13 +66,14 @@ function openGroupDetails(group): void { | |||
|     dialog.value = true; | ||||
| } | ||||
| 
 | ||||
| const headers = ref([ | ||||
| const headers = computed(() => [ | ||||
|     { title: t('group'), align: 'start', key: 'name' }, | ||||
|     { title: t('progress'), align: 'center', key: 'progress' }, | ||||
|     { title: t('submission'), align: 'center', key: 'submission' } | ||||
| ]); | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| const {mutate, isSuccess} = useDeleteAssignmentMutation(); | ||||
| 
 | ||||
| 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-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-list> | ||||
|                                 <v-list-item | ||||
|  |  | |||
		Reference in a new issue
	
	 Joyelle Ndagijimana
						Joyelle Ndagijimana