178 lines
6.0 KiB
Vue
178 lines
6.0 KiB
Vue
<script setup lang="ts">
|
|
import PerformanceCriteriaRow from "@/components/competences/PerformanceCriteriaRow.vue";
|
|
import ItDropdownSelect from "@/components/ui/ItDropdownSelect.vue";
|
|
import ItProgress from "@/components/ui/ItProgress.vue";
|
|
import { useCompetenceStore } from "@/stores/competence";
|
|
import maxBy from "lodash/maxBy";
|
|
import orderBy from "lodash/orderBy";
|
|
import * as log from "loglevel";
|
|
import { computed } from "vue";
|
|
|
|
log.debug("CompetenceIndexPage created");
|
|
|
|
const props = defineProps<{
|
|
courseSlug: string;
|
|
}>();
|
|
|
|
log.debug("CompetenceIndexPage created", props);
|
|
|
|
const competenceStore = useCompetenceStore();
|
|
|
|
const failedCriteria = computed(() => {
|
|
return competenceStore
|
|
.flatPerformanceCriteria()
|
|
.filter((criteria) => {
|
|
return criteria.completion_status === "fail";
|
|
})
|
|
.slice(0, 3);
|
|
});
|
|
|
|
const lastUpdatedCompetences = computed(() => {
|
|
return orderBy(
|
|
competenceStore.competences(),
|
|
[
|
|
(competence) => {
|
|
let criteria = competence.children;
|
|
if (competenceStore.selectedCircle.id != "all") {
|
|
criteria = criteria.filter((criteria) => {
|
|
return (
|
|
criteria.circle.translation_key === competenceStore.selectedCircle.id
|
|
);
|
|
});
|
|
}
|
|
return (
|
|
maxBy(criteria, "completion_status_updated_at")
|
|
?.completion_status_updated_at || ""
|
|
);
|
|
},
|
|
],
|
|
["desc"]
|
|
).slice(0, 3);
|
|
});
|
|
|
|
const countStatus = computed(() => {
|
|
return competenceStore.calcStatusCount(competenceStore.flatPerformanceCriteria());
|
|
});
|
|
</script>
|
|
|
|
<template>
|
|
<div class="container-large lg:mt-4">
|
|
<div
|
|
v-if="competenceStore.competenceProfilePage()"
|
|
class="mb-10 flex flex-col justify-between lg:flex-row lg:items-center"
|
|
>
|
|
<h1>{{ $t("competences.title") }}</h1>
|
|
<ItDropdownSelect
|
|
v-model="competenceStore.selectedCircle"
|
|
class="mt-4 w-full lg:mt-0 lg:w-96"
|
|
:items="competenceStore.availableCircles"
|
|
></ItDropdownSelect>
|
|
</div>
|
|
<div class="l mb-4 bg-white px-8 py-4 lg:mb-8 lg:py-8">
|
|
<div>
|
|
<h3 class="border-b pb-4">{{ $t("competences.lastImprovements") }}</h3>
|
|
<ul>
|
|
<li
|
|
v-for="competence in lastUpdatedCompetences"
|
|
:key="competence.id"
|
|
class="flex flex-col border-b py-4 last:mb-8 lg:flex-row lg:items-center"
|
|
>
|
|
<p class="mb-4 inline-block lg:mb-0 lg:mr-5 lg:w-1/4">
|
|
{{ competence.competence_id }} {{ competence.title }}
|
|
</p>
|
|
<ItProgress
|
|
:status-count="
|
|
competenceStore.calcStatusCount(
|
|
competenceStore.criteriaByCompetence(competence)
|
|
)
|
|
"
|
|
></ItProgress>
|
|
</li>
|
|
</ul>
|
|
<router-link
|
|
:to="`${competenceStore.competenceProfilePage()?.frontend_url}/competences`"
|
|
class="btn-text inline-flex items-center py-2 pl-0"
|
|
>
|
|
<span>{{ $t("general.showAll") }}</span>
|
|
<it-icon-arrow-right></it-icon-arrow-right>
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
<div class="l mb-4 bg-white px-8 py-4 lg:mb-8 lg:py-8">
|
|
<h3 class="mb-4 border-b pb-4 lg:border-0 lg:pb-0">
|
|
{{ $t("competences.assessment") }}
|
|
</h3>
|
|
<ul
|
|
class="mb-6 flex flex-col lg:flex-row lg:items-center lg:justify-between lg:gap-8"
|
|
>
|
|
<li
|
|
class="mb-4 inline-block flex-1 border-b pb-4 lg:mb-0 lg:border-b-0 lg:border-r lg:pb-0"
|
|
>
|
|
<h5 class="mb-4 text-gray-700">«{{ $t("selfEvaluation.no") }}»</h5>
|
|
<div class="flex flex-row items-center">
|
|
<it-icon-smiley-thinking class="h-16 w-16"></it-icon-smiley-thinking>
|
|
<p class="ml-4 inline-block text-7xl font-bold">{{ countStatus.fail }}</p>
|
|
</div>
|
|
</li>
|
|
<li
|
|
class="mb-4 inline-block flex-1 border-b pb-4 lg:mb-0 lg:border-b-0 lg:border-r lg:pb-0"
|
|
>
|
|
<h5 class="mb-4 text-gray-700">«{{ $t("selfEvaluation.yes") }}»</h5>
|
|
<div class="flex flex-row items-center">
|
|
<it-icon-smiley-happy class="h-16 w-16"></it-icon-smiley-happy>
|
|
<p class="ml-4 inline-block text-7xl font-bold">
|
|
{{ countStatus.success }}
|
|
</p>
|
|
</div>
|
|
</li>
|
|
<li class="lg:mb-0flex-1 border-b pb-4 lg:border-b-0 lg:pb-0">
|
|
<h5 class="mb-4 text-gray-700">{{ $t("competences.notAssessed") }}</h5>
|
|
<div class="flex flex-row items-center">
|
|
<it-icon-smiley-neutral class="h-16 w-16"></it-icon-smiley-neutral>
|
|
<p class="ml-4 inline-block text-7xl font-bold">
|
|
{{ countStatus.unknown }}
|
|
</p>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
<router-link
|
|
:to="`${competenceStore.competenceProfilePage()?.frontend_url}/criteria`"
|
|
class="btn-text inline-flex items-center py-2 pl-0"
|
|
>
|
|
<span>{{ $t("general.showAll") }}</span>
|
|
<it-icon-arrow-right></it-icon-arrow-right>
|
|
</router-link>
|
|
</div>
|
|
<div
|
|
v-if="failedCriteria.length > 0"
|
|
class="l mb-4 bg-white px-8 py-4 lg:mb-8 lg:py-8"
|
|
>
|
|
<div class="mb-4 flex flex-row items-center border-b pb-4">
|
|
<it-icon-smiley-thinking class="mr-5 h-11 w-11"></it-icon-smiley-thinking>
|
|
<h3>«{{ $t("selfEvaluation.no") }}»</h3>
|
|
</div>
|
|
<ul class="mb-6">
|
|
<li
|
|
v-for="criteria in failedCriteria"
|
|
:key="criteria.id"
|
|
class="mb-4 border-b pb-4"
|
|
>
|
|
<PerformanceCriteriaRow
|
|
:criteria="criteria"
|
|
:course-slug="props.courseSlug"
|
|
></PerformanceCriteriaRow>
|
|
</li>
|
|
</ul>
|
|
<router-link
|
|
:to="`${competenceStore.competenceProfilePage()?.frontend_url}/criteria`"
|
|
class="btn-text inline-flex items-center py-2 pl-0"
|
|
>
|
|
<span>{{ $t("general.showAll") }}</span>
|
|
<it-icon-arrow-right></it-icon-arrow-right>
|
|
</router-link>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped></style>
|