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

193 lines
6.3 KiB
Vue

<script setup lang="ts">
import EvaluationSummary from "@/pages/cockpit/assignmentEvaluationPage/EvaluationSummary.vue";
import AssignmentIntroductionView from "@/pages/learningPath/learningContentPage/assignment/AssignmentIntroductionView.vue";
import AssignmentSubmissionView from "@/pages/learningPath/learningContentPage/assignment/AssignmentSubmissionView.vue";
import AssignmentTaskView from "@/pages/learningPath/learningContentPage/assignment/AssignmentTaskView.vue";
import LearningContentMultiLayout from "@/pages/learningPath/learningContentPage/layouts/LearningContentMultiLayout.vue";
import { useAssignmentStore } from "@/stores/assignmentStore";
import { useCourseSessionsStore } from "@/stores/courseSessions";
import { useUserStore } from "@/stores/user";
import type {
Assignment,
AssignmentTask,
CourseSessionAssignmentDetails,
CourseSessionUser,
LearningContent,
} from "@/types";
import dayjs from "dayjs";
import * as log from "loglevel";
import { computed, onMounted, reactive } from "vue";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const courseSessionsStore = useCourseSessionsStore();
const assignmentStore = useAssignmentStore();
const userStore = useUserStore();
interface State {
assignment: Assignment | undefined;
courseSessionAssignmentDetails: CourseSessionAssignmentDetails | undefined;
pageIndex: number;
}
const state: State = reactive({
assignment: undefined,
courseSessionAssignmentDetails: undefined,
// 0 = introduction, 1 - n = tasks, n+1 = submission
pageIndex: 0,
});
const props = defineProps<{
assignmentId: number;
learningContent: LearningContent;
}>();
const assignmentCompletion = computed(() => assignmentStore.assignmentCompletion);
const completionStatus = computed(() => {
return assignmentCompletion.value?.completion_status ?? "in_progress";
});
onMounted(async () => {
log.debug("AssignmentView mounted", props.assignmentId, props.learningContent);
const courseSessionsStore = useCourseSessionsStore();
try {
state.assignment = await assignmentStore.loadAssignment(props.assignmentId);
state.courseSessionAssignmentDetails = courseSessionsStore.findAssignmentDetails(
props.learningContent.id
);
await assignmentStore.loadAssignmentCompletion(
props.assignmentId,
courseSessionId.value
);
if (completionStatus.value === "in_progress") {
state.pageIndex = 0;
} else {
state.pageIndex = numPages.value - 1;
}
} catch (error) {
log.error(error);
}
});
const numTasks = computed(() => state.assignment?.tasks?.length ?? 0);
const numPages = computed(() => numTasks.value + 2);
const showPreviousButton = computed(() => state.pageIndex != 0);
const showNextButton = computed(() => state.pageIndex + 1 < numPages.value);
const showExitButton = computed(() => numPages.value === state.pageIndex + 1);
const dueDate = computed(() =>
dayjs(state.courseSessionAssignmentDetails?.submissionDeadlineDateTimeUtc)
);
const courseSessionId = computed(
() => courseSessionsStore.currentCourseSession?.id ?? 0
);
const currentTask = computed(() => {
if (state.pageIndex > 0 && state.pageIndex <= numTasks.value) {
return state.assignment?.tasks[state.pageIndex - 1];
}
return undefined;
});
const handleBack = () => {
log.debug("handleBack");
if (state.pageIndex > 0) {
state.pageIndex -= 1;
}
log.debug(`pageIndex: ${state.pageIndex}`);
};
const handleContinue = () => {
log.debug("handleContinue");
if (state.pageIndex + 1 < numPages.value) {
state.pageIndex += 1;
}
log.debug(`pageIndex: ${state.pageIndex}`);
};
const jumpToTask = (task: AssignmentTask) => {
log.debug("jumpToTask", task);
const index = state.assignment?.tasks.findIndex((t) => t.id === task.id);
if (index && index >= 0) {
state.pageIndex = index + 1;
}
log.debug(`pageIndex: ${state.pageIndex}`);
};
const getTitle = () => {
if (0 === state.pageIndex) {
return t("general.introduction");
} else if (state.pageIndex === numPages.value - 1) {
return t("general.submission");
}
return currentTask?.value?.value.title ?? "Unknown";
};
const assignmentUser = computed(() => {
return (courseSessionsStore.currentCourseSession?.users ?? []).find(
(user) => user.user_id === Number(userStore.id)
) as CourseSessionUser;
});
</script>
<template>
<div v-if="state.assignment">
<div class="flex">
<LearningContentMultiLayout
:current-step="state.pageIndex"
:subtitle="state.assignment?.title ?? ''"
:title="getTitle()"
learning-content-type="assignment"
:steps-count="numPages"
:show-next-button="showNextButton"
:show-exit-button="showExitButton"
:show-start-button="false"
:show-previous-button="showPreviousButton"
start-badge-text="Einleitung"
end-badge-text="Abgabe"
close-button-variant="close"
@previous="handleBack()"
@next="handleContinue()"
>
<div class="flex">
<div>
<AssignmentIntroductionView
v-if="state.pageIndex === 0 && state.assignment"
:due-date="dueDate"
:assignment="state.assignment!"
></AssignmentIntroductionView>
<AssignmentTaskView
v-if="currentTask"
:task="currentTask"
:assignment-id="props.assignmentId"
></AssignmentTaskView>
<AssignmentSubmissionView
v-if="
state.pageIndex + 1 === numPages && state.assignment && courseSessionId
"
:due-date="dueDate"
:assignment="state.assignment!"
:assignment-completion-data="assignmentCompletion?.completion_data ?? {}"
:course-session-id="courseSessionId!"
@edit-task="jumpToTask($event)"
></AssignmentSubmissionView>
</div>
</div>
</LearningContentMultiLayout>
<div
v-if="assignmentCompletion?.completion_status === 'evaluation_submitted'"
class="min-w-2/5 mr-4 bg-gray-200 px-6 py-6"
>
<EvaluationSummary
v-if="state.assignment"
:assignment-user="assignmentUser"
:assignment="state.assignment"
:assignment-completion="assignmentCompletion"
:show-evaluation-user="true"
></EvaluationSummary>
</div>
</div>
</div>
</template>