187 lines
7.1 KiB
Vue
187 lines
7.1 KiB
Vue
<script setup lang="ts">
|
|
import LearningPathDiagram from "@/components/learningPath/LearningPathDiagram.vue";
|
|
import ItPersonRow from "@/components/ui/ItPersonRow.vue";
|
|
import type { LearningPath } from "@/services/learningPath";
|
|
|
|
import { useCurrentCourseSession } from "@/composables";
|
|
import SubmissionsOverview from "@/pages/cockpit/cockpitPage/SubmissionsOverview.vue";
|
|
import { useCockpitStore } from "@/stores/cockpit";
|
|
import { useCompetenceStore } from "@/stores/competence";
|
|
import { useLearningPathStore } from "@/stores/learningPath";
|
|
import log from "loglevel";
|
|
import CockpitDates from "@/pages/cockpit/cockpitPage/CockpitDates.vue";
|
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
|
|
|
const props = defineProps<{
|
|
courseSlug: string;
|
|
}>();
|
|
|
|
log.debug("CockpitIndexPage created", props.courseSlug);
|
|
|
|
const cockpitStore = useCockpitStore();
|
|
const competenceStore = useCompetenceStore();
|
|
const learningPathStore = useLearningPathStore();
|
|
const courseSession = useCurrentCourseSession();
|
|
|
|
function userCountStatusForCircle(userId: string) {
|
|
if (!cockpitStore.selectedCircle) return { FAIL: 0, SUCCESS: 0, UNKNOWN: 0 };
|
|
const criteria = competenceStore.flatPerformanceCriteria(
|
|
userId,
|
|
cockpitStore.selectedCircle.id
|
|
);
|
|
return competenceStore.calcStatusCount(criteria);
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<div class="bg-gray-200">
|
|
<div class="container-large">
|
|
<div class="mb-9 flex items-end justify-between">
|
|
<h1>Cockpit</h1>
|
|
<div class="flex flex-row">
|
|
<ItDropdownSelect
|
|
v-model="cockpitStore.selectedCircle"
|
|
class="mt-4 w-full lg:mt-0 lg:w-96"
|
|
:items="cockpitStore.circles"
|
|
></ItDropdownSelect>
|
|
</div>
|
|
</div>
|
|
<template v-if="cockpitStore.selectedCircle">
|
|
<!-- Status -->
|
|
<div class="mb-4 gap-4 lg:grid lg:grid-cols-3 lg:grid-rows-none">
|
|
<div class="my-4 flex flex-col justify-between bg-white p-6 lg:my-0">
|
|
<div>
|
|
<h3 class="heading-3 mb-4 flex items-center gap-2">
|
|
{{ $t("Trainerunterlagen") }}
|
|
</h3>
|
|
<div class="mb-4">
|
|
{{ $t("cockpit.trainerFilesText") }}
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<a
|
|
href="https://vbvbern.sharepoint.com/sites/myVBV-AFA_K-CI"
|
|
class="btn-secondary min-w-min"
|
|
target="_blank"
|
|
>
|
|
{{ $t("MS Teams öffnen") }}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
<div class="my-4 flex flex-col justify-between bg-white p-6 lg:my-0">
|
|
<div>
|
|
<h3 class="heading-3 mb-4 flex items-center gap-2">
|
|
{{ $t("Anwesenheitskontrolle Präsenzkurse") }}
|
|
</h3>
|
|
<div class="mb-4">
|
|
{{
|
|
$t(
|
|
"Hier überprüfst und bestätigst du die Anwesenheit deiner Teilnehmenden."
|
|
)
|
|
}}
|
|
</div>
|
|
</div>
|
|
<div>
|
|
<router-link
|
|
:to="`/course/${props.courseSlug}/cockpit/attendance`"
|
|
class="btn-secondary min-w-min"
|
|
>
|
|
{{ $t("Anwesenheit prüfen") }}
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
<div class="bg-white p-6">
|
|
<CockpitDates></CockpitDates>
|
|
</div>
|
|
</div>
|
|
<SubmissionsOverview
|
|
:course-session="courseSession"
|
|
:selected-circle="cockpitStore.selectedCircle.id"
|
|
></SubmissionsOverview>
|
|
<div class="pt-4">
|
|
<!-- progress -->
|
|
<div v-if="cockpitStore.courseSessionMembers" class="bg-white p-6">
|
|
<h1 class="heading-3 mb-5">{{ $t("cockpit.progress") }}</h1>
|
|
<ul>
|
|
<ItPersonRow
|
|
v-for="csu in cockpitStore.courseSessionMembers"
|
|
:key="csu.user_id + csu.session_title"
|
|
:name="`${csu.first_name} ${csu.last_name}`"
|
|
:avatar-url="csu.avatar_url"
|
|
>
|
|
<template #center>
|
|
<div
|
|
class="mt-2 flex w-full flex-col items-center justify-between lg:mt-0 lg:flex-row"
|
|
>
|
|
<LearningPathDiagram
|
|
v-if="
|
|
learningPathStore.learningPathForUser(
|
|
props.courseSlug,
|
|
csu.user_id
|
|
)
|
|
"
|
|
:learning-path="
|
|
learningPathStore.learningPathForUser(
|
|
props.courseSlug,
|
|
csu.user_id
|
|
) as LearningPath
|
|
"
|
|
:show-circle-translation-keys="[
|
|
cockpitStore.selectedCircle.translation_key,
|
|
]"
|
|
diagram-type="singleSmall"
|
|
class="mr-4"
|
|
></LearningPathDiagram>
|
|
<p class="lg:min-w-[150px]">
|
|
{{ cockpitStore.selectedCircle.name }}
|
|
</p>
|
|
<div class="ml-4 flex flex-row items-center">
|
|
<div class="mr-6 flex flex-row items-center">
|
|
<it-icon-smiley-thinking
|
|
class="mr-2 inline-block h-8 w-8"
|
|
></it-icon-smiley-thinking>
|
|
<p class="text-bold inline-block w-6">
|
|
{{ userCountStatusForCircle(csu.user_id).FAIL }}
|
|
</p>
|
|
</div>
|
|
<li class="mr-6 flex flex-row items-center">
|
|
<it-icon-smiley-happy
|
|
class="mr-2 inline-block h-8 w-8"
|
|
></it-icon-smiley-happy>
|
|
<p class="text-bold inline-block w-6">
|
|
{{ userCountStatusForCircle(csu.user_id).SUCCESS }}
|
|
</p>
|
|
</li>
|
|
<li class="flex flex-row items-center">
|
|
<it-icon-smiley-neutral
|
|
class="mr-2 inline-block h-8 w-8"
|
|
></it-icon-smiley-neutral>
|
|
<p class="text-bold inline-block w-6">
|
|
{{ userCountStatusForCircle(csu.user_id).UNKNOWN }}
|
|
</p>
|
|
</li>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<template #link>
|
|
<router-link
|
|
:to="`/course/${props.courseSlug}/cockpit/profile/${csu.user_id}`"
|
|
class="link w-full lg:text-right"
|
|
>
|
|
{{ $t("general.profileLink") }}
|
|
</router-link>
|
|
</template>
|
|
</ItPersonRow>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
<span v-else class="text-lg text-orange-600">
|
|
{{ $t("a.Kein Circle verfügbar oder ausgewählt.") }}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped></style>
|