wip: summary boxes
This commit is contained in:
parent
ed4f9714d4
commit
63bcb44fa2
|
|
@ -0,0 +1,43 @@
|
|||
<script setup lang="ts">
|
||||
import ItProgress from "@/components/ui/ItProgress.vue";
|
||||
import { computed } from "vue";
|
||||
import BaseBox from "@/components/dashboard/BaseBox.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
assignmentsCompleted: number;
|
||||
avgPassed: number;
|
||||
}>();
|
||||
|
||||
const progress = computed(() => {
|
||||
return {
|
||||
SUCCESS: props.avgPassed,
|
||||
FAIL: 100 - props.avgPassed,
|
||||
UNKNOWN: 0,
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseBox :details-link="'/statistic/assignment'">
|
||||
<template #title>{{ $t("a.Kompetenznachweis-Elemente") }}</template>
|
||||
<template #content>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.NUMBER Elemente abgeschlossen')">
|
||||
<template #NUMBER>
|
||||
<span class="mr-3 text-4xl font-bold">{{ assignmentsCompleted }}</span>
|
||||
</template>
|
||||
</i18next>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.{NUMBER} Bestanden')">
|
||||
<template #NUMBER>
|
||||
<span class="mr-3 text-4xl font-bold">
|
||||
{{ Math.round(props.avgPassed) }}%
|
||||
</span>
|
||||
</template>
|
||||
</i18next>
|
||||
</div>
|
||||
<ItProgress :status-count="progress"></ItProgress>
|
||||
</template>
|
||||
</BaseBox>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
<script setup lang="ts">
|
||||
import ItProgress from "@/components/ui/ItProgress.vue";
|
||||
import { computed } from "vue";
|
||||
import BaseBox from "@/components/dashboard/BaseBox.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
daysCompleted: number;
|
||||
avgParticipantsPresent: number;
|
||||
}>();
|
||||
|
||||
const progressRecord = computed(() => {
|
||||
return {
|
||||
SUCCESS: props.avgParticipantsPresent,
|
||||
FAIL: 100 - props.avgParticipantsPresent,
|
||||
UNKNOWN: 0,
|
||||
};
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseBox :details-link="'/statistic/attendance'">
|
||||
<template #title>{{ $t("a.Anwesenheit") }}</template>
|
||||
<template #content>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.NUMBER Präsenztage abgeschlossen')">
|
||||
<template #NUMBER>
|
||||
<span class="mr-3 text-4xl font-bold">{{ daysCompleted }}</span>
|
||||
</template>
|
||||
</i18next>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.NUMBER Teilnehmer anwesend')">
|
||||
<template #NUMBER>
|
||||
<span class="mr-3 text-4xl font-bold">{{ avgParticipantsPresent }}%</span>
|
||||
</template>
|
||||
</i18next>
|
||||
</div>
|
||||
<ItProgress :status-count="progressRecord"></ItProgress>
|
||||
</template>
|
||||
</BaseBox>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
detailsLink: string;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex flex-col space-y-4 bg-white p-6">
|
||||
<h4 class="mb-1 font-bold">
|
||||
<slot name="title"></slot>
|
||||
</h4>
|
||||
<slot name="content"></slot>
|
||||
<router-link class="pt-8 underline" :to="detailsLink">
|
||||
{{ $t("a.Details anschauen") }}
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<script setup lang="ts">
|
||||
import BaseBox from "@/components/dashboard/BaseBox.vue";
|
||||
|
||||
defineProps<{
|
||||
failCount: number;
|
||||
successCount: number;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseBox :details-link="'/statistic/competence'">
|
||||
<template #title>{{ $t("a.Selbsteinschätzungen") }}</template>
|
||||
<template #content>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.{NUMBER} Das kann ich')">
|
||||
<template #NUMBER>
|
||||
<span class="mr-3 text-4xl font-bold">{{ successCount }}</span>
|
||||
</template>
|
||||
</i18next>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.{NUMBER} Das will ich nochmals anschauen')">
|
||||
<template #NUMBER>
|
||||
<span class="mr-3 text-4xl font-bold">{{ failCount }}%</span>
|
||||
</template>
|
||||
</i18next>
|
||||
</div>
|
||||
</template>
|
||||
</BaseBox>
|
||||
</template>
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
<script setup lang="ts">
|
||||
defineProps<{
|
||||
participantCount: number;
|
||||
expertCount: number;
|
||||
sessionCount: number;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="flex items-center justify-between bg-white p-6">
|
||||
<div class="flex space-x-6">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-4xl font-bold">
|
||||
{{ participantCount }}
|
||||
</span>
|
||||
<span>{{ $t("a.Teilnehmer") }}</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-4xl font-bold">
|
||||
{{ expertCount }}
|
||||
</span>
|
||||
<span>{{ $t("a.Trainer") }}</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-4xl font-bold">
|
||||
{{ sessionCount }}
|
||||
</span>
|
||||
<span>{{ $t("a.Durchführungen") }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<!-- TODO Figure out where this link should go -->
|
||||
<router-link class="btn-secondary" to="#">
|
||||
{{ $t("a.Liste anzeigen") }}
|
||||
</router-link>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped></style>
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
<script setup lang="ts">
|
||||
import BaseBox from "@/components/dashboard/BaseBox.vue";
|
||||
|
||||
defineProps<{
|
||||
feedbackCount: number;
|
||||
statisfactionMax: number;
|
||||
statisfactionAvg: number;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<BaseBox :details-link="'/statistic/feedback'">
|
||||
<template #title>{{ $t("a.Feedback Teilnehmer") }}</template>
|
||||
<template #content>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.{AVG} von {MAX}')">
|
||||
<template #AVG>
|
||||
<span class="mr-3 text-4xl font-bold">{{ statisfactionAvg }}</span>
|
||||
</template>
|
||||
<template #MAX>{{ statisfactionMax }}</template>
|
||||
</i18next>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.Total {NUMBER} Antworten')">
|
||||
<template #NUMBER>{{ feedbackCount }}</template>
|
||||
</i18next>
|
||||
</div>
|
||||
</template>
|
||||
</BaseBox>
|
||||
</template>
|
||||
|
|
@ -1,63 +1,65 @@
|
|||
<script setup lang="ts">
|
||||
import { useDashboardStore } from "@/stores/dashboard";
|
||||
import { computed } from "vue";
|
||||
import ItProgress from "@/components/ui/ItProgress.vue";
|
||||
import CourseStatistics from "@/components/dashboard/CourseStatistics.vue";
|
||||
import AttendanceSummaryBox from "@/components/dashboard/AttendanceSummaryBox.vue";
|
||||
import type { CourseStatisticsType } from "@/gql/graphql";
|
||||
import AssignmentSummaryBox from "@/components/dashboard/AssignmentSummaryBox.vue";
|
||||
import FeedbackSummaryBox from "@/components/dashboard/FeedbackSummaryBox.vue";
|
||||
import CompetenceSummaryBox from "@/components/dashboard/CompetenceSummaryBox.vue";
|
||||
|
||||
const dashboardStore = useDashboardStore();
|
||||
|
||||
const statistics = computed(() => {
|
||||
return dashboardStore.currentDashBoardData as CourseStatisticsType;
|
||||
});
|
||||
|
||||
const courseSessionSelectionMetrics = computed(() => {
|
||||
return statistics.value.course_session_selection_metrics;
|
||||
});
|
||||
|
||||
const attendanceDayPresences = computed(() => {
|
||||
return statistics.value.attendance_day_presences.summary;
|
||||
});
|
||||
|
||||
const assigmentSummary = computed(() => {
|
||||
return statistics.value.assignments.summary;
|
||||
});
|
||||
|
||||
const competenceSummary = computed(() => {
|
||||
return statistics.value.competences.summary;
|
||||
});
|
||||
|
||||
const feebackSummary = computed(() => {
|
||||
return statistics.value.feedback_responses.summary;
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div v-if="statistics" class="mb-14 space-y-8">
|
||||
<div class="flex items-center justify-between bg-white p-6">
|
||||
<div class="flex space-x-6">
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-4xl font-bold">352</span>
|
||||
<span>Teilnehmer</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-4xl font-bold">25</span>
|
||||
<span>Trainer</span>
|
||||
</div>
|
||||
<div class="flex items-center space-x-2">
|
||||
<span class="text-4xl font-bold">18</span>
|
||||
<span>Durchführungen</span>
|
||||
</div>
|
||||
</div>
|
||||
<router-link class="btn-secondary" to="#">
|
||||
{{ $t("a.Liste anzeigen") }}
|
||||
</router-link>
|
||||
</div>
|
||||
<CourseStatistics
|
||||
:session-count="courseSessionSelectionMetrics.session_count"
|
||||
:participant-count="courseSessionSelectionMetrics.participant_count"
|
||||
:expert-count="courseSessionSelectionMetrics.expert_count"
|
||||
/>
|
||||
<div class="grid auto-rows-fr grid-cols-1 gap-8 xl:grid-cols-2">
|
||||
<div class="flex flex-col space-y-4 bg-white p-6">
|
||||
<h4 class="mb-1 font-bold">{{ $t("a.Anwesenheit") }}</h4>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.NUMBER Präsenztage abgeschlossen')">
|
||||
<template #NUMBER>
|
||||
<span class="mr-3 text-4xl font-bold">
|
||||
{{ statistics.attendance_day_presences.summary.days_completed }}
|
||||
</span>
|
||||
</template>
|
||||
</i18next>
|
||||
</div>
|
||||
<div class="flex items-center">
|
||||
<i18next :translation="$t('a.NUMBER Präsenztage abgeschlossen')">
|
||||
<template #NUMBER>
|
||||
<span class="mr-3 text-4xl font-bold">
|
||||
{{ statistics.attendance_day_presences.summary.days_completed }}
|
||||
</span>
|
||||
</template>
|
||||
</i18next>
|
||||
</div>
|
||||
<ItProgress></ItProgress>
|
||||
<router-link class="pt-8 underline" to="/statistic/attendance">
|
||||
{{ $t("a.Details anschauen") }}
|
||||
</router-link>
|
||||
</div>
|
||||
<AttendanceSummaryBox
|
||||
:days-completed="attendanceDayPresences.days_completed"
|
||||
:avg-participants-present="attendanceDayPresences.participants_present"
|
||||
/>
|
||||
<AssignmentSummaryBox
|
||||
:assignments-completed="assigmentSummary.completed_count"
|
||||
:avg-passed="assigmentSummary.average_passed"
|
||||
/>
|
||||
<FeedbackSummaryBox
|
||||
:feedback-count="feebackSummary.total_responses"
|
||||
:statisfaction-max="feebackSummary.satisfaction_max"
|
||||
:statisfaction-avg="feebackSummary.satisfaction_average"
|
||||
/>
|
||||
<CompetenceSummaryBox
|
||||
:fail-count="competenceSummary.fail_total"
|
||||
:success-count="competenceSummary.success_total"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -184,6 +184,24 @@ const router = createRouter({
|
|||
component: () =>
|
||||
import("@/pages/dashboard/statistic/AttendanceDayPresences.vue"),
|
||||
},
|
||||
{
|
||||
path: "assignment",
|
||||
props: true,
|
||||
component: () =>
|
||||
import("@/pages/dashboard/statistic/AttendanceDayPresences.vue"),
|
||||
},
|
||||
{
|
||||
path: "competence",
|
||||
props: true,
|
||||
component: () =>
|
||||
import("@/pages/dashboard/statistic/AttendanceDayPresences.vue"),
|
||||
},
|
||||
{
|
||||
path: "feedback",
|
||||
props: true,
|
||||
component: () =>
|
||||
import("@/pages/dashboard/statistic/AttendanceDayPresences.vue"),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
|
|
|||
Loading…
Reference in New Issue