feat: nieuwe component voor de deadline
This commit is contained in:
		
							parent
							
								
									db7c5409fc
								
							
						
					
					
						commit
						3e00f0eb1f
					
				
					 4 changed files with 84 additions and 11 deletions
				
			
		
							
								
								
									
										48
									
								
								frontend/src/components/DeadlineSelector.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								frontend/src/components/DeadlineSelector.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,48 @@ | ||||||
|  | <script setup lang="ts"> | ||||||
|  | import { ref, computed, defineEmits } from "vue"; | ||||||
|  | 
 | ||||||
|  | const date = ref(""); | ||||||
|  | const time = ref(""); | ||||||
|  | const emit = defineEmits(["update:deadline"]); | ||||||
|  | 
 | ||||||
|  | const formattedDeadline = computed(() => { | ||||||
|  |     if (!date.value || !time.value) return ""; | ||||||
|  |     return `${date.value} ${time.value}`; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | const updateDeadline = () => { | ||||||
|  |     if (date.value && time.value) { | ||||||
|  |         emit("update:deadline", formattedDeadline.value); | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |     <div> | ||||||
|  |         <v-card-text> | ||||||
|  |             <v-text-field | ||||||
|  |                 v-model="date" | ||||||
|  |                 label="Select Deadline Date" | ||||||
|  |                 type="date" | ||||||
|  |                 variant="outlined" | ||||||
|  |                 density="compact" | ||||||
|  |                 @update:modelValue="updateDeadline" | ||||||
|  |             ></v-text-field> | ||||||
|  |         </v-card-text> | ||||||
|  | 
 | ||||||
|  |         <v-card-text> | ||||||
|  |             <v-text-field | ||||||
|  |                 v-model="time" | ||||||
|  |                 label="Select Deadline Time" | ||||||
|  |                 type="time" | ||||||
|  |                 variant="outlined" | ||||||
|  |                 density="compact" | ||||||
|  |                 @update:modelValue="updateDeadline" | ||||||
|  |             ></v-text-field> | ||||||
|  |         </v-card-text> | ||||||
|  |     </div> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
|  | @ -54,7 +54,7 @@ const createGroup = () => { | ||||||
|             item-title="displayName" |             item-title="displayName" | ||||||
|             item-value="id" |             item-value="id" | ||||||
|             :label="t('pick-class')" |             :label="t('pick-class')" | ||||||
|             variant="solo" |             variant="outlined" | ||||||
|             clearable |             clearable | ||||||
|             hide-details |             hide-details | ||||||
|             density="compact" |             density="compact" | ||||||
|  | @ -67,7 +67,7 @@ const createGroup = () => { | ||||||
|             item-title="title" |             item-title="title" | ||||||
|             item-value="value" |             item-value="value" | ||||||
|             :label="t('choose-students')" |             :label="t('choose-students')" | ||||||
|             variant="solo" |             variant="outlined" | ||||||
|             clearable |             clearable | ||||||
|             multiple |             multiple | ||||||
|             hide-details |             hide-details | ||||||
|  |  | ||||||
|  | @ -5,20 +5,22 @@ | ||||||
|  * @param selectedLearningPath - The selected learning path, containing hruid and title. |  * @param selectedLearningPath - The selected learning path, containing hruid and title. | ||||||
|  * @param selectedClasses - The selected classes, an array of class objects. |  * @param selectedClasses - The selected classes, an array of class objects. | ||||||
|  * @param groups - An array of groups, each containing student IDs. |  * @param groups - An array of groups, each containing student IDs. | ||||||
|  * |  * @param deadline - The deadline of the assignment in ISO format. | ||||||
|  * Sends a POST request to the backend with the form data. |  * Sends a POST request to the backend with the form data. | ||||||
|  */ |  */ | ||||||
| export const submitForm = async ( | export const submitForm = async ( | ||||||
|     assignmentTitle: string, |     assignmentTitle: string, | ||||||
|     selectedLearningPath: any, |     selectedLearningPath: any, | ||||||
|     selectedClasses: any[], |     selectedClasses: any[], | ||||||
|     groups: string[][] |     groups: string[][], | ||||||
|  |     deadline: string | ||||||
| ) => { | ) => { | ||||||
|     const formData = { |     const formData = { | ||||||
|         title: assignmentTitle, |         title: assignmentTitle, | ||||||
|         hruid: selectedLearningPath?.hruid, |         hruid: selectedLearningPath?.hruid, | ||||||
|         classes: selectedClasses.map(cl => cl.value), |         classes: selectedClasses.map(cl => cl.value), | ||||||
|         groups: groups |         groups: groups, | ||||||
|  |         deadline: deadline | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     try { |     try { | ||||||
|  | @ -71,3 +73,21 @@ export const classesRules = [ | ||||||
|         return 'You must select at least one class.'; |         return 'You must select at least one class.'; | ||||||
|     }, |     }, | ||||||
| ]; | ]; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Validation rule for the deadline field. | ||||||
|  |  * | ||||||
|  |  * Ensures that a valid deadline is selected and is in the future. | ||||||
|  |  */ | ||||||
|  | export const deadlineRules = [ | ||||||
|  |     (value: string) => { | ||||||
|  |         if (!value) return 'You must set a deadline.'; | ||||||
|  | 
 | ||||||
|  |         const selectedDate = new Date(value); | ||||||
|  |         const now = new Date(); | ||||||
|  | 
 | ||||||
|  |         if (selectedDate <= now) return 'The deadline must be in the future.'; | ||||||
|  | 
 | ||||||
|  |         return true; | ||||||
|  |     }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
|  | @ -3,7 +3,8 @@ | ||||||
|     import {computed, onMounted, ref, watch} from "vue"; |     import {computed, onMounted, ref, watch} from "vue"; | ||||||
|     import GroupSelector from "@/components/GroupSelector.vue"; |     import GroupSelector from "@/components/GroupSelector.vue"; | ||||||
|     import {classes} from "@/utils/tempData.ts"; |     import {classes} from "@/utils/tempData.ts"; | ||||||
|     import {assignmentTitleRules, classesRules, learningPathRules, submitForm} from "@/utils/assignmentForm.ts";  // Assuming your tempData.ts has the required classes |     import {assignmentTitleRules, classesRules, learningPathRules, submitForm} from "@/utils/assignmentForm.ts"; | ||||||
|  |     import DeadlineSelector from "@/components/DeadlineSelector.vue"; | ||||||
| 
 | 
 | ||||||
|     const {t, locale} = useI18n(); |     const {t, locale} = useI18n(); | ||||||
| 
 | 
 | ||||||
|  | @ -12,6 +13,7 @@ | ||||||
|     const searchQuery = ref(''); |     const searchQuery = ref(''); | ||||||
| 
 | 
 | ||||||
|     const assignmentTitle = ref(''); |     const assignmentTitle = ref(''); | ||||||
|  |     const deadline = ref(null); | ||||||
|     const allLearningPaths = ref([]); |     const allLearningPaths = ref([]); | ||||||
|     const filteredLearningPaths = ref([]); |     const filteredLearningPaths = ref([]); | ||||||
|     const selectedLearningPath = ref(null); |     const selectedLearningPath = ref(null); | ||||||
|  | @ -79,7 +81,8 @@ | ||||||
|     onMounted(fetchAllLearningPaths); |     onMounted(fetchAllLearningPaths); | ||||||
| 
 | 
 | ||||||
|     const submitFormHandler = () => { |     const submitFormHandler = () => { | ||||||
|         submitForm(assignmentTitle.value, selectedLearningPath.value, selectedClasses.value, groups.value); |         console.log(deadline.value); | ||||||
|  |         submitForm(assignmentTitle.value, selectedLearningPath.value, selectedClasses.value, groups.value, deadline.value); | ||||||
|     }; |     }; | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
|  | @ -92,7 +95,7 @@ | ||||||
|                 <v-container class="step-container"> |                 <v-container class="step-container"> | ||||||
|                     <v-card-text> |                     <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="solo" clearable required></v-text-field> |                                       density="compact" variant="outlined" clearable required></v-text-field> | ||||||
|                     </v-card-text> |                     </v-card-text> | ||||||
| 
 | 
 | ||||||
|                     <v-card-text> |                     <v-card-text> | ||||||
|  | @ -101,7 +104,7 @@ | ||||||
|                             :items="searchResults" |                             :items="searchResults" | ||||||
|                             :label="t('choose-lp')" |                             :label="t('choose-lp')" | ||||||
|                             :rules="learningPathRules" |                             :rules="learningPathRules" | ||||||
|                             variant="solo" |                             variant="outlined" | ||||||
|                             clearable |                             clearable | ||||||
|                             hide-details |                             hide-details | ||||||
|                             density="compact" |                             density="compact" | ||||||
|  | @ -119,7 +122,7 @@ | ||||||
|                             :items="allClasses" |                             :items="allClasses" | ||||||
|                             :label="t('choose-classes')" |                             :label="t('choose-classes')" | ||||||
|                             :rules="classesRules" |                             :rules="classesRules" | ||||||
|                             variant="solo" |                             variant="outlined" | ||||||
|                             clearable |                             clearable | ||||||
|                             multiple |                             multiple | ||||||
|                             hide-details |                             hide-details | ||||||
|  | @ -132,6 +135,8 @@ | ||||||
|                         ></v-combobox> |                         ></v-combobox> | ||||||
|                     </v-card-text> |                     </v-card-text> | ||||||
| 
 | 
 | ||||||
|  |                     <DeadlineSelector v-model:deadline="deadline" /> | ||||||
|  | 
 | ||||||
|                     <h3>{{ t('create-groups') }}</h3> |                     <h3>{{ t('create-groups') }}</h3> | ||||||
| 
 | 
 | ||||||
|                     <GroupSelector |                     <GroupSelector | ||||||
|  | @ -147,7 +152,7 @@ | ||||||
|                     </v-card-text> |                     </v-card-text> | ||||||
| 
 | 
 | ||||||
|                 </v-container> |                 </v-container> | ||||||
|                 <v-btn class="mt-2" type="submit" block>Submit</v-btn> |                 <v-btn class="mt-2" color="secondary" type="submit" block>Submit</v-btn> | ||||||
|             </v-form> |             </v-form> | ||||||
|         </v-card> |         </v-card> | ||||||
|     </div> |     </div> | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Joyelle Ndagijimana
						Joyelle Ndagijimana