127 lines
4.2 KiB
Vue
127 lines
4.2 KiB
Vue
<script setup lang="ts">
|
|
import DueDatesShortList from "@/components/dueDates/DueDatesShortList.vue";
|
|
import LearningPathListView from "@/pages/learningPath/learningPathPage/LearningPathListView.vue";
|
|
import LearningPathPathView from "@/pages/learningPath/learningPathPage/LearningPathPathView.vue";
|
|
import CircleProgress from "@/pages/learningPath/learningPathPage/LearningPathProgress.vue";
|
|
import LearningPathTopics from "@/pages/learningPath/learningPathPage/LearningPathTopics.vue";
|
|
import type { ViewType } from "@/pages/learningPath/learningPathPage/LearningPathViewSwitch.vue";
|
|
import LearningPathViewSwitch from "@/pages/learningPath/learningPathPage/LearningPathViewSwitch.vue";
|
|
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core";
|
|
import { computed, ref } from "vue";
|
|
import { useLearningPathWithCompletion } from "@/composables";
|
|
import { someFinishedInLearningSequence } from "@/services/circle";
|
|
|
|
const props = defineProps<{
|
|
courseSlug: string;
|
|
}>();
|
|
|
|
const breakpoints = useBreakpoints(breakpointsTailwind);
|
|
|
|
// Layout state
|
|
const useMobileLayout = breakpoints.smaller("sm");
|
|
const selectedView = ref<ViewType>(
|
|
(window.localStorage.getItem("learningPathView") as ViewType) || "path"
|
|
);
|
|
|
|
const lpQueryResult = useLearningPathWithCompletion(props.courseSlug);
|
|
|
|
const learningPath = computed(() => lpQueryResult.learningPath.value);
|
|
|
|
const circlesCount = computed(() => {
|
|
return lpQueryResult.circles.value?.length ?? 0;
|
|
});
|
|
|
|
const inProgressCirclesCount = computed(() => {
|
|
if (lpQueryResult.circles.value?.length) {
|
|
return lpQueryResult.circles.value.filter(
|
|
(circle) =>
|
|
circle.learning_sequences.filter((ls) => someFinishedInLearningSequence(ls))
|
|
.length
|
|
).length;
|
|
}
|
|
return 0;
|
|
});
|
|
|
|
const changeViewType = (viewType: ViewType) => {
|
|
selectedView.value = viewType;
|
|
window.localStorage.setItem("learningPathView", viewType);
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<div class="flex flex-col">
|
|
<!-- Top -->
|
|
<div class="flex flex-row justify-between space-x-8 bg-gray-200 p-6 sm:p-12">
|
|
<!-- Left -->
|
|
<div class="flex flex-col justify-between lg:w-1/2">
|
|
<div>
|
|
<p class="font-bold">
|
|
{{ $t("learningPathPage.welcomeBack") }}
|
|
</p>
|
|
<h2 data-cy="learning-path-title">
|
|
{{ learningPath?.title }}
|
|
</h2>
|
|
</div>
|
|
|
|
<CircleProgress
|
|
:all-count="circlesCount"
|
|
:in-progress-count="inProgressCirclesCount"
|
|
></CircleProgress>
|
|
</div>
|
|
|
|
<!-- Right -->
|
|
<div v-if="!useMobileLayout" class="flex-grow">
|
|
<div class="text-bold pb-3">
|
|
{{ $t("learningPathPage.nextDueDates") }}
|
|
</div>
|
|
<DueDatesShortList :max-count="2" :show-top-border="true"></DueDatesShortList>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Bottom -->
|
|
<div class="bg-white">
|
|
<div class="flex flex-col justify-between px-6 sm:flex-row sm:px-12">
|
|
<!-- Topics -->
|
|
<div
|
|
v-if="selectedView == 'path'"
|
|
class="order-2 pb-8 sm:order-1 sm:pb-0 sm:pt-4"
|
|
>
|
|
<LearningPathTopics :topics="learningPath?.topics ?? []"></LearningPathTopics>
|
|
</div>
|
|
<div v-else class="flex-grow"></div>
|
|
|
|
<!-- View switch -->
|
|
<LearningPathViewSwitch
|
|
class="order-1 py-8 sm:order-2 sm:py-0 sm:pt-4"
|
|
:initial-view="selectedView"
|
|
@select-view="changeViewType($event)"
|
|
></LearningPathViewSwitch>
|
|
</div>
|
|
|
|
<!-- Path view -->
|
|
<div v-if="selectedView == 'path'" class="flex flex-col" data-cy="lp-path-view">
|
|
<LearningPathPathView
|
|
:learning-path="learningPath"
|
|
:use-mobile-layout="useMobileLayout"
|
|
></LearningPathPathView>
|
|
</div>
|
|
|
|
<!-- List view -->
|
|
<div
|
|
v-if="selectedView == 'list'"
|
|
class="flex flex-col pl-6 sm:pl-24"
|
|
data-cy="lp-list-view"
|
|
>
|
|
<LearningPathListView :learning-path="learningPath"></LearningPathListView>
|
|
</div>
|
|
<div
|
|
v-if="useMobileLayout"
|
|
class="p-6"
|
|
:class="useMobileLayout ? 'bg-gray-200' : ''"
|
|
>
|
|
<!--<LearningPathAppointmentsMock></LearningPathAppointmentsMock>-->
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|