vbv/client/src/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionView.vue

186 lines
6.0 KiB
Vue

<script setup lang="ts">
import DateEmbedding from "@/components/dueDates/DateEmbedding.vue";
import ItButton from "@/components/ui/ItButton.vue";
import ItCheckbox from "@/components/ui/ItCheckbox.vue";
import ItSuccessAlert from "@/components/ui/ItSuccessAlert.vue";
import { useCourseSessionDetailQuery, useCurrentCourseSession } from "@/composables";
import { bustItGetCache } from "@/fetchHelpers";
import { UPSERT_ASSIGNMENT_COMPLETION_MUTATION } from "@/graphql/mutations";
import AssignmentSubmissionResponses from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionResponses.vue";
import { useUserStore } from "@/stores/user";
import type { Assignment, AssignmentCompletion, AssignmentTask } from "@/types";
import { useMutation } from "@urql/vue";
import log from "loglevel";
import { computed, reactive } from "vue";
import { useTranslation } from "i18next-vue";
import eventBus from "@/utils/eventBus";
import dayjs from "dayjs";
import { useCircleStore } from "@/stores/circle";
const props = defineProps<{
assignment: Assignment;
learningContentId: string;
assignmentCompletion?: AssignmentCompletion;
courseSessionId: string;
submissionDeadlineStart?: string;
}>();
const emit = defineEmits<{
(e: "editTask", task: AssignmentTask): void;
}>();
const courseSession = useCurrentCourseSession();
const courseSessionDetailResult = useCourseSessionDetailQuery();
const circleStore = useCircleStore();
const { t } = useTranslation();
const state = reactive({
confirmInput: false,
confirmPerson: false,
});
const circleExperts = computed(() => {
if (circleStore.circle) {
return courseSessionDetailResult.filterCircleExperts(circleStore.circle.slug);
}
return [];
});
const circleExpert = computed(() => {
return circleExperts.value[0];
});
const circleExpertName = computed(() => {
return `${circleExpert.value?.first_name} ${circleExpert.value?.last_name}`;
});
const completionStatus = computed(() => {
return props.assignmentCompletion?.completion_status ?? "IN_PROGRESS";
});
const completionData = computed(() => {
return props.assignmentCompletion?.completion_data ?? {};
});
const canSubmit = computed(() => {
return (
!state.confirmInput ||
(props.assignment.assignment_type === "CASEWORK" && !state.confirmPerson)
);
});
const isCasework = computed(() => props.assignment.assignment_type === "CASEWORK");
const upsertAssignmentCompletionMutation = useMutation(
UPSERT_ASSIGNMENT_COMPLETION_MUTATION
);
const onEditTask = (task: AssignmentTask) => {
emit("editTask", task);
};
const onSubmit = async () => {
try {
await upsertAssignmentCompletionMutation.executeMutation({
assignmentId: props.assignment.id,
courseSessionId: courseSession.value.id,
learningContentId: props.learningContentId,
completionDataString: JSON.stringify({}),
completionStatus: "SUBMITTED",
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
id: props.assignmentCompletion?.id,
});
bustItGetCache(
`/api/course/completion/${courseSession.value.id}/${useUserStore().id}/`
);
eventBus.emit("finishedLearningContent", true);
} catch (error) {
log.error("Could not submit assignment", error);
}
};
</script>
<template>
<div class="w-full border border-gray-400 p-8">
<h3 class="heading-3 border-b border-gray-400 pb-6">
{{ $t("assignment.acceptConditionsDisclaimer") }}
</h3>
<div v-if="completionStatus === 'IN_PROGRESS'">
<ItCheckbox
class="w-full border-b border-gray-400 py-10 sm:py-6"
:checkbox-item="{
label: $t('assignment.confirmSubmitResults'),
value: 'value',
checked: state.confirmInput,
}"
data-cy="confirm-submit-results"
@toggle="state.confirmInput = !state.confirmInput"
></ItCheckbox>
<div v-if="isCasework" class="w-full border-b border-gray-400">
<ItCheckbox
class="py-6"
:checkbox-item="{
label: $t('assignment.confirmSubmitPerson'),
value: 'value',
checked: state.confirmPerson,
}"
data-cy="confirm-submit-person"
@toggle="state.confirmPerson = !state.confirmPerson"
></ItCheckbox>
<div class="flex flex-row items-center pb-6 pl-[49px]">
<img
alt="Notification icon"
class="mr-2 h-[45px] min-w-[45px] rounded-full"
:src="circleExpert.avatar_url"
/>
<p class="text-base font-bold">
{{ circleExpertName }}
</p>
</div>
<!-- TODO: find way to find user that will do the corrections -->
</div>
<div v-if="isCasework" class="flex flex-col space-x-2 pt-6 text-base sm:flex-row">
<p>{{ $t("assignment.assessmentDocumentDisclaimer") }}</p>
<a :href="props.assignment.evaluation_document_url" class="underline">
{{ $t("assignment.showAssessmentDocument") }}
</a>
</div>
<p v-if="isCasework && props.submissionDeadlineStart" class="pt-6">
{{ $t("assignment.dueDateSubmission") }}
<DateEmbedding
:single-date="dayjs(props.submissionDeadlineStart)"
></DateEmbedding>
</p>
<ItButton
class="mt-6"
variant="blue"
size="large"
:disabled="canSubmit"
data-cy="submit-assignment"
@click="onSubmit"
>
<p>{{ $t("assignment.submitAssignment") }}</p>
</ItButton>
</div>
<div v-else class="pt-6">
<ItSuccessAlert
:text="t('assignment.assignmentSubmitted')"
data-cy="success-text"
></ItSuccessAlert>
<p v-if="isCasework" class="pt-6">
{{
$t("assignment.submissionNotificationDisclaimer", { name: circleExpertName })
}}
</p>
</div>
</div>
<AssignmentSubmissionResponses
:assignment="props.assignment"
:assignment-completion-data="completionData"
:allow-edit="completionStatus === 'IN_PROGRESS'"
@edit-task="onEditTask"
></AssignmentSubmissionResponses>
</template>