234 lines
7.0 KiB
Vue
234 lines
7.0 KiB
Vue
<script setup lang="ts">
|
|
import ItRadioGroup from "@/components/ui/ItRadioGroup.vue";
|
|
import ItTextarea from "@/components/ui/ItTextarea.vue";
|
|
import { graphql } from "@/gql/";
|
|
import type { SendFeedbackInput } from "@/gql/graphql";
|
|
import FeedbackCompletition from "@/pages/learningPath/learningContentPage/feedback/FeedbackCompletition.vue";
|
|
import {
|
|
PERCENTAGES,
|
|
RATINGS,
|
|
YES_NO,
|
|
} from "@/pages/learningPath/learningContentPage/feedback/feedback.constants";
|
|
import LearningContentMultiLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentMultiLayout.vue";
|
|
import { useCircleStore } from "@/stores/circle";
|
|
import { useCourseSessionsStore } from "@/stores/courseSessions";
|
|
import type { LearningContent } from "@/types";
|
|
import { useMutation } from "@urql/vue";
|
|
import { useRouteQuery } from "@vueuse/router";
|
|
import log from "loglevel";
|
|
import { computed, onMounted, reactive, ref } from "vue";
|
|
import { useI18n } from "vue-i18n";
|
|
|
|
const props = defineProps<{ page: LearningContent }>();
|
|
const courseSessionsStore = useCourseSessionsStore();
|
|
const circleStore = useCircleStore();
|
|
const { t } = useI18n();
|
|
|
|
onMounted(async () => {
|
|
log.debug("Feedback mounted");
|
|
});
|
|
|
|
const stepNo = useRouteQuery("step", "0", { transform: Number, mode: "push" });
|
|
|
|
const title = computed(
|
|
() => `«${circleStore.circle?.title}»: ${t("feedback.areYouSatisfied")}`
|
|
);
|
|
|
|
const stepLabels = [
|
|
t("general.introduction"),
|
|
t("feedback.satisfactionLabel"),
|
|
t("feedback.goalAttainmentLabel"),
|
|
t("feedback.proficiencyLabel"),
|
|
t("feedback.preparationTaskClarityLabel"),
|
|
t("feedback.instructorCompetenceLabel"),
|
|
t("feedback.instructorRespectLabel"),
|
|
t("feedback.instructorOpenFeedbackLabel"),
|
|
t("feedback.recommendLabel"),
|
|
t("feedback.courseNegativeFeedbackLabel"),
|
|
t("feedback.coursePositiveFeedbackLabel"),
|
|
t("general.submission"),
|
|
];
|
|
|
|
const numSteps = stepLabels.length;
|
|
|
|
const sendFeedbackMutation = graphql(`
|
|
mutation SendFeedbackMutation($input: SendFeedbackInput!) {
|
|
sendFeedback(input: $input) {
|
|
feedbackResponse {
|
|
id
|
|
}
|
|
errors {
|
|
field
|
|
messages
|
|
}
|
|
}
|
|
}
|
|
`);
|
|
const { executeMutation } = useMutation(sendFeedbackMutation);
|
|
|
|
const satisfaction = ref(null);
|
|
const goalAttainment = ref(null);
|
|
const proficiency = ref(null);
|
|
const preparationTaskClarity = ref(null);
|
|
const instructorCompetence = ref(null);
|
|
const instructorRespect = ref(null);
|
|
const instructorOpenFeedback = ref("");
|
|
const wouldRecommend = ref(null);
|
|
const courseNegativeFeedback = ref("");
|
|
const coursePositiveFeedback = ref("");
|
|
|
|
const mutationResult = ref<any>(null);
|
|
|
|
const previousStep = () => {
|
|
if (stepNo.value > 0) {
|
|
stepNo.value -= 1;
|
|
}
|
|
};
|
|
const nextStep = () => {
|
|
if (stepNo.value < numSteps) {
|
|
stepNo.value += 1;
|
|
}
|
|
log.info(`next step ${stepNo.value} of ${numSteps}`);
|
|
};
|
|
|
|
const sendFeedback = () => {
|
|
log.info("sending feedback");
|
|
const courseSession = courseSessionsStore.currentCourseSession;
|
|
if (!courseSession || !courseSession.id) {
|
|
log.error("no course session set");
|
|
return;
|
|
}
|
|
const input: SendFeedbackInput = reactive({
|
|
data: {
|
|
preparation_task_clarity: preparationTaskClarity,
|
|
course_negative_feedback: courseNegativeFeedback,
|
|
course_positive_feedback: coursePositiveFeedback,
|
|
goald_attainment: goalAttainment,
|
|
instructor_competence: instructorCompetence,
|
|
instructor_respect: instructorRespect,
|
|
instructor_open_feedback: instructorOpenFeedback,
|
|
satisfaction,
|
|
proficiency,
|
|
would_recommend: wouldRecommend,
|
|
},
|
|
page: props.page.translation_key,
|
|
courseSession: courseSession.id,
|
|
});
|
|
const variables = reactive({
|
|
input,
|
|
});
|
|
log.debug(variables);
|
|
executeMutation(variables)
|
|
.then(({ data, error }) => {
|
|
log.debug(data);
|
|
log.error(error);
|
|
mutationResult.value = data;
|
|
})
|
|
.catch((e) => log.error(e));
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<LearningContentMultiLayout
|
|
:title="title"
|
|
subtitle="Feedback"
|
|
:learning-content-type="'feedback'"
|
|
:show-start-button="stepNo === 0"
|
|
:show-next-button="stepNo > 0 && stepNo + 1 < numSteps"
|
|
:show-previous-button="stepNo > 0"
|
|
:show-exit-button="stepNo + 1 === numSteps"
|
|
:current-step="stepNo"
|
|
:steps-count="numSteps"
|
|
:start-badge-text="$t('general.introduction')"
|
|
:end-badge-text="$t('general.submission')"
|
|
:base-url="props.page.frontend_url"
|
|
@previous="previousStep()"
|
|
@next="nextStep()"
|
|
>
|
|
<div>
|
|
<p v-if="stepNo === 0" class="mt-10">
|
|
{{
|
|
$t("feedback.intro", {
|
|
name: `${courseSessionsStore.circleExperts[0].first_name} ${courseSessionsStore.circleExperts[0].last_name}`,
|
|
})
|
|
}}
|
|
</p>
|
|
<p v-if="stepNo > 0 && stepNo + 1 < numSteps" class="pb-2">
|
|
{{ stepLabels[stepNo] }}
|
|
</p>
|
|
<ItRadioGroup
|
|
v-if="stepNo === 1"
|
|
v-model="satisfaction"
|
|
class="mb-8"
|
|
:items="RATINGS"
|
|
/>
|
|
<ItRadioGroup
|
|
v-if="stepNo === 2"
|
|
v-model="goalAttainment"
|
|
class="mb-8"
|
|
:items="RATINGS"
|
|
/>
|
|
<ItRadioGroup
|
|
v-if="stepNo === 3"
|
|
v-model="proficiency"
|
|
class="mb-8"
|
|
:items="PERCENTAGES"
|
|
/>
|
|
<ItRadioGroup
|
|
v-if="stepNo === 4"
|
|
v-model="preparationTaskClarity"
|
|
class="mb-8"
|
|
:items="YES_NO"
|
|
/>
|
|
<ItRadioGroup
|
|
v-if="stepNo === 5"
|
|
v-model="instructorCompetence"
|
|
class="mb-8"
|
|
:items="RATINGS"
|
|
/>
|
|
<ItRadioGroup
|
|
v-if="stepNo === 6"
|
|
v-model="instructorRespect"
|
|
class="mb-8"
|
|
:items="RATINGS"
|
|
/>
|
|
<ItTextarea v-if="stepNo === 7" v-model="instructorOpenFeedback" class="mb-8" />
|
|
<ItRadioGroup
|
|
v-if="stepNo === 8"
|
|
v-model="wouldRecommend"
|
|
class="mb-8"
|
|
:items="YES_NO"
|
|
/>
|
|
<ItTextarea v-if="stepNo === 9" v-model="courseNegativeFeedback" class="mb-8" />
|
|
<ItTextarea v-if="stepNo === 10" v-model="coursePositiveFeedback" class="mb-8" />
|
|
<FeedbackCompletition
|
|
v-if="stepNo === 11"
|
|
:avatar-url="courseSessionsStore.circleExperts[0].avatar_url"
|
|
:title="
|
|
$t('feedback.completionTitle', {
|
|
name: `${courseSessionsStore.circleExperts[0].first_name} ${courseSessionsStore.circleExperts[0].last_name}`,
|
|
})
|
|
"
|
|
:description="$t('feedback.completionDescription')"
|
|
:feedback-sent="mutationResult != null"
|
|
@send-feedback="sendFeedback"
|
|
/>
|
|
</div>
|
|
</LearningContentMultiLayout>
|
|
<!--
|
|
<pre>
|
|
satisfaction {{ satisfaction }}
|
|
goalAttainment {{ goalAttainment }}
|
|
proficiency {{ proficiency }}
|
|
receivedMaterials {{ receivedMaterials }}
|
|
materialsRating {{ materialsRating }}
|
|
instructorCompetence {{ instructorCompetence }}
|
|
instructorRespect {{ instructorRespect }}
|
|
instructorOpenFeedback {{ instructorOpenFeedback }}
|
|
wouldRecommend {{ wouldRecommend }}
|
|
coursePositiveFeedback {{ coursePositiveFeedback }}
|
|
courseNegativeFeedback {{ courseNegativeFeedback }}
|
|
mutationResult: {{ mutationResult }}
|
|
</pre> -->
|
|
</template>
|