From 6997e29da1aa94bf4c5c7eb23ced37fe30b55a88 Mon Sep 17 00:00:00 2001 From: Gabriellvl Date: Wed, 14 May 2025 11:00:23 +0200 Subject: [PATCH 01/12] fix: class link naar hoofdletter in backend --- backend/src/controllers/students.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/controllers/students.ts b/backend/src/controllers/students.ts index 229cff7e..e4c49683 100644 --- a/backend/src/controllers/students.ts +++ b/backend/src/controllers/students.ts @@ -113,7 +113,7 @@ export async function createStudentRequestHandler(req: Request, res: Response): const classId = req.body.classId; requireFields({ username, classId }); - const request = await createClassJoinRequest(username, classId); + const request = await createClassJoinRequest(username, classId.toUpperCase()); res.json({ request }); } From c0b0e01eeacdd6722a85eb334ce3b398214ef0d1 Mon Sep 17 00:00:00 2001 From: Gabriellvl Date: Wed, 14 May 2025 11:01:04 +0200 Subject: [PATCH 02/12] feat: onthou link voor redirect naar login --- frontend/src/router/index.ts | 4 ++++ frontend/src/views/CallbackPage.vue | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 359eab1a..001738e4 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -143,6 +143,10 @@ router.beforeEach(async (to, _from, next) => { // Verify if user is logged in before accessing certain routes if (to.meta.requiresAuth) { if (!authService.isLoggedIn.value && !(await authService.loadUser())) { + const path = to.fullPath + if (path !== "/") { + localStorage.setItem("redirectAfterLogin", path); + } next("/login"); } else { next(); diff --git a/frontend/src/views/CallbackPage.vue b/frontend/src/views/CallbackPage.vue index cd004eae..f554096a 100644 --- a/frontend/src/views/CallbackPage.vue +++ b/frontend/src/views/CallbackPage.vue @@ -10,10 +10,21 @@ const errorMessage: Ref = ref(null); + async function redirectPage() { + const redirectUrl = localStorage.getItem("redirectAfterLogin"); + if (redirectUrl) { + console.log("redirect", redirectUrl); + localStorage.removeItem("redirectAfterLogin"); + await router.replace(redirectUrl); + } else { + await router.replace("/user"); // Redirect to theme page + } + } + onMounted(async () => { try { await auth.handleLoginCallback(); - await router.replace("/user"); // Redirect to theme page + await redirectPage(); } catch (error) { errorMessage.value = `${t("loginUnexpectedError")}: ${error}`; } From 5bd5748706ebd054fe994d7122f8d78a1268df43 Mon Sep 17 00:00:00 2001 From: Gabriellvl Date: Wed, 14 May 2025 11:02:25 +0200 Subject: [PATCH 03/12] feat: query in link, laad klas code in + fix: regex fix --- frontend/src/views/classes/StudentClasses.vue | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/frontend/src/views/classes/StudentClasses.vue b/frontend/src/views/classes/StudentClasses.vue index 0b5bb0ac..cadc8f63 100644 --- a/frontend/src/views/classes/StudentClasses.vue +++ b/frontend/src/views/classes/StudentClasses.vue @@ -2,7 +2,7 @@ import { useI18n } from "vue-i18n"; import authState from "@/services/auth/auth-service.ts"; import { computed, onMounted, ref } from "vue"; - import { validate, version } from "uuid"; + import { useRoute } from "vue-router"; import type { ClassDTO } from "@dwengo-1/common/interfaces/class"; import { useCreateJoinRequestMutation, useStudentClassesQuery } from "@/queries/students"; import type { StudentDTO } from "@dwengo-1/common/interfaces/student"; @@ -15,6 +15,7 @@ import "../../assets/common.css"; const { t } = useI18n(); + const route = useRoute(); // Username of logged in student const username = ref(undefined); @@ -38,6 +39,11 @@ } finally { isLoading.value = false; } + + const queryCode = route.query.code as string | undefined; + if (queryCode) { + code.value = queryCode; + } }); // Fetch all classes of the logged in student @@ -75,11 +81,15 @@ // The code a student sends in to join a class needs to be formatted as v4 to be valid // These rules are used to display a message to the user if they use a code that has an invalid format + function codeRegex(value: string){ + return /^[a-zA-Z0-9]{6}$/.test(value) + } + const codeRules = [ (value: string | undefined): string | boolean => { if (value === undefined || value === "") { return true; - } else if (value !== undefined && validate(value) && version(value) === 4) { + } else if (codeRegex(value)) { return true; } return t("invalidFormat"); @@ -92,7 +102,7 @@ // Function called when a student submits a code to join a class function submitCode(): void { // Check if the code is valid - if (code.value !== undefined && validate(code.value) && version(code.value) === 4) { + if (code.value !== undefined && codeRegex(code.value)) { mutate( { username: username.value!, classId: code.value }, { @@ -260,7 +270,7 @@ From acac6402d785541218cd17af595780a03ddb421c Mon Sep 17 00:00:00 2001 From: Gabriellvl Date: Wed, 14 May 2025 11:02:58 +0200 Subject: [PATCH 04/12] feat: copy link --- frontend/src/views/classes/TeacherClasses.vue | 93 ++++++++++++------- 1 file changed, 62 insertions(+), 31 deletions(-) diff --git a/frontend/src/views/classes/TeacherClasses.vue b/frontend/src/views/classes/TeacherClasses.vue index 3ca32264..0f5b35c1 100644 --- a/frontend/src/views/classes/TeacherClasses.vue +++ b/frontend/src/views/classes/TeacherClasses.vue @@ -132,17 +132,13 @@ // Show the teacher, copying of the code was a successs const copied = ref(false); - // Copy the generated code to the clipboard - async function copyToClipboard(): Promise { - await navigator.clipboard.writeText(code.value); - copied.value = true; - } + async function copyToClipboard(code: string, isDialog: boolean = false, isLink: boolean = false): Promise { + const content = isLink ? `${window.location.origin}/user/class?code=${code}` : code; + await navigator.clipboard.writeText(content); + copied.value = isDialog; - async function copyCode(selectedCode: string): Promise { - code.value = selectedCode; - await copyToClipboard(); - showSnackbar(t("copied"), "white"); - copied.value = false; + if (!isDialog) + showSnackbar(t("copied"), "white"); } // Custom breakpoints @@ -235,20 +231,25 @@ - - {{ c.id }} - - + + + {{ c.id }} + + + mdi-link-variant + + + + + {{ c.students.length }} @@ -310,14 +311,29 @@ max-width="400px" > - code + {{ t("code") }} + > + +
+ > + +
Date: Wed, 14 May 2025 11:14:41 +0200 Subject: [PATCH 05/12] fix: lint --- frontend/src/views/CallbackPage.vue | 3 +-- frontend/src/views/classes/StudentClasses.vue | 2 +- frontend/src/views/classes/TeacherClasses.vue | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/frontend/src/views/CallbackPage.vue b/frontend/src/views/CallbackPage.vue index f554096a..d07a3003 100644 --- a/frontend/src/views/CallbackPage.vue +++ b/frontend/src/views/CallbackPage.vue @@ -10,10 +10,9 @@ const errorMessage: Ref = ref(null); - async function redirectPage() { + async function redirectPage(): Promise { const redirectUrl = localStorage.getItem("redirectAfterLogin"); if (redirectUrl) { - console.log("redirect", redirectUrl); localStorage.removeItem("redirectAfterLogin"); await router.replace(redirectUrl); } else { diff --git a/frontend/src/views/classes/StudentClasses.vue b/frontend/src/views/classes/StudentClasses.vue index cadc8f63..d943b57a 100644 --- a/frontend/src/views/classes/StudentClasses.vue +++ b/frontend/src/views/classes/StudentClasses.vue @@ -81,7 +81,7 @@ // The code a student sends in to join a class needs to be formatted as v4 to be valid // These rules are used to display a message to the user if they use a code that has an invalid format - function codeRegex(value: string){ + function codeRegex(value: string): boolean { return /^[a-zA-Z0-9]{6}$/.test(value) } diff --git a/frontend/src/views/classes/TeacherClasses.vue b/frontend/src/views/classes/TeacherClasses.vue index 0f5b35c1..ea3a2441 100644 --- a/frontend/src/views/classes/TeacherClasses.vue +++ b/frontend/src/views/classes/TeacherClasses.vue @@ -132,7 +132,7 @@ // Show the teacher, copying of the code was a successs const copied = ref(false); - async function copyToClipboard(code: string, isDialog: boolean = false, isLink: boolean = false): Promise { + async function copyToClipboard(code: string, isDialog = false, isLink = false): Promise { const content = isLink ? `${window.location.origin}/user/class?code=${code}` : code; await navigator.clipboard.writeText(content); copied.value = isDialog; From bdd102b937df3d91c05aa8ba5c2cf89b40e19317 Mon Sep 17 00:00:00 2001 From: Lint Action Date: Wed, 14 May 2025 09:42:34 +0000 Subject: [PATCH 06/12] style: fix linting issues met Prettier --- frontend/src/router/index.ts | 2 +- frontend/src/views/classes/StudentClasses.vue | 2 +- frontend/src/views/classes/TeacherClasses.vue | 16 ++++++++++++---- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts index 001738e4..c87c88d2 100644 --- a/frontend/src/router/index.ts +++ b/frontend/src/router/index.ts @@ -143,7 +143,7 @@ router.beforeEach(async (to, _from, next) => { // Verify if user is logged in before accessing certain routes if (to.meta.requiresAuth) { if (!authService.isLoggedIn.value && !(await authService.loadUser())) { - const path = to.fullPath + const path = to.fullPath; if (path !== "/") { localStorage.setItem("redirectAfterLogin", path); } diff --git a/frontend/src/views/classes/StudentClasses.vue b/frontend/src/views/classes/StudentClasses.vue index d943b57a..590b29e5 100644 --- a/frontend/src/views/classes/StudentClasses.vue +++ b/frontend/src/views/classes/StudentClasses.vue @@ -82,7 +82,7 @@ // The code a student sends in to join a class needs to be formatted as v4 to be valid // These rules are used to display a message to the user if they use a code that has an invalid format function codeRegex(value: string): boolean { - return /^[a-zA-Z0-9]{6}$/.test(value) + return /^[a-zA-Z0-9]{6}$/.test(value); } const codeRules = [ diff --git a/frontend/src/views/classes/TeacherClasses.vue b/frontend/src/views/classes/TeacherClasses.vue index ea3a2441..f2d3cf41 100644 --- a/frontend/src/views/classes/TeacherClasses.vue +++ b/frontend/src/views/classes/TeacherClasses.vue @@ -137,8 +137,7 @@ await navigator.clipboard.writeText(content); copied.value = isDialog; - if (!isDialog) - showSnackbar(t("copied"), "white"); + if (!isDialog) showSnackbar(t("copied"), "white"); } // Custom breakpoints @@ -231,7 +230,12 @@ - + mdi-link-variant - + From 699b8304639cebfdae82f4df2bd2824102bd99ac Mon Sep 17 00:00:00 2001 From: Gabriellvl Date: Wed, 14 May 2025 12:41:02 +0200 Subject: [PATCH 07/12] feat: add username menu + zelfde avatar navbar --- frontend/src/components/MenuBar.vue | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/frontend/src/components/MenuBar.vue b/frontend/src/components/MenuBar.vue index a58be2f8..f95441d6 100644 --- a/frontend/src/components/MenuBar.vue +++ b/frontend/src/components/MenuBar.vue @@ -14,6 +14,7 @@ const _router = useRouter(); // Zonder '_' gaf dit een linter error voor unused variable const name: string = auth.authState.user!.profile.name!; + const username = auth.authState.user!.profile.preferred_username!; const email = auth.authState.user!.profile.email; const initials: string = name .split(" ") @@ -180,10 +181,15 @@
- - {{ initials }} + + {{ initials }}

{{ name }}

+

{{ username }}

{{ email }}

Date: Wed, 14 May 2025 12:56:53 +0200 Subject: [PATCH 08/12] fix: extra margin --- backend/src/app.ts | 2 +- frontend/src/components/MenuBar.vue | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/src/app.ts b/backend/src/app.ts index cf10a6df..ee773474 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -25,7 +25,7 @@ app.use(responseTime(responseTimeLogger)); app.use('/api', apiRouter); // Swagger -app.use('/api-docs', swaggerUi.serve, swaggerMiddleware); +// App.use('/api-docs', swaggerUi.serve, swaggerMiddleware); app.use(errorHandler); diff --git a/frontend/src/components/MenuBar.vue b/frontend/src/components/MenuBar.vue index f95441d6..a4652236 100644 --- a/frontend/src/components/MenuBar.vue +++ b/frontend/src/components/MenuBar.vue @@ -184,7 +184,7 @@ {{ initials }} From e6f05364f3d48e7b3e2d0916b8ef749f4159876c Mon Sep 17 00:00:00 2001 From: Gabriellvl Date: Wed, 14 May 2025 12:58:39 +0200 Subject: [PATCH 09/12] fix: uncomment swagger --- backend/src/app.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/backend/src/app.ts b/backend/src/app.ts index ee773474..cf10a6df 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -25,7 +25,7 @@ app.use(responseTime(responseTimeLogger)); app.use('/api', apiRouter); // Swagger -// App.use('/api-docs', swaggerUi.serve, swaggerMiddleware); +app.use('/api-docs', swaggerUi.serve, swaggerMiddleware); app.use(errorHandler); From 4600e5dd9efdf4fbce351ec2d67fd947c14ef3c6 Mon Sep 17 00:00:00 2001 From: Gabriellvl Date: Thu, 15 May 2025 19:31:38 +0200 Subject: [PATCH 10/12] fix: stijl consistent leerpaden --- .../components/LearningPathSearchField.vue | 7 ++- frontend/src/components/LearningPathsGrid.vue | 4 +- frontend/src/views/SingleTheme.vue | 15 +++-- .../learning-paths/LearningPathSearchPage.vue | 61 ++++++++----------- 4 files changed, 41 insertions(+), 46 deletions(-) diff --git a/frontend/src/components/LearningPathSearchField.vue b/frontend/src/components/LearningPathSearchField.vue index b8b71960..9afd62f6 100644 --- a/frontend/src/components/LearningPathSearchField.vue +++ b/frontend/src/components/LearningPathSearchField.vue @@ -31,4 +31,9 @@ > - + diff --git a/frontend/src/components/LearningPathsGrid.vue b/frontend/src/components/LearningPathsGrid.vue index 865c7166..8df08a00 100644 --- a/frontend/src/components/LearningPathsGrid.vue +++ b/frontend/src/components/LearningPathsGrid.vue @@ -53,9 +53,9 @@ white-space: normal; } .results-grid { - margin: 20px; + margin: 20px auto; display: flex; - align-items: stretch; + justify-content: center; gap: 20px; flex-wrap: wrap; } diff --git a/frontend/src/views/SingleTheme.vue b/frontend/src/views/SingleTheme.vue index 6924cc1c..4b14d606 100644 --- a/frontend/src/views/SingleTheme.vue +++ b/frontend/src/views/SingleTheme.vue @@ -31,13 +31,14 @@