diff --git a/assets/vue/components/Login.vue b/assets/vue/components/Login.vue index e027339d0da..db6e90d78ef 100644 --- a/assets/vue/components/Login.vue +++ b/assets/vue/components/Login.vue @@ -113,17 +113,26 @@ const requires2FA = ref(false) redirectNotAuthenticated() async function onSubmitLoginForm() { - const response = await performLogin({ - login: login.value, - password: password.value, - totp: requires2FA.value ? totp.value : null, - _remember_me: remember.value, - }) - - if (response.requires2FA) { - requires2FA.value = true - } else { - await router.replace({ name: "Home" }) + try { + const response = await performLogin({ + login: login.value, + password: password.value, + totp: requires2FA.value ? totp.value : null, + _remember_me: remember.value, + }) + + if (!response) { + console.warn("[Login] No response from performLogin.") + return + } + + if (response.requires2FA) { + requires2FA.value = true + } else { + await router.replace({ name: "Home" }) + } + } catch (error) { + console.error("[Login] performLogin failed:", error) } } diff --git a/assets/vue/components/course/CatalogueCourseCard.vue b/assets/vue/components/course/CatalogueCourseCard.vue index 6859758fd65..e6af0d7d39f 100644 --- a/assets/vue/components/course/CatalogueCourseCard.vue +++ b/assets/vue/components/course/CatalogueCourseCard.vue @@ -1,16 +1,65 @@ diff --git a/assets/vue/components/layout/TopbarNotLoggedIn.vue b/assets/vue/components/layout/TopbarNotLoggedIn.vue index e5f4ce60c95..e5bbc7d1980 100644 --- a/assets/vue/components/layout/TopbarNotLoggedIn.vue +++ b/assets/vue/components/layout/TopbarNotLoggedIn.vue @@ -63,6 +63,18 @@ const menuItems = computed(() => { }) } + const showCatalogueLink = + platformConfigStore.getSetting("course.course_catalog_published") !== "false" && + platformConfigStore.getSetting("course.catalog_hide_public_link") !== "true" && + platformConfigStore.getSetting("display.allow_students_to_browse_courses") !== "false" + + if (showCatalogueLink) { + items.splice(1, 0, { + label: t("Browse courses"), + url: router.resolve({ name: "CatalogueCourses" }).href, + }) + } + console.log("Menu Items:", items) return items }) diff --git a/assets/vue/components/session/CatalogueSessionCard.vue b/assets/vue/components/session/CatalogueSessionCard.vue index 5c74722c2a3..e819b5b62d2 100644 --- a/assets/vue/components/session/CatalogueSessionCard.vue +++ b/assets/vue/components/session/CatalogueSessionCard.vue @@ -1,6 +1,6 @@ diff --git a/assets/vue/services/courseRelUserService.js b/assets/vue/services/courseRelUserService.js index 841e52c0850..33dee1ba188 100644 --- a/assets/vue/services/courseRelUserService.js +++ b/assets/vue/services/courseRelUserService.js @@ -24,7 +24,12 @@ async function subscribe({ userId, courseId }) { }) } +async function autoSubscribeCourse(courseId) { + return await baseService.post(`/catalogue/auto-subscribe-course/${courseId}`) +} + export default { findAll, subscribe, + autoSubscribeCourse, } diff --git a/assets/vue/services/courseService.js b/assets/vue/services/courseService.js index 8c696d523f1..9e1bd779516 100644 --- a/assets/vue/services/courseService.js +++ b/assets/vue/services/courseService.js @@ -187,4 +187,21 @@ export default { const response = await api.get("/catalogue/courses-list") return response.data }, + loadCourseCatalogue: async () => { + try { + const response = await fetch("/api/public_courses") + if (!response.ok) throw new Error("Failed to load catalogue courses") + + const data = await response.json() + const items = Array.isArray(data) ? data : (data["hydra:member"] ?? data.items ?? []) + return items.map((course) => ({ + ...course, + userVote: null, + extra_fields: course.extra_fields || {}, + })) + } catch (e) { + console.error("loadCourseCatalogue error:", e) + return [] + } + }, } diff --git a/assets/vue/views/course/CatalogueCourses.vue b/assets/vue/views/course/CatalogueCourses.vue index ffd1773d50a..412787e8478 100644 --- a/assets/vue/views/course/CatalogueCourses.vue +++ b/assets/vue/views/course/CatalogueCourses.vue @@ -14,17 +14,80 @@ icon="pi pi-filter-slash" @click="clearFilter()" /> - - +