vbv/client/src/pages/learningPath/learningPathPage/LearningPathPage.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>