Refactor feedback component

This commit is contained in:
Ramon Wenger 2022-12-08 17:02:59 +01:00
parent fb10799140
commit dd30010269
6 changed files with 149 additions and 182 deletions

View File

@ -1,87 +1,83 @@
<template>
<div>
<div>
<p>Würden Sie den Kurs weiterempfehlen?</p>
<ItCheckbox :checked="wouldRecommend" @toggle="recommend = !recommend" />
</div>
<div>
<ItRadioGroup
v-model="satisfaction"
label="Zufriedenheit insgesamt"
:items="ratings"
/>
<ItRadioGroup
v-model="goalAttainment"
label="Zielerreichung insgesamt"
:items="ratings"
/>
<ItRadioGroup
v-model="proficiency"
label="Wie beurteilen Sie Ihre Sicherheit bezüglichen den Themen nach dem Kurs?"
:items="percentages"
/>
</div>
<ItRadioGroup
v-model="wouldRecommend"
label="Würden Sie den Kurs weiterempfehlen?"
class="mb-8"
:items="YES_NO"
/>
<ItRadioGroup
v-model="satisfaction"
label="Zufriedenheit insgesamt"
class="mb-8"
:items="RATINGS"
/>
<ItRadioGroup
v-model="goalAttainment"
label="Zielerreichung insgesamt"
class="mb-8"
:items="RATINGS"
/>
<ItRadioGroup
v-model="proficiency"
label="Wie beurteilen Sie Ihre Sicherheit bezüglichen den Themen nach dem Kurs?"
class="mb-8"
:items="PERCENTAGES"
/>
<ItRadioGroup
v-model="receivedMaterials"
label="Haben Sie Vorbereitungsunterlagen (z.B. eLearning) erhalten?"
:items="yesNo"
class="mb-8"
:items="YES_NO"
/>
<ItRadioGroup
v-model="materialsRating"
label="Falls ja: Wie beurteilen Sie die Vorbereitungsunterlagen (z.B.
eLearning)?"
:items="ratings"
class="mb-8"
:items="RATINGS"
/>
<ItRadioGroup
v-model="instructorCompetence"
label="Der Kursleiter war themenstark, fachkompetent."
:items="ratings"
class="mb-8"
:items="RATINGS"
/>
<ItRadioGroup
v-model="instructorRespect"
class="mb-8"
label="Fragen und Anregungen der Kursteilnehmenden wurden ernst
genommen u. aufgegriffen."
:items="ratings"
:items="RATINGS"
/>
<ItRadioGroup
v-model="howDiscovered"
label="Wie sind Sie auf das Kursangebot aufmerksam geworden?"
:items="discoveryReasons"
/>
<p>Was ich dem Kursleiter sonst noch sagen wollte:</p>
<textarea
v-model="instructorOpenFeedback"
rows="4"
class="block w-96 rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
/>
<div>
<p>Wo sehen Sie Verbesserungspotenzial?</p>
<div class="mb-8">
<p class="mb-4">Was ich dem Kursleiter sonst noch sagen wollte:</p>
<textarea
v-model="instructorOpenFeedback"
rows="4"
class="block w-full rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
/>
</div>
<div class="mb-8">
<p class="mb-4">Wo sehen Sie Verbesserungspotenzial?</p>
<textarea
v-model="courseNegativeFeedback"
rows="4"
class="block w-96 rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
class="block w-full rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
/>
<!-- class="block w-full rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"-->
</div>
<div>
<p>Was hat Ihnen besonders gut gefallen?</p>
<div class="mb-8">
<p class="mb-4">Was hat Ihnen besonders gut gefallen?</p>
<textarea
v-model="coursePositiveFeedback"
rows="4"
class="block w-96 rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
class="block w-full rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"
/>
<!-- class="block w-full rounded-md border-gray-300 py-3 px-4 shadow-sm focus:border-indigo-500 focus:ring-indigo-500"-->
</div>
<h3>Motivation</h3>
<ItCheckbox />
Persönliches Interesse
<ItCheckbox />
Berufliches Interesse
<ItCheckbox />
Pflichtkurs
<ItCheckbox />
Andere Gründe
<button @click="sendFeedback">Send!</button>
<button class="btn-blue" @click="sendFeedback">Senden und abschliessen</button>
<hr />
<pre>
satisfaction {{ satisfaction }}
goalAttainment {{ goalAttainment }}
@ -94,22 +90,29 @@ genommen u. aufgegriffen."
wouldRecommend {{ wouldRecommend }}
coursePositiveFeedback {{ coursePositiveFeedback }}
courseNegativeFeedback {{ courseNegativeFeedback }}
howDiscovered {{ howDiscovered }}
motivation {{ motivation }}
mutationResult: {{ mutationResult }}
</pre>
</div>
</template>
<script setup lang="ts">
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
import {
PERCENTAGES,
RATINGS,
YES_NO,
} from "@/components/learningPath/feedback.constants";
import ItRadioGroup from "@/components/ui/ItRadioGroup.vue";
import { COMPLETION_SUCCESS } from "@/constants";
import { graphql } from "@/gql/";
import type { SendFeedbackInput } from "@/gql/graphql";
import { useCircleStore } from "@/stores/circle";
import type { LearningContent } from "@/types";
import { useMutation } from "@urql/vue";
import log from "loglevel";
import { reactive, ref } from "vue";
const { page } = defineProps<{ page: LearningContent }>();
const sendFeedbackMutation = graphql(`
mutation SendFeedbackMutation($input: SendFeedbackInput!) {
sendFeedback(input: $input) {
@ -128,111 +131,14 @@ const sendFeedbackMutation = graphql(`
`);
const { executeMutation } = useMutation(sendFeedbackMutation);
const discoveryReasons = [
{
name: "Internet",
id: "I",
},
{
name: "Prospekt",
id: "L",
},
{
name: "Zeitung",
id: "N",
},
{
name: "Persönliche Empfehlung",
id: "R",
},
{
name: "Öffentliche Veranstaltung",
id: "E",
},
{
name: "Andere",
id: "O",
},
];
const yesNo = [
{
name: "Ja",
id: true,
},
{
name: "Nein",
id: false,
},
];
const ratings = [
{
name: "sehr unzufrieden",
id: 1,
},
{
name: "unzufrieden",
id: 2,
},
{
name: "zufrieden",
id: 3,
},
{
name: "sehr zufrieden",
id: 4,
},
];
const percentages = [
{
name: "20%",
id: 20,
},
{
name: "40%",
id: 40,
},
{
name: "60%",
id: 60,
},
{
name: "80%",
id: 80,
},
{
name: "100%",
id: 100,
},
];
const motivations = [
{
name: "Persönliches Interesse",
id: 1,
},
{
name: "Berufliches Interesse",
id: 2,
},
{
name: "Pflichtkurs",
id: 3,
},
{
name: "Andere Gründe",
id: 4,
},
];
const motivation = ref("");
const satisfaction = ref(0);
const goalAttainment = ref(0);
const wouldRecommend = ref(true);
const proficiency = ref(0);
const receivedMaterials = ref(false);
const satisfaction = ref(null);
const goalAttainment = ref(null);
const wouldRecommend = ref(null);
const proficiency = ref(null);
const receivedMaterials = ref(null);
const materialsRating = ref(null);
const instructorCompetence = ref(0);
const instructorRespect = ref(0);
const howDiscovered = ref("");
const instructorCompetence = ref(null);
const instructorRespect = ref(null);
const coursePositiveFeedback = ref("");
const courseNegativeFeedback = ref("");
const instructorOpenFeedback = ref("");
@ -240,12 +146,12 @@ const instructorOpenFeedback = ref("");
const mutationResult = ref<any>(null);
const sendFeedback = () => {
log.info("sending feedback");
const input: SendFeedbackInput = reactive({
materialsRating,
courseNegativeFeedback,
coursePositiveFeedback,
goalAttainment,
howDiscovered,
instructorCompetence,
instructorRespect,
instructorOpenFeedback,
@ -253,14 +159,18 @@ const sendFeedback = () => {
proficiency,
receivedMaterials,
wouldRecommend,
motivation,
page: page.translation_key,
});
const variables = reactive({
input,
});
executeMutation(variables).then(({ data }) => {
log.debug(data);
mutationResult.value = data;
});
log.debug(variables);
executeMutation(variables)
.then(({ data, error }) => {
log.debug(data);
log.error(error);
mutationResult.value = data;
})
.catch((e) => log.error(e));
};
</script>

View File

@ -4,6 +4,7 @@ import type { LearningUnit } from "@/types";
import * as log from "loglevel";
import LearningContentContainer from "@/components/learningPath/LearningContentContainer.vue";
import {COMPLETION_FAILURE, COMPLETION_SUCCESS} from "@/constants";
import { computed, reactive } from "vue";
log.debug("LearningContent.vue setup");
@ -83,7 +84,7 @@ function handleBack() {
'border-2': currentQuestion.completion_status === 'success',
}"
data-cy="success"
@click="circleStore.markCompletion(currentQuestion, 'success')"
@click="circleStore.markCompletion(currentQuestion, COMPLETION_SUCCESS)"
>
<it-icon-smiley-happy class="w-16 h-16 mr-4"></it-icon-smiley-happy>
<span class="font-bold text-large">{{ $t("selfEvaluation.yes") }}.</span>
@ -91,8 +92,8 @@ function handleBack() {
<button
class="flex-1 inline-flex items-center text-left p-4 border"
:class="{
'border-orange-500': currentQuestion.completion_status === 'fail',
'border-2': currentQuestion.completion_status === 'fail',
'border-orange-500': currentQuestion.completion_status === COMPLETION_FAILURE,
'border-2': currentQuestion.completion_status === COMPLETION_FAILURE,
}"
data-cy="fail"
@click="circleStore.markCompletion(currentQuestion, 'fail')"

View File

@ -0,0 +1,52 @@
import type { RadioItem } from "@/components/learningPath/feedback.types";
export const YES_NO: RadioItem<boolean>[] = [
{
name: "Ja",
value: true,
},
{
name: "Nein",
value: false,
},
];
export const RATINGS: RadioItem<number>[] = [
{
name: "sehr unzufrieden",
value: 1,
},
{
name: "unzufrieden",
value: 2,
},
{
name: "zufrieden",
value: 3,
},
{
name: "sehr zufrieden",
value: 4,
},
];
export const PERCENTAGES: RadioItem<number>[] = [
{
name: "20%",
value: 20,
},
{
name: "40%",
value: 40,
},
{
name: "60%",
value: 60,
},
{
name: "80%",
value: 80,
},
{
name: "100%",
value: 100,
},
];

View File

@ -0,0 +1,4 @@
export interface RadioItem<T> {
value: T;
name: string;
}

3
client/src/constants.ts Normal file
View File

@ -0,0 +1,3 @@
export const COMPLETION_SUCCESS = "success";
export const COMPLETION_FAILURE = "fail";
export const COMPLETION_UNKNOWN = "unknown";

View File

@ -1679,20 +1679,19 @@ export type SecurityRequestResponseLog = {
export type SendFeedbackInput = {
clientMutationId?: InputMaybe<Scalars['String']>;
courseNegativeFeedback: Scalars['String'];
coursePositiveFeedback: Scalars['String'];
goalAttainment: Scalars['Int'];
howDiscovered: Scalars['String'];
courseNegativeFeedback?: InputMaybe<Scalars['String']>;
coursePositiveFeedback?: InputMaybe<Scalars['String']>;
goalAttainment?: InputMaybe<Scalars['Int']>;
id?: InputMaybe<Scalars['Int']>;
instructorCompetence: Scalars['Int'];
instructorOpenFeedback: Scalars['String'];
instructorRespect: Scalars['Int'];
instructorCompetence?: InputMaybe<Scalars['Int']>;
instructorOpenFeedback?: InputMaybe<Scalars['String']>;
instructorRespect?: InputMaybe<Scalars['Int']>;
materialsRating?: InputMaybe<Scalars['Int']>;
motivation: Scalars['String'];
proficiency: Scalars['Int'];
receivedMaterials: Scalars['Boolean'];
satisfaction: Scalars['Int'];
wouldRecommend: Scalars['Boolean'];
page: Scalars['String'];
proficiency?: InputMaybe<Scalars['Int']>;
receivedMaterials?: InputMaybe<Scalars['Boolean']>;
satisfaction?: InputMaybe<Scalars['Int']>;
wouldRecommend?: InputMaybe<Scalars['Boolean']>;
};
export type SendFeedbackPayload = {
@ -1702,13 +1701,11 @@ export type SendFeedbackPayload = {
coursePositiveFeedback?: Maybe<Scalars['String']>;
errors?: Maybe<Array<Maybe<ErrorType>>>;
goalAttainment?: Maybe<Scalars['Int']>;
howDiscovered?: Maybe<Scalars['String']>;
id?: Maybe<Scalars['Int']>;
instructorCompetence?: Maybe<Scalars['Int']>;
instructorOpenFeedback?: Maybe<Scalars['String']>;
instructorRespect?: Maybe<Scalars['Int']>;
materialsRating?: Maybe<Scalars['Int']>;
motivation?: Maybe<Scalars['String']>;
proficiency?: Maybe<Scalars['Int']>;
receivedMaterials?: Maybe<Scalars['Boolean']>;
satisfaction?: Maybe<Scalars['Int']>;