207 lines
6.6 KiB
Vue
207 lines
6.6 KiB
Vue
<script setup lang="ts">
|
|
import { useTranslation } from "i18next-vue";
|
|
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
|
|
import LearningContentSimpleLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentSimpleLayout.vue";
|
|
import type { AssignmentCompletion, LearningContentEdoniqTest } from "@/types";
|
|
import { computed, ref } from "vue";
|
|
import * as log from "loglevel";
|
|
import { itPost } from "@/fetchHelpers";
|
|
import { useQuery } from "@urql/vue";
|
|
import { ASSIGNMENT_COMPLETION_QUERY } from "@/graphql/queries";
|
|
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
|
|
import dayjs from "dayjs";
|
|
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
|
|
import {
|
|
formatDueDate,
|
|
getDateString,
|
|
} from "../../../../components/dueDates/dueDatesUtils";
|
|
|
|
const { t } = useTranslation();
|
|
|
|
const props = defineProps<{
|
|
content: LearningContentEdoniqTest;
|
|
}>();
|
|
|
|
const courseSession = useCurrentCourseSession();
|
|
const courseSessionDetailResult = useCourseSessionDetailQuery();
|
|
|
|
const courseSessionEdoniqTest = computed(() => {
|
|
return courseSessionDetailResult.findEdoniqTest(props.content.id.toString());
|
|
});
|
|
|
|
const queryResult = useQuery({
|
|
query: ASSIGNMENT_COMPLETION_QUERY,
|
|
variables: {
|
|
courseSessionId: courseSession.value.id.toString(),
|
|
assignmentId: props.content.content_assignment_id.toString(),
|
|
learningContentId: props.content.id.toString(),
|
|
},
|
|
});
|
|
|
|
const assignmentCompletion = computed(
|
|
() =>
|
|
queryResult.data.value?.assignment_completion as AssignmentCompletion | undefined
|
|
);
|
|
|
|
const completionStatus = computed(() => {
|
|
return assignmentCompletion.value?.completion_status ?? "";
|
|
});
|
|
|
|
const termsAccepted = ref(false);
|
|
const extendedTimeTest = ref(false);
|
|
|
|
const deadlineInPast = computed(() => {
|
|
// with 16 minutes buffer
|
|
return dayjs(courseSessionEdoniqTest.value?.deadline.start)
|
|
.add(16, "minute")
|
|
.isBefore(dayjs());
|
|
});
|
|
|
|
async function startTest() {
|
|
log.info("start test", props.content);
|
|
|
|
if (assignmentCompletion.value?.edoniq_extended_time_flag) {
|
|
extendedTimeTest.value = true;
|
|
}
|
|
|
|
const response = await itPost("/api/core/edoniq-test/redirect/", {
|
|
learning_content_id: props.content.id,
|
|
extended_time_test: extendedTimeTest.value,
|
|
});
|
|
log.info(response.redirect_url);
|
|
window.open(response.redirect_url, "_blank");
|
|
}
|
|
</script>
|
|
|
|
<template>
|
|
<LearningContentSimpleLayout
|
|
:title="props.content.title"
|
|
:learning-content="props.content"
|
|
>
|
|
<div class="container-medium">
|
|
<section class="py-4">
|
|
<h3>{{ $t("a.Aufgabe") }}</h3>
|
|
<p class="mt-2 text-lg">{{ $t("edoniqTest.testDescription") }}</p>
|
|
</section>
|
|
|
|
<section v-if="courseSessionEdoniqTest" class="py-4">
|
|
<h3>{{ $t("a.Abgabetermin") }}</h3>
|
|
<p class="mt-2 text-lg">
|
|
{{
|
|
$t("edoniqTest.submitDateDescription", {
|
|
x: formatDueDate(courseSessionEdoniqTest.deadline.start),
|
|
})
|
|
}}
|
|
</p>
|
|
</section>
|
|
|
|
<section class="py-4">
|
|
<h3>{{ $t("a.Kompetenznachweis") }}</h3>
|
|
<div class="mt-2 text-lg">
|
|
{{
|
|
$t("circlePage.Dieser Inhalt gehört zu x", {
|
|
x: content.competence_certificate?.title,
|
|
})
|
|
}}.
|
|
</div>
|
|
<div class="mt-2 text-lg">
|
|
<router-link
|
|
:to="content.competence_certificate?.frontend_url ?? ''"
|
|
class="link"
|
|
data-cy="show-results"
|
|
>
|
|
{{ $t("circlePage.Im KompetenzNavi anschauen") }}
|
|
</router-link>
|
|
</div>
|
|
</section>
|
|
|
|
<section v-if="!completionStatus">
|
|
<div class="mt-8 border p-8">
|
|
<h3 class="mb-4">{{ $t("edoniqTest.checkboxTitle") }}</h3>
|
|
<ItCheckbox
|
|
v-if="props.content.checkbox_text"
|
|
:checkbox-item="{
|
|
label: props.content.checkbox_text,
|
|
value: termsAccepted,
|
|
checked: termsAccepted,
|
|
}"
|
|
@toggle="termsAccepted = !termsAccepted"
|
|
/>
|
|
</div>
|
|
<div class="my-8 border-b border-t py-8">
|
|
<h3 class="mb-4">{{ $t("edoniqTest.qualifiesForExtendedTimeTitle") }}</h3>
|
|
<ItCheckbox
|
|
v-if="props.content.has_extended_time_test"
|
|
:checkbox-item="{
|
|
label: t('edoniqTest.qualifiesForExtendedTime'),
|
|
value: extendedTimeTest,
|
|
checked: extendedTimeTest,
|
|
}"
|
|
@toggle="extendedTimeTest = !extendedTimeTest"
|
|
/>
|
|
</div>
|
|
|
|
<div>
|
|
<button
|
|
:disabled="!termsAccepted || deadlineInPast"
|
|
class="btn-primary inline-flex items-center"
|
|
@click="startTest()"
|
|
>
|
|
{{ $t("edoniqTest.startTest") }}
|
|
<it-icon-external-link class="it-icon ml-2 h-5 w-5"></it-icon-external-link>
|
|
</button>
|
|
|
|
<div class="mt-4">
|
|
<div v-if="deadlineInPast" class="text-error-red-500">
|
|
{{ $t("edoniqTest.deadlineInPast") }}
|
|
</div>
|
|
<div v-else>
|
|
{{ $t("a.Abgabetermin") }}:
|
|
{{ getDateString(dayjs(courseSessionEdoniqTest?.deadline.start)) }}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<section v-else>
|
|
<div v-if="assignmentCompletion" class="mt-8 border p-8" data-cy="test-result">
|
|
<ItSuccessAlert :text="$t('edoniqTest.testSubmitted')" />
|
|
<div class="my-4">
|
|
{{ $t("a.Resultat") }}:
|
|
<span class="font-bold">
|
|
{{ assignmentCompletion.evaluation_points }}
|
|
</span>
|
|
{{
|
|
$t("assignment.von x Punkten", {
|
|
x: assignmentCompletion.evaluation_max_points,
|
|
})
|
|
}}
|
|
({{
|
|
(
|
|
((assignmentCompletion.evaluation_points ?? 0) /
|
|
(assignmentCompletion.evaluation_max_points ?? 1)) *
|
|
100
|
|
).toFixed(0)
|
|
}}%)
|
|
<span
|
|
v-if="!assignmentCompletion.evaluation_passed"
|
|
class="rounded bg-error-red-200 px-2 py-1 text-sm"
|
|
>
|
|
{{ $t("a.Nicht Bestanden") }}
|
|
</span>
|
|
</div>
|
|
|
|
<div class="mt-4">
|
|
<button class="btn-primary inline-flex items-center" @click="startTest()">
|
|
{{ $t("edoniqTest.viewResults") }}
|
|
<it-icon-external-link
|
|
class="it-icon ml-2 h-5 w-5"
|
|
></it-icon-external-link>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
</LearningContentSimpleLayout>
|
|
</template>
|