From 5998f715eede7c65017013195679ded9295e201b Mon Sep 17 00:00:00 2001 From: Matthias Seghers Date: Wed, 13 Mar 2024 19:19:29 +0100 Subject: [PATCH 1/3] de-duping + teacherLoader --- frontend/src/dataloaders/SharedFunctions.ts | 20 ++++++++++++++++++++ frontend/src/dataloaders/StudentLoader.ts | 13 +++---------- frontend/src/dataloaders/TeacherLoader.ts | 10 ++++++++++ frontend/src/main.tsx | 5 ++++- frontend/src/pages/teacher/HomeTeacher.tsx | 6 ++++++ 5 files changed, 43 insertions(+), 11 deletions(-) create mode 100644 frontend/src/dataloaders/SharedFunctions.ts create mode 100644 frontend/src/dataloaders/TeacherLoader.ts diff --git a/frontend/src/dataloaders/SharedFunctions.ts b/frontend/src/dataloaders/SharedFunctions.ts new file mode 100644 index 00000000..303c276c --- /dev/null +++ b/frontend/src/dataloaders/SharedFunctions.ts @@ -0,0 +1,20 @@ +import {Project, Subject} from "../utils/ApiInterfaces.ts"; +import apiFetch from "../utils/ApiFetch.ts"; + +export enum projectLoaderRole { + STUDENT = "student", + TEACHER = "teacher" +} + +export async function projectLoader(role: projectLoaderRole): Promise { + const projects: Project[] = await (await apiFetch(`/api/${role}/projects`)).json() as Project[]; + const subjects: Subject[] = await (await apiFetch(`/api/${role}/subjects`)).json() as Subject[]; + for (let i = 0; i < projects.length; i++) { + const subject: Subject | undefined = subjects.find(subject => subject.id === projects[i].subject_id); + if (subject !== undefined) { + projects[i].subject_name = subject.name; + } + } + // TODO: add submission data + return projects; +} diff --git a/frontend/src/dataloaders/StudentLoader.ts b/frontend/src/dataloaders/StudentLoader.ts index 891f5f71..d4907d05 100644 --- a/frontend/src/dataloaders/StudentLoader.ts +++ b/frontend/src/dataloaders/StudentLoader.ts @@ -1,18 +1,11 @@ -import apiFetch from "../utils/ApiFetch.ts"; -import {Project, Subject} from "../utils/ApiInterfaces.ts"; +import {Project} from "../utils/ApiInterfaces.ts"; +import {projectLoader, projectLoaderRole} from "./SharedFunctions.ts"; export interface studentLoaderObject { projects: Project[] } export default async function studentLoader(): Promise { - const projects: Project[] = await (await apiFetch("/api/student/projects")).json() as Project[]; - const subjects: Subject[] = await (await apiFetch("/api/student/subjects")).json() as Subject[]; - for (let i = 0; i < projects.length; i++) { - const subject: Subject | undefined = subjects.find(subject => subject.id === projects[i].subject_id); - if (subject !== undefined) { - projects[i].subject_name = subject.name; - } - } + const projects: Project[] = await projectLoader(projectLoaderRole.STUDENT); // TODO: add submission data return {"projects": projects}; } \ No newline at end of file diff --git a/frontend/src/dataloaders/TeacherLoader.ts b/frontend/src/dataloaders/TeacherLoader.ts new file mode 100644 index 00000000..ef11a008 --- /dev/null +++ b/frontend/src/dataloaders/TeacherLoader.ts @@ -0,0 +1,10 @@ +import {Project} from "../utils/ApiInterfaces.ts"; +import {projectLoader, projectLoaderRole} from "./SharedFunctions.ts"; + +export interface teacherLoaderObject { + projects: Project[] +} +export default async function teacherLoader(): Promise { + const projects: Project[] = await projectLoader(projectLoaderRole.TEACHER); + return {"projects": projects} +} \ No newline at end of file diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 15b215b1..eaca2efd 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -11,6 +11,7 @@ import HomeTeacher from "./pages/teacher/HomeTeacher.tsx"; import 'bulma/css/bulma.min.css'; import './assets/styles/mainpage.css' import studentLoader from "./dataloaders/StudentLoader.ts"; +import teacherLoader from "./dataloaders/TeacherLoader.ts"; const router = createBrowserRouter([ { @@ -34,7 +35,9 @@ const router = createBrowserRouter([ }, { path: "/teacher", - element: + element: , + id: "teacher", + loader: teacherLoader } ]); diff --git a/frontend/src/pages/teacher/HomeTeacher.tsx b/frontend/src/pages/teacher/HomeTeacher.tsx index 5ff9bbe1..4b42b601 100644 --- a/frontend/src/pages/teacher/HomeTeacher.tsx +++ b/frontend/src/pages/teacher/HomeTeacher.tsx @@ -1,6 +1,12 @@ import {JSX} from "react"; +import {teacherLoaderObject} from "../../dataloaders/TeacherLoader.ts"; +import {useRouteLoaderData} from "react-router-dom"; export default function HomeTeacher(): JSX.Element { + + const data: teacherLoaderObject = useRouteLoaderData("teacher") as teacherLoaderObject; + console.log(data); + return ( <>Homescreen for a teacher ) From 45be65a904d8883d69693f12e3276f823a40772e Mon Sep 17 00:00:00 2001 From: Matthias Seghers Date: Wed, 13 Mar 2024 23:06:04 +0100 Subject: [PATCH 2/3] subjectsTeacherDataLoader --- frontend/src/dataloaders/SharedFunctions.ts | 22 +++++++++++---- frontend/src/dataloaders/StudentLoader.ts | 4 +-- .../src/dataloaders/SubjectsTeacherLoader.ts | 27 +++++++++++++++++++ frontend/src/dataloaders/TeacherLoader.ts | 4 +-- frontend/src/main.tsx | 8 ++++++ .../src/pages/teacher/SubjectsTeacher.tsx | 13 +++++++++ frontend/src/utils/ApiFetch.ts | 1 + frontend/src/utils/ApiInterfaces.ts | 7 +++++ 8 files changed, 77 insertions(+), 9 deletions(-) create mode 100644 frontend/src/dataloaders/SubjectsTeacherLoader.ts create mode 100644 frontend/src/pages/teacher/SubjectsTeacher.tsx diff --git a/frontend/src/dataloaders/SharedFunctions.ts b/frontend/src/dataloaders/SharedFunctions.ts index 303c276c..44387ae9 100644 --- a/frontend/src/dataloaders/SharedFunctions.ts +++ b/frontend/src/dataloaders/SharedFunctions.ts @@ -1,20 +1,32 @@ import {Project, Subject} from "../utils/ApiInterfaces.ts"; import apiFetch from "../utils/ApiFetch.ts"; -export enum projectLoaderRole { +export enum teacherStudentRole { STUDENT = "student", TEACHER = "teacher" } -export async function projectLoader(role: projectLoaderRole): Promise { - const projects: Project[] = await (await apiFetch(`/api/${role}/projects`)).json() as Project[]; - const subjects: Subject[] = await (await apiFetch(`/api/${role}/subjects`)).json() as Subject[]; +export async function projectsLoader(role: teacherStudentRole): Promise { + const getter = await getAllProjectsAndSubjects(role); + const subjects = getter.subjects; + const projects = getter.projects; + // TODO: add submission data for (let i = 0; i < projects.length; i++) { const subject: Subject | undefined = subjects.find(subject => subject.id === projects[i].subject_id); if (subject !== undefined) { projects[i].subject_name = subject.name; } } - // TODO: add submission data return projects; } + +export interface projectsAndSubjects { + projects: Project[], + subjects: Subject[] +} + +export async function getAllProjectsAndSubjects(role: teacherStudentRole): Promise { + const projects: Project[] = await (await apiFetch(`/${role}/projects`)).json() as Project[]; + const subjects: Subject[] = await (await apiFetch(`/${role}/subjects`)).json() as Subject[]; + return {projects, subjects} +} diff --git a/frontend/src/dataloaders/StudentLoader.ts b/frontend/src/dataloaders/StudentLoader.ts index d4907d05..36d804db 100644 --- a/frontend/src/dataloaders/StudentLoader.ts +++ b/frontend/src/dataloaders/StudentLoader.ts @@ -1,11 +1,11 @@ import {Project} from "../utils/ApiInterfaces.ts"; -import {projectLoader, projectLoaderRole} from "./SharedFunctions.ts"; +import {projectsLoader, teacherStudentRole} from "./SharedFunctions.ts"; export interface studentLoaderObject { projects: Project[] } export default async function studentLoader(): Promise { - const projects: Project[] = await projectLoader(projectLoaderRole.STUDENT); + const projects: Project[] = await projectsLoader(teacherStudentRole.STUDENT); // TODO: add submission data return {"projects": projects}; } \ No newline at end of file diff --git a/frontend/src/dataloaders/SubjectsTeacherLoader.ts b/frontend/src/dataloaders/SubjectsTeacherLoader.ts new file mode 100644 index 00000000..87432a67 --- /dev/null +++ b/frontend/src/dataloaders/SubjectsTeacherLoader.ts @@ -0,0 +1,27 @@ +import {Project, properSubject, Subject} from "../utils/ApiInterfaces.ts"; +import {getAllProjectsAndSubjects, projectsAndSubjects, teacherStudentRole} from "./SharedFunctions.ts"; + +export interface subjectsTeacherLoaderObject { + subjects: properSubject[] +} + +export let SUBJECT_TEACHER_ID = "subjectTeacher"; + +export default async function subjectsTeacherLoader(): Promise { + const temp: projectsAndSubjects = await getAllProjectsAndSubjects(teacherStudentRole.TEACHER); + const subjects: Subject[] = temp.subjects; + const projects: Project[] = temp.projects; + + const p_subjects: properSubject[] = subjects.map(subject => { + const active_projects = projects.filter(project => + project.archived && project.subject_id === subject.id + ); + return { + id: subject.id, + name: subject.name, + active_projects: active_projects.length, + first_deadline: null // TODO: add deadlines when needed api endpoints are added. + }; + }); + return {"subjects": p_subjects} +} \ No newline at end of file diff --git a/frontend/src/dataloaders/TeacherLoader.ts b/frontend/src/dataloaders/TeacherLoader.ts index ef11a008..1be5fa07 100644 --- a/frontend/src/dataloaders/TeacherLoader.ts +++ b/frontend/src/dataloaders/TeacherLoader.ts @@ -1,10 +1,10 @@ import {Project} from "../utils/ApiInterfaces.ts"; -import {projectLoader, projectLoaderRole} from "./SharedFunctions.ts"; +import {projectsLoader, teacherStudentRole} from "./SharedFunctions.ts"; export interface teacherLoaderObject { projects: Project[] } export default async function teacherLoader(): Promise { - const projects: Project[] = await projectLoader(projectLoaderRole.TEACHER); + const projects: Project[] = await projectsLoader(teacherStudentRole.TEACHER); return {"projects": projects} } \ No newline at end of file diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index eaca2efd..6dd6346b 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -12,6 +12,8 @@ import 'bulma/css/bulma.min.css'; import './assets/styles/mainpage.css' import studentLoader from "./dataloaders/StudentLoader.ts"; import teacherLoader from "./dataloaders/TeacherLoader.ts"; +import SubjectsTeacher from "./pages/teacher/SubjectsTeacher.tsx"; +import subjectsTeacherLoader, {SUBJECT_TEACHER_ID} from "./dataloaders/SubjectsTeacherLoader.ts"; const router = createBrowserRouter([ { @@ -38,6 +40,12 @@ const router = createBrowserRouter([ element: , id: "teacher", loader: teacherLoader + }, + { + path: "/teacher/courses", + element: , + id: SUBJECT_TEACHER_ID, + loader: subjectsTeacherLoader } ]); diff --git a/frontend/src/pages/teacher/SubjectsTeacher.tsx b/frontend/src/pages/teacher/SubjectsTeacher.tsx new file mode 100644 index 00000000..30075e0a --- /dev/null +++ b/frontend/src/pages/teacher/SubjectsTeacher.tsx @@ -0,0 +1,13 @@ +import {JSX} from "react"; +import {SUBJECT_TEACHER_ID, subjectsTeacherLoaderObject} from "../../dataloaders/SubjectsTeacherLoader.ts"; +import {useRouteLoaderData} from "react-router-dom"; + +export default function SubjectsTeacher(): JSX.Element { + + const data: subjectsTeacherLoaderObject = useRouteLoaderData(SUBJECT_TEACHER_ID) as subjectsTeacherLoaderObject; + console.log(data); + + return( +

hier ziet de lkr al zijn vakken.

+ ) +} \ No newline at end of file diff --git a/frontend/src/utils/ApiFetch.ts b/frontend/src/utils/ApiFetch.ts index c9cd8772..c02c9282 100644 --- a/frontend/src/utils/ApiFetch.ts +++ b/frontend/src/utils/ApiFetch.ts @@ -4,6 +4,7 @@ export default function apiFetch(url: string, options?: RequestInit) { if (typeof options === 'undefined') { options = {} } + url = "/api" + url; if (DEBUG) { url = "http://127.0.0.1:8000" + url; } diff --git a/frontend/src/utils/ApiInterfaces.ts b/frontend/src/utils/ApiInterfaces.ts index 60048858..5eda68ef 100644 --- a/frontend/src/utils/ApiInterfaces.ts +++ b/frontend/src/utils/ApiInterfaces.ts @@ -15,3 +15,10 @@ export interface Project { subject_id: number, subject_name: string | undefined | null } + +export interface properSubject { + id: number, + name: string, + active_projects: number, + first_deadline: Date | null | string +} \ No newline at end of file From 455a8821a97ffb076080aac8309dcb2f6a96a088 Mon Sep 17 00:00:00 2001 From: Matthias Seghers Date: Wed, 13 Mar 2024 23:10:34 +0100 Subject: [PATCH 3/3] made router ID's a var to avoid typos --- frontend/src/dataloaders/StudentLoader.ts | 4 ++++ frontend/src/dataloaders/SubjectsTeacherLoader.ts | 2 +- frontend/src/dataloaders/TeacherLoader.ts | 3 +++ frontend/src/main.tsx | 12 ++++++------ frontend/src/pages/student/HomeStudent.tsx | 4 ++-- frontend/src/pages/teacher/HomeTeacher.tsx | 4 ++-- frontend/src/pages/teacher/SubjectsTeacher.tsx | 4 ++-- 7 files changed, 20 insertions(+), 13 deletions(-) diff --git a/frontend/src/dataloaders/StudentLoader.ts b/frontend/src/dataloaders/StudentLoader.ts index 36d804db..39dd96d0 100644 --- a/frontend/src/dataloaders/StudentLoader.ts +++ b/frontend/src/dataloaders/StudentLoader.ts @@ -4,6 +4,10 @@ import {projectsLoader, teacherStudentRole} from "./SharedFunctions.ts"; export interface studentLoaderObject { projects: Project[] } + +export const STUDENT_ROUTER_ID = "student"; + + export default async function studentLoader(): Promise { const projects: Project[] = await projectsLoader(teacherStudentRole.STUDENT); // TODO: add submission data diff --git a/frontend/src/dataloaders/SubjectsTeacherLoader.ts b/frontend/src/dataloaders/SubjectsTeacherLoader.ts index 87432a67..e5c066a1 100644 --- a/frontend/src/dataloaders/SubjectsTeacherLoader.ts +++ b/frontend/src/dataloaders/SubjectsTeacherLoader.ts @@ -5,7 +5,7 @@ export interface subjectsTeacherLoaderObject { subjects: properSubject[] } -export let SUBJECT_TEACHER_ID = "subjectTeacher"; +export const SUBJECT_TEACHER_ROUTER_ID = "subjectTeacher"; export default async function subjectsTeacherLoader(): Promise { const temp: projectsAndSubjects = await getAllProjectsAndSubjects(teacherStudentRole.TEACHER); diff --git a/frontend/src/dataloaders/TeacherLoader.ts b/frontend/src/dataloaders/TeacherLoader.ts index 1be5fa07..da3e74ca 100644 --- a/frontend/src/dataloaders/TeacherLoader.ts +++ b/frontend/src/dataloaders/TeacherLoader.ts @@ -4,6 +4,9 @@ import {projectsLoader, teacherStudentRole} from "./SharedFunctions.ts"; export interface teacherLoaderObject { projects: Project[] } + +export const TEACHER_ROUTER_ID = "teacher"; + export default async function teacherLoader(): Promise { const projects: Project[] = await projectsLoader(teacherStudentRole.TEACHER); return {"projects": projects} diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 6dd6346b..29f90a54 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -10,10 +10,10 @@ import HomeStudent from "./pages/student/HomeStudent.tsx"; import HomeTeacher from "./pages/teacher/HomeTeacher.tsx"; import 'bulma/css/bulma.min.css'; import './assets/styles/mainpage.css' -import studentLoader from "./dataloaders/StudentLoader.ts"; -import teacherLoader from "./dataloaders/TeacherLoader.ts"; +import studentLoader, {STUDENT_ROUTER_ID} from "./dataloaders/StudentLoader.ts"; +import teacherLoader, {TEACHER_ROUTER_ID} from "./dataloaders/TeacherLoader.ts"; import SubjectsTeacher from "./pages/teacher/SubjectsTeacher.tsx"; -import subjectsTeacherLoader, {SUBJECT_TEACHER_ID} from "./dataloaders/SubjectsTeacherLoader.ts"; +import subjectsTeacherLoader, {SUBJECT_TEACHER_ROUTER_ID} from "./dataloaders/SubjectsTeacherLoader.ts"; const router = createBrowserRouter([ { @@ -32,19 +32,19 @@ const router = createBrowserRouter([ { path: "/student", element: , - id: "student", + id: STUDENT_ROUTER_ID, loader: studentLoader }, { path: "/teacher", element: , - id: "teacher", + id: TEACHER_ROUTER_ID, loader: teacherLoader }, { path: "/teacher/courses", element: , - id: SUBJECT_TEACHER_ID, + id: SUBJECT_TEACHER_ROUTER_ID, loader: subjectsTeacherLoader } ]); diff --git a/frontend/src/pages/student/HomeStudent.tsx b/frontend/src/pages/student/HomeStudent.tsx index d53fa306..6a32fb36 100644 --- a/frontend/src/pages/student/HomeStudent.tsx +++ b/frontend/src/pages/student/HomeStudent.tsx @@ -4,12 +4,12 @@ import {Sidebar} from "../../components/Sidebar.tsx"; import ProjectCardStudent from "./ProjectCardStudent.tsx"; import '../../assets/styles/students_components.css' import {useRouteLoaderData} from "react-router-dom"; -import {studentLoaderObject} from "../../dataloaders/StudentLoader.ts"; +import {STUDENT_ROUTER_ID, studentLoaderObject} from "../../dataloaders/StudentLoader.ts"; export default function HomeStudent(): JSX.Element { // data contains a list of Project in data.projects (i think) - const data: studentLoaderObject = useRouteLoaderData("student") as studentLoaderObject + const data: studentLoaderObject = useRouteLoaderData(STUDENT_ROUTER_ID) as studentLoaderObject console.log(data) // TODO: remove return ( diff --git a/frontend/src/pages/teacher/HomeTeacher.tsx b/frontend/src/pages/teacher/HomeTeacher.tsx index 4b42b601..b38a8b1c 100644 --- a/frontend/src/pages/teacher/HomeTeacher.tsx +++ b/frontend/src/pages/teacher/HomeTeacher.tsx @@ -1,10 +1,10 @@ import {JSX} from "react"; -import {teacherLoaderObject} from "../../dataloaders/TeacherLoader.ts"; +import {TEACHER_ROUTER_ID, teacherLoaderObject} from "../../dataloaders/TeacherLoader.ts"; import {useRouteLoaderData} from "react-router-dom"; export default function HomeTeacher(): JSX.Element { - const data: teacherLoaderObject = useRouteLoaderData("teacher") as teacherLoaderObject; + const data: teacherLoaderObject = useRouteLoaderData(TEACHER_ROUTER_ID) as teacherLoaderObject; console.log(data); return ( diff --git a/frontend/src/pages/teacher/SubjectsTeacher.tsx b/frontend/src/pages/teacher/SubjectsTeacher.tsx index 30075e0a..ef214a2b 100644 --- a/frontend/src/pages/teacher/SubjectsTeacher.tsx +++ b/frontend/src/pages/teacher/SubjectsTeacher.tsx @@ -1,10 +1,10 @@ import {JSX} from "react"; -import {SUBJECT_TEACHER_ID, subjectsTeacherLoaderObject} from "../../dataloaders/SubjectsTeacherLoader.ts"; +import {SUBJECT_TEACHER_ROUTER_ID, subjectsTeacherLoaderObject} from "../../dataloaders/SubjectsTeacherLoader.ts"; import {useRouteLoaderData} from "react-router-dom"; export default function SubjectsTeacher(): JSX.Element { - const data: subjectsTeacherLoaderObject = useRouteLoaderData(SUBJECT_TEACHER_ID) as subjectsTeacherLoaderObject; + const data= useRouteLoaderData(SUBJECT_TEACHER_ROUTER_ID) as subjectsTeacherLoaderObject; console.log(data); return(