feat: component om een groep aan te maken
This commit is contained in:
		
							parent
							
								
									35faf7a80c
								
							
						
					
					
						commit
						05fa69f0c7
					
				
					 2 changed files with 81 additions and 12 deletions
				
			
		
							
								
								
									
										41
									
								
								frontend/src/components/GroupSelector.vue
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										41
									
								
								frontend/src/components/GroupSelector.vue
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,41 @@ | ||||||
|  | <script setup lang="ts"> | ||||||
|  |     import { ref, defineProps, defineEmits } from 'vue'; | ||||||
|  |     import { useI18n } from 'vue-i18n'; | ||||||
|  | 
 | ||||||
|  |     const props = defineProps({ | ||||||
|  |         students: Array, | ||||||
|  |     }); | ||||||
|  |     const emit = defineEmits(['groupCreated']); | ||||||
|  |     const { t } = useI18n(); | ||||||
|  |     const selectedStudents = ref([]); | ||||||
|  | 
 | ||||||
|  |     const createGroup = () => { | ||||||
|  |         if (selectedStudents.value.length) { | ||||||
|  |             emit('groupCreated', selectedStudents.value); | ||||||
|  |             selectedStudents.value = []; // Reset selection after creating group | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | </script> | ||||||
|  | 
 | ||||||
|  | <template> | ||||||
|  |     <v-card-text> | ||||||
|  |         <v-combobox | ||||||
|  |             v-model="selectedStudents" | ||||||
|  |             :items="props.students" | ||||||
|  |             :label="t('choose-groups')" | ||||||
|  |             variant="solo" | ||||||
|  |             clearable | ||||||
|  |             multiple | ||||||
|  |             hide-details | ||||||
|  |             chips | ||||||
|  |             append-inner-icon="mdi-magnify" | ||||||
|  |             item-title="title" | ||||||
|  |             item-value="value" | ||||||
|  |         ></v-combobox> | ||||||
|  |         <v-btn @click="createGroup" color="primary" class="mt-2" size="small">{{ t('create-group') }}</v-btn> | ||||||
|  |     </v-card-text> | ||||||
|  | </template> | ||||||
|  | 
 | ||||||
|  | <style scoped> | ||||||
|  | 
 | ||||||
|  | </style> | ||||||
|  | @ -1,25 +1,21 @@ | ||||||
| <script setup lang="ts"> | <script setup lang="ts"> | ||||||
|     import {useI18n} from "vue-i18n"; |     import {useI18n} from "vue-i18n"; | ||||||
|     import {computed, onMounted, ref, watch} from "vue"; |     import {computed, onMounted, ref, watch} from "vue"; | ||||||
|  |     import GroupSelector from "@/components/GroupSelector.vue"; | ||||||
| 
 | 
 | ||||||
|     const {t, locale} = useI18n(); |     const {t, locale} = useI18n(); | ||||||
| 
 | 
 | ||||||
|     const language = ref(locale.value); |     const language = ref(locale.value); | ||||||
| 
 | 
 | ||||||
|     // If this value is set to true, the search bar will display a "loading" animation |  | ||||||
|     const loading = ref(false); |  | ||||||
|     const searchQuery = ref(""); |     const searchQuery = ref(""); | ||||||
| 
 | 
 | ||||||
|     // Store all learning paths |  | ||||||
|     const allLearningPaths = ref([]); |     const allLearningPaths = ref([]); | ||||||
| 
 |  | ||||||
|     // Filtered learning paths that will be displayed in the search bar dropdown |  | ||||||
|     const filteredLearningPaths = ref([]); |     const filteredLearningPaths = ref([]); | ||||||
| 
 |  | ||||||
|     // The hruid and title of the currently selected learning path(TODO: use for post req) |  | ||||||
|     const selectedLearningPath = ref(null); |     const selectedLearningPath = ref(null); | ||||||
| 
 |     const allClasses = ref(["f", "r"]); | ||||||
|     const selectedClasses = ref([]); |     const selectedClasses = ref([]); | ||||||
|  |     const allStudents = ref([]); // Fetched students from each selected class | ||||||
|  |     const groups = ref<string[][]>([]);  // Each group is a list of student {names, id's} | ||||||
| 
 | 
 | ||||||
|     // Fetch all learning paths initially |     // Fetch all learning paths initially | ||||||
|     async function fetchAllLearningPaths() { |     async function fetchAllLearningPaths() { | ||||||
|  | @ -63,11 +59,21 @@ | ||||||
|         ); |         ); | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     const classes = computed(() => ["f", "r"]); |  | ||||||
| 
 |  | ||||||
|     // Fetch all learning paths on mount |     // Fetch all learning paths on mount | ||||||
|     onMounted(fetchAllLearningPaths); |     onMounted(fetchAllLearningPaths); | ||||||
| 
 | 
 | ||||||
|  |     // All students that aren't already in a group | ||||||
|  |     const availableStudents = computed(() => { | ||||||
|  |         const groupedStudents = new Set(groups.value.flat()); | ||||||
|  |         return allStudents.value.filter(student => !groupedStudents.has(student)); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const addGroupToList = (students: string[]) => { | ||||||
|  |         if (students.length) { | ||||||
|  |             groups.value.push(students); | ||||||
|  |         } | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
| </script> | </script> | ||||||
| 
 | 
 | ||||||
| <template> | <template> | ||||||
|  | @ -85,7 +91,6 @@ | ||||||
|                             clearable |                             clearable | ||||||
|                             hide-details |                             hide-details | ||||||
|                             density="compact" |                             density="compact" | ||||||
|                             :loading="loading" |  | ||||||
|                             append-inner-icon="mdi-magnify" |                             append-inner-icon="mdi-magnify" | ||||||
|                             item-title="title" |                             item-title="title" | ||||||
|                             item-value="value" |                             item-value="value" | ||||||
|  | @ -96,7 +101,7 @@ | ||||||
|                     <v-card-text> |                     <v-card-text> | ||||||
|                         <v-combobox |                         <v-combobox | ||||||
|                             v-model="selectedClasses" |                             v-model="selectedClasses" | ||||||
|                             :items="classes" |                             :items="allClasses" | ||||||
|                             :label="t('choose-classes')" |                             :label="t('choose-classes')" | ||||||
|                             variant="solo" |                             variant="solo" | ||||||
|                             clearable |                             clearable | ||||||
|  | @ -109,6 +114,29 @@ | ||||||
|                         ></v-combobox> |                         ></v-combobox> | ||||||
|                     </v-card-text> |                     </v-card-text> | ||||||
| 
 | 
 | ||||||
|  |                     <v-container> | ||||||
|  |                         <h3>{{ t('create-groups') }}</h3> | ||||||
|  | 
 | ||||||
|  |                         <GroupSelector | ||||||
|  |                             :students="availableStudents" | ||||||
|  |                             @groupCreated="addGroupToList" | ||||||
|  |                         /> | ||||||
|  | 
 | ||||||
|  |                         <!-- Counter for created groups --> | ||||||
|  |                         <v-card-text v-if="groups.length"> | ||||||
|  |                             <strong>{{ t('created-groups') }}: {{ groups.length }}</strong> | ||||||
|  |                         </v-card-text> | ||||||
|  | 
 | ||||||
|  |                         <!-- Display created groups --> | ||||||
|  |                         <v-card-text v-if="groups.length"> | ||||||
|  |                             <ul> | ||||||
|  |                                 <li v-for="(group, index) in groups" :key="index"> | ||||||
|  |                                     {{ group.join(', ') }} | ||||||
|  |                                 </li> | ||||||
|  |                             </ul> | ||||||
|  |                         </v-card-text> | ||||||
|  |                     </v-container> | ||||||
|  | 
 | ||||||
|                 </v-container> |                 </v-container> | ||||||
|                 <v-btn class="mt-2" type="submit" block>Submit</v-btn> |                 <v-btn class="mt-2" type="submit" block>Submit</v-btn> | ||||||
|             </v-form> |             </v-form> | ||||||
|  |  | ||||||
		Reference in a new issue
	
	 Joyelle Ndagijimana
						Joyelle Ndagijimana