Skip to content

Commit

Permalink
chore: abstracted the dashboard as example for future views
Browse files Browse the repository at this point in the history
  • Loading branch information
EwoutV committed Apr 2, 2024
1 parent f9a47d4 commit f8c61cc
Show file tree
Hide file tree
Showing 15 changed files with 217 additions and 203 deletions.
11 changes: 10 additions & 1 deletion frontend/src/components/YearSelector.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,21 @@
<script setup lang="ts">
import Dropdown from 'primevue/dropdown';
import { useI18n } from 'vue-i18n';
import { computed } from 'vue';
/* Composable injections */
const { t } = useI18n();
/* Props */
defineProps<{ years: string[] }>();
const props = defineProps<{ years: number[] }>();
/* State */
const years = computed(() =>
props.years.map((year) => ({
label: `${year} - ${year + 1}`,
value: year
}))
);
/* Models */
const year = defineModel();
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/projects/GroupCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { useStudents } from '@/composables/services/students.service.ts';
import { onMounted } from 'vue';
import { useI18n } from 'vue-i18n';
import { Group } from '@/types/Group.ts';
import { type Group } from '@/types/Group.ts';
/* Props */
const props = defineProps<{
Expand Down
8 changes: 3 additions & 5 deletions frontend/src/components/projects/ProjectCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { PrimeIcons } from 'primevue/api';
import { useI18n } from 'vue-i18n';
import { computed } from 'vue';
import moment from 'moment';
import { Course } from '@/types/Course.ts';
import { type Course } from '@/types/Course.ts';
/**
* TODO
Expand All @@ -20,7 +20,7 @@ const props = defineProps<{
}>();
const formattedDeadline = computed(() => {
return moment(props.project.deadline).format("DD MMMM YYYY")
return moment(props.project.deadline).format('DD MMMM YYYY');
});
/* Composable injections */
Expand All @@ -30,9 +30,7 @@ const { t } = useI18n();
<template>
<Card class="border-round project-card">
<template #header>
<h2 class="text-primary m-0 text-2xl">
<span class="pi pi-book text-xl mr-2"/> {{ course.name }}
</h2>
<h2 class="text-primary m-0 text-2xl"><span class="pi pi-book text-xl mr-2" /> {{ course.name }}</h2>
</template>
<template #subtitle>
{{ project.name }}
Expand Down
124 changes: 62 additions & 62 deletions frontend/src/components/projects/ProjectList.vue
Original file line number Diff line number Diff line change
@@ -1,62 +1,62 @@
<script setup lang="ts">
import { Course } from '@/types/Course.ts';
import { watch } from 'vue';
import { useProject } from '@/composables/services/project.service.ts';
import ProjectCard from '@/components/projects/ProjectCard.vue';
import { useI18n } from 'vue-i18n';
/* Props */
const props = withDefaults(defineProps<{
courses: Course[];
}>(), {
courses: []
});
/* Composables */
const { t } = useI18n();
const { projects, getProjectsByCourse } = useProject();
watch(
() => props.courses,
async (courses: Course[]) => {
for (const course of courses) {
// Fetch the projects for the course
await getProjectsByCourse(course.id);
// Assign the course to the projects
projects.value?.forEach((project) => {
project.course = course;
});
// Assign the projects to the course
course.projects = projects.value ?? [];
}
},
{
immediate: true,
},
);
</script>

<template>
<template v-if="courses.length > 0">
<div class="grid align-items-stretch">
<div
class="col-12 md:col-6 lg:col-4 xl:col-3"
v-for="project in courses.flatMap((course) => course.projects)"
:key="project.id"
>
<ProjectCard class="h-100" :project="project" :course="project.course" />
</div>
</div>
</template>
<template v-else>
<div class="col-12">
<p>{{ t('views.dashboard.no_projects') }}</p>
</div>
</template>
</template>

<style scoped lang="scss">
</style>
<script setup lang="ts">
import { type Course } from '@/types/Course.ts';
import { watch } from 'vue';
import { useProject } from '@/composables/services/project.service.ts';
import ProjectCard from '@/components/projects/ProjectCard.vue';
import { useI18n } from 'vue-i18n';
/* Props */
const props = withDefaults(
defineProps<{
courses: Course[];
}>(),
{
courses: () => [],
},
);
/* Composables */
const { t } = useI18n();
const { projects, getProjectsByCourse } = useProject();
watch(
() => props.courses,
async (courses: Course[]) => {
for (const course of courses) {
// Fetch the projects for the course
await getProjectsByCourse(course.id);
// Assign the course to the projects
projects.value?.forEach((project) => {
project.course = course;
});
// Assign the projects to the course
course.projects = projects.value ?? [];
}
},
{
immediate: true,
},
);
</script>

<template>
<template v-if="courses.length > 0">
<div class="grid align-items-stretch">
<div
class="col-12 md:col-6 lg:col-4 xl:col-3"
v-for="project in courses.flatMap((course) => course.projects)"
:key="project.id">
<ProjectCard class="h-100" :project="project" :course="project.course" />
</div>
</div>
</template>
<template v-else>
<div class="col-12">
<p>{{ t('views.dashboard.no_projects') }}</p>
</div>
</template>
</template>

<style scoped lang="scss"></style>
4 changes: 2 additions & 2 deletions frontend/src/composables/services/assistant.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,8 @@ export function useAssistant(): AssistantState {
await deleteId<Assistant>(endpoint, assistant, Assistant.fromJSON);
}

async function initAssistant(assistant: Assistant|null) {
if (assistant !== null) {
async function initAssistant(assistant: Assistant | null): Promise<void> {
if (assistant !== null) {
await getCourseByAssistant(assistant.id);
assistant.courses = courses.value ?? [];
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/composables/services/students.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,8 @@ export function useStudents(): StudentsState {
await deleteId<Student>(endpoint, student, Student.fromJSON);
}

async function initStudent(student: Student|null) {
if (student !== null) {
async function initStudent(student: Student | null): Promise<void> {
if (student !== null) {
await getCoursesByStudent(student.id);
student.courses = courses.value ?? [];
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/composables/services/teachers.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ export function useTeacher(): TeacherState {
await deleteId<Teacher>(endpoint, teacher, Teacher.fromJSON);
}

async function initTeacher(teacher: Teacher|null) {
if (teacher !== null) {
async function initTeacher(teacher: Teacher | null): Promise<void> {
if (teacher !== null) {
await getCoursesByTeacher(teacher.id);
teacher.courses = courses.value ?? [];
}
Expand Down
5 changes: 4 additions & 1 deletion frontend/src/store/authentication.store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,10 @@ export const useAuthStore = defineStore('auth', () => {
});

return {
user, student, teacher, assistant,
user,
student,
teacher,
assistant,
view,
intent,
login,
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/types/users/Student.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class Student extends User {
public roles: Role[] = [],
public courses: Course[] = [],
public groups: Group[] = [],
public faculties: Faculty[] = []
public faculties: Faculty[] = [],
) {
super(id, username, email, first_name, last_name, last_enrolled, is_staff, roles, faculties, create_time, last_login);
}
Expand Down
26 changes: 26 additions & 0 deletions frontend/src/types/users/User.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ export class User {
public last_login: Date | null,
) {}

/**
* Get the academic years of the user.
*/
get academic_years(): number[] {
const startYear = this.getAcademicYear(this.create_time);
const endYear = this.getAcademicYear(new Date());

return Array.from({ length: endYear - startYear + 1 }, (_, i) => startYear + i);
}

/**
* Get the full name of the user.
*
Expand All @@ -26,6 +36,22 @@ export class User {
return `${this.first_name} ${this.last_name}`;
}

/**
* Get the academic year of a date.
*
* @param date
* @returns number
*/
public getAcademicYear(date: Date = new Date): number {
const year = date.getFullYear();

if (date.getMonth() >= 9) {
return year;
}

return year - 1;
}

/**
* Check if the user is a student.
*
Expand Down
11 changes: 11 additions & 0 deletions frontend/src/views/courses/roles/StudentCourseView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>

<template>

</template>

<style scoped lang="scss">
</style>
11 changes: 11 additions & 0 deletions frontend/src/views/courses/roles/TeacherCourseView.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<script setup lang="ts">
</script>

<template>

</template>

<style scoped lang="scss">
</style>
Loading

0 comments on commit f8c61cc

Please sign in to comment.