154 lines
4.4 KiB
Vue
154 lines
4.4 KiB
Vue
<template>
|
|
<div class="bg-gray-200">
|
|
<div class="container-large">
|
|
<nav class="py-4 pb-4">
|
|
<router-link
|
|
class="btn-text inline-flex items-center pl-0"
|
|
:to="`/course/${props.courseSlug}/cockpit`"
|
|
>
|
|
<it-icon-arrow-left />
|
|
<span>{{ $t("general.back") }}</span>
|
|
</router-link>
|
|
</nav>
|
|
<main>
|
|
<h1 class="mb-2">{{ $t("feedback.feedbackPageTitle") }}</h1>
|
|
<p class="mb-10">
|
|
<span class="font-bold">{{ feedbackData.amount }}</span>
|
|
{{ $t("feedback.feedbackPageInfo") }}
|
|
</p>
|
|
<ol v-if="Object.keys(feedbackData).length > 0">
|
|
<li v-for="(question, i) in orderedQuestions" :key="i">
|
|
<RatingScale
|
|
v-if="ratingKeys.includes(question.key)"
|
|
class="mb-8 bg-white"
|
|
:ratings="feedbackData.questions[question.key]"
|
|
:title="`${$t('feedback.questionTitle')} ${i + 1}`"
|
|
:text="question.question"
|
|
/>
|
|
<VerticalBarChart
|
|
v-else-if="verticalChartKyes.includes(question.key)"
|
|
class="mb-8 bg-white"
|
|
:title="`${$t('feedback.questionTitle')} ${i + 1}`"
|
|
:ratings="feedbackData.questions[question.key]"
|
|
:text="question.question"
|
|
:ratio="0.2"
|
|
/>
|
|
<OpenFeedback
|
|
v-else-if="openKeys.includes(question.key)"
|
|
class="mb-8 bg-white"
|
|
:title="`${$t('feedback.questionTitle')} ${i + 1}`"
|
|
:text="question.question"
|
|
:answers="feedbackData.questions[question.key].filter((a: string) => a !== '')"
|
|
></OpenFeedback>
|
|
<HorizontalBarChart
|
|
v-else-if="horizontalChartKeys.includes(question.key)"
|
|
class="mb-8 bg-white"
|
|
:title="`${$t('feedback.questionTitle')} ${i}`"
|
|
:text="question.question"
|
|
:items="feedbackData.questions[question.key].map((a: string) => `${a}%`)"
|
|
/>
|
|
</li>
|
|
</ol>
|
|
</main>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import HorizontalBarChart from "@/components/ui/HorizontalBarChart.vue";
|
|
import OpenFeedback from "@/components/ui/OpenFeedback.vue";
|
|
import RatingScale from "@/components/ui/RatingScale.vue";
|
|
import VerticalBarChart from "@/components/ui/VerticalBarChart.vue";
|
|
import { useCurrentCourseSession } from "@/composables";
|
|
import { itGet } from "@/fetchHelpers";
|
|
import * as log from "loglevel";
|
|
import { onMounted, reactive } from "vue";
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
interface FeedbackData {
|
|
amount: number;
|
|
questions: {
|
|
[key: string]: any;
|
|
};
|
|
}
|
|
|
|
const props = defineProps<{
|
|
courseSlug: string;
|
|
circleId: string;
|
|
}>();
|
|
|
|
log.debug("FeedbackPage created", props.circleId);
|
|
|
|
const courseSession = useCurrentCourseSession();
|
|
const { t } = useI18n();
|
|
|
|
const orderedQuestions = [
|
|
{
|
|
key: "satisfaction",
|
|
question: t("feedback.satisfactionLabel"),
|
|
},
|
|
{
|
|
key: "goal_attainment",
|
|
question: t("feedback.goalAttainmentLabel"),
|
|
},
|
|
{
|
|
key: "proficiency",
|
|
question: t("feedback.proficiencyLabel"),
|
|
},
|
|
{
|
|
key: "preparation_task_clarity",
|
|
question: t("feedback.preparationTaskClarityLabel"),
|
|
},
|
|
{
|
|
key: "instructor_competence",
|
|
question: t("feedback.instructorCompetenceLabel"),
|
|
},
|
|
{
|
|
key: "instructor_respect",
|
|
question: t("feedback.instructorRespectLabel"),
|
|
},
|
|
{
|
|
key: "instructor_open_feedback",
|
|
question: t("feedback.instructorOpenFeedbackLabel"),
|
|
},
|
|
{
|
|
key: "would_recommend",
|
|
question: t("feedback.recommendLabel"),
|
|
},
|
|
{
|
|
key: "course_negative_feedback",
|
|
question: t("feedback.courseNegativeFeedbackLabel"),
|
|
},
|
|
{
|
|
key: "course_positive_feedback",
|
|
question: t("feedback.coursePositiveFeedbackLabel"),
|
|
},
|
|
];
|
|
|
|
const ratingKeys = [
|
|
"satisfaction",
|
|
"goal_attainment",
|
|
"instructor_competence",
|
|
"instructor_respect",
|
|
];
|
|
const verticalChartKyes = ["preparation_task_clarity", "would_recommend"];
|
|
const horizontalChartKeys = ["proficiency"];
|
|
const openKeys = [
|
|
"course_negative_feedback",
|
|
"course_positive_feedback",
|
|
"instructor_open_feedback",
|
|
];
|
|
|
|
const feedbackData = reactive<FeedbackData>({ amount: 0, questions: {} });
|
|
|
|
onMounted(async () => {
|
|
log.debug("FeedbackPage mounted");
|
|
const data = await itGet(
|
|
`/api/core/feedback/${courseSession.course.id}/${props.circleId}`
|
|
);
|
|
Object.assign(feedbackData, data);
|
|
});
|
|
</script>
|
|
|
|
<style scoped></style>
|