vbv/client/src/components/dashboard/UkStatistics.vue

103 lines
3.0 KiB
Vue

<script setup lang="ts">
import AssignmentSummaryBox from "@/components/dashboard/AssignmentSummaryBox.vue";
import AttendanceSummaryBox from "@/components/dashboard/AttendanceSummaryBox.vue";
import CompetenceSummaryBox from "@/components/dashboard/CompetenceSummaryBox.vue";
import FeedbackSummaryBox from "@/components/dashboard/FeedbackSummaryBox.vue";
import LoadingSpinner from "@/components/ui/LoadingSpinner.vue";
import type { CourseStatisticsType } from "@/gql/graphql";
import { useDashboardStore } from "@/stores/dashboard";
import { computed, onMounted, ref } from "vue";
const props = defineProps<{
courseId: string;
courseSlug: string;
}>();
const statistics = ref<CourseStatisticsType | null>(null);
const dashboardStore = useDashboardStore();
const attendanceDayPresences = computed(() => {
return (
statistics?.value?.attendance_day_presences?.summary ?? {
days_completed: 0,
participants_present: 0,
}
);
});
const assigmentSummary = computed(() => {
return (
statistics?.value?.assignments.summary ?? {
average_passed: 0,
completed_count: 0,
total_passed: 0,
total_failed: 0,
}
);
});
const competenceSummary = computed(() => {
return (
statistics?.value?.competences.summary ?? {
fail_total: 0,
success_total: 0,
}
);
});
const feebackSummary = computed(() => {
return (
statistics?.value?.feedback_responses.summary ?? {
satisfaction_average: 0,
satisfaction_max: 0,
total_responses: 0,
}
);
});
onMounted(async () => {
statistics.value = await dashboardStore.loadStatisticsData(props.courseId);
});
</script>
<template>
<div v-if="statistics" class="space-y-8">
<div
class="flex flex-col flex-wrap justify-between gap-x-5 border-b border-gray-300 pb-8 last:border-0 md:flex-row"
>
<AttendanceSummaryBox
class="flex-grow"
:days-completed="attendanceDayPresences.days_completed"
:avg-participants-present="attendanceDayPresences.participants_present"
:course-slug="props.courseSlug"
/>
<AssignmentSummaryBox
class="flex-grow"
:assignments-completed="assigmentSummary.completed_count"
:avg-passed="assigmentSummary.average_passed"
:course-slug="props.courseSlug"
/>
</div>
<div
class="flex flex-col flex-wrap gap-x-5 border-b border-gray-300 align-top last:border-0 md:flex-row"
>
<FeedbackSummaryBox
:feedback-count="feebackSummary.total_responses"
:statisfaction-max="feebackSummary.satisfaction_max"
:statisfaction-avg="feebackSummary.satisfaction_average"
:course-slug="props.courseSlug"
/>
<CompetenceSummaryBox
:fail-count="competenceSummary.fail_total"
:success-count="competenceSummary.success_total"
:details-link="`/statistic/${courseSlug}/competence`"
:course-slug="props.courseSlug"
/>
</div>
</div>
<div v-else class="flex w-full flex-row justify-center">
<LoadingSpinner />
</div>
</template>