135 lines
4.1 KiB
Vue
135 lines
4.1 KiB
Vue
<template>
|
|
<div class="se">
|
|
<BoxedIconTitleBlock
|
|
class="se__heading"
|
|
:title="exam?.title || 'آزمون'"
|
|
:desc="exam?.desc || 'جزئیات آزمون را مشاهده و سپس شروع آزمون را بزنید'"
|
|
>
|
|
<template #icon>
|
|
<SvgIcon name="pencil" :size="24" color="var(--color-primary)" />
|
|
</template>
|
|
</BoxedIconTitleBlock>
|
|
|
|
<SkeletonLoaderBlock v-if="isLoading && !exam" :rows="2" :cols-per-row="1" />
|
|
<StudentExamSummary v-else-if="exam" :exam="examSummary" @start="onStart" />
|
|
|
|
<SimpleTitleIconBlock title="تعداد تلاش ها برای این آزمون" class="se__list-title">
|
|
<template #header-icon>
|
|
<SvgIcon name="list-bullets" :size="16" color="#bcbcbc" />
|
|
</template>
|
|
</SimpleTitleIconBlock>
|
|
|
|
<SkeletonLoaderBlock v-if="isLoading && attempts.length === 0" :rows="2" :cols-per-row="1" />
|
|
<div v-else-if="attempts.length > 0">
|
|
<StudentExamAttemptItem v-for="attempt in attempts" :key="attempt.id" :attempt="attempt" />
|
|
</div>
|
|
<div v-else class="se__empty">
|
|
<SvgIcon name="scroll" :size="128" color="#c3c3c3" />
|
|
<p class="se__empty-title">طلبه گرامی</p>
|
|
<p class="se__empty-desc">شما تاکنون هیچ آزمونی را به شروع نکرده اید.</p>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
import { computed, ref } from 'vue'
|
|
import { useRoute, useRouter } from 'vue-router'
|
|
import SvgIcon from '@/components/icons/SvgIcon.vue'
|
|
import BoxedIconTitleBlock from '@/components/blocks/BoxedIconTitleBlock.vue'
|
|
import SkeletonLoaderBlock from '@/components/blocks/SkeletonLoaderBlock.vue'
|
|
import SimpleTitleIconBlock from '@/components/blocks/SimpleTitleIconBlock.vue'
|
|
import StudentExamSummary from '@/features/student/exams/components/StudentExamSummary.vue'
|
|
import { useStudentExamQuery, useStudentExamResultsQuery } from '@/services/query/student-exams'
|
|
import StudentExamAttemptItem from '@/features/student/exams/components/StudentExamAttemptItem.vue'
|
|
|
|
const route = useRoute()
|
|
const router = useRouter()
|
|
|
|
const examId = computed(() => route.params.id)
|
|
|
|
const { data: exam, isLoading } = useStudentExamQuery(examId, {
|
|
enabled: () => !!examId.value,
|
|
})
|
|
|
|
const resultsFilters = ref({})
|
|
const resultsPagination = ref({ page: 1, perPage: 50 })
|
|
const { data: results } = useStudentExamResultsQuery(resultsFilters, resultsPagination)
|
|
|
|
// Attempts on this exam, newest first, shaped for StudentExamAttemptItem.
|
|
const attempts = computed(() =>
|
|
(results.value?.data ?? [])
|
|
.filter((a) => String(a.examId) === String(examId.value))
|
|
.map((a) => ({
|
|
id: a.id,
|
|
title: exam.value?.title || 'آزمون',
|
|
score: a.score,
|
|
date: a.submittedAt,
|
|
status: a.isPassed ? 'passed' : 'failed',
|
|
statusLabel: a.isPassed ? 'قبول شده' : 'مردود',
|
|
}))
|
|
)
|
|
|
|
const examSummary = computed(() => {
|
|
const passed = attempts.value.some((a) => a.status === 'passed')
|
|
const status = passed ? 'passed' : attempts.value.length > 0 ? 'failed' : 'not_started'
|
|
const statusLabel = passed
|
|
? 'قبول شده اید'
|
|
: attempts.value.length > 0
|
|
? 'قبول نشده اید'
|
|
: 'شروع نشده'
|
|
return {
|
|
...exam.value,
|
|
attempts: attempts.value,
|
|
attemptsCount: attempts.value.length,
|
|
status,
|
|
statusLabel,
|
|
}
|
|
})
|
|
|
|
const onStart = () => {
|
|
router.push({ name: 'student-take-exam', params: { id: examId.value } }).catch(() => {})
|
|
}
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.se {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 0.75rem;
|
|
|
|
&__heading {
|
|
margin-bottom: 0.75rem;
|
|
}
|
|
|
|
&__list-title {
|
|
margin-block: 0.25rem;
|
|
}
|
|
|
|
&__empty {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 0.5rem;
|
|
padding: 2.5rem 1rem;
|
|
border-radius: 0.75rem;
|
|
}
|
|
|
|
&__empty-title {
|
|
font-family: var(--font-family-fa);
|
|
font-weight: 500;
|
|
font-size: 1rem;
|
|
color: #8e8e8e;
|
|
margin: 0.5rem 0 0;
|
|
}
|
|
|
|
&__empty-desc {
|
|
font-family: var(--font-family-fa);
|
|
font-weight: 400;
|
|
color: #4b4b4b;
|
|
font-size: 0.875rem;
|
|
margin: 0;
|
|
}
|
|
}
|
|
</style>
|