fix: bugs
This commit is contained in:
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<div class="stat-card">
|
||||
<component
|
||||
:is="to ? RouterLink : 'div'"
|
||||
:to="to || undefined"
|
||||
class="stat-card"
|
||||
:class="{ 'stat-card--linked': to }"
|
||||
>
|
||||
<SvgIcon name="card-corner-arrow" :size="'1.5rem'" class="stat-card__corner" />
|
||||
|
||||
<div class="stat-card__head">
|
||||
@@ -14,10 +19,11 @@
|
||||
<span class="stat-card__subtitle">{{ subtitle }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { RouterLink } from 'vue-router'
|
||||
import SvgIcon from '@/components/icons/SvgIcon.vue'
|
||||
|
||||
defineProps({
|
||||
@@ -27,6 +33,7 @@ defineProps({
|
||||
value: { type: [String, Number], default: '' },
|
||||
unit: { type: String, default: '' },
|
||||
subtitle: { type: String, default: '' },
|
||||
to: { type: [String, Object], default: null },
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -41,6 +48,23 @@ defineProps({
|
||||
background: rgba(255, 255, 255, 58%);
|
||||
box-shadow: 0 6.75px 19.425px rgba(0, 0, 0, 4%);
|
||||
border-radius: 0.9375rem;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
|
||||
&--linked {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 9px 24px rgba(0, 0, 0, 7%);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
&__corner {
|
||||
position: absolute;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
</template>
|
||||
</BoxedIconTitleBlock>
|
||||
|
||||
<SkeletonLoaderBlock v-if="isLoading" :rows="1" :cols-per-row="3" />
|
||||
<SkeletonLoaderBlock v-if="isLoading" :rows="2" :cols-per-row="3" />
|
||||
<div v-else class="dashboard__stats">
|
||||
<DashboardStatCard
|
||||
v-for="(stat, i) in institutionStats"
|
||||
@@ -19,6 +19,7 @@
|
||||
:value="stat.value"
|
||||
:unit="stat.unit"
|
||||
:subtitle="stat.subtitle"
|
||||
:to="stat.to"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
@@ -95,37 +96,56 @@ const ACCESS_LABELS = {
|
||||
limited: 'محدود',
|
||||
}
|
||||
|
||||
const formatThousands = (value) => {
|
||||
const n = Number(value ?? 0)
|
||||
return n >= 1000
|
||||
? { value: toFaDigits(Math.round(n / 1000)), unit: 'هزار' }
|
||||
: { value: toFaDigits(n), unit: 'نفر' }
|
||||
}
|
||||
|
||||
const institutionStats = computed(() => {
|
||||
const stats = dashboard.value.stats ?? {}
|
||||
const users = formatThousands(stats.activeUsers)
|
||||
return [
|
||||
{
|
||||
icon: 'user',
|
||||
label: 'آمار کلی کاربران',
|
||||
value: users.value,
|
||||
unit: users.unit,
|
||||
subtitle: 'کاربر فعال',
|
||||
icon: 'users-three',
|
||||
label: 'مجموع کل متقاضیان',
|
||||
value: toFaDigits(stats.totalApplicants ?? 0),
|
||||
unit: 'نفر',
|
||||
subtitle: 'احراز شده و نشده',
|
||||
to: { name: 'admin-users' },
|
||||
},
|
||||
{
|
||||
icon: 'video',
|
||||
label: 'دوره های ایجاد شده',
|
||||
value: toFaDigits(stats.coursesCreated ?? 0),
|
||||
unit: 'دوره',
|
||||
subtitle: 'ایجاد شده',
|
||||
icon: 'clock',
|
||||
label: 'تعداد کاربران در انتظار ارزیابی',
|
||||
value: toFaDigits(stats.awaitingEvaluation ?? 0),
|
||||
unit: 'نفر',
|
||||
subtitle: 'در انتظار ارزیابی',
|
||||
to: { name: 'admin-user-verification' },
|
||||
},
|
||||
{
|
||||
icon: 'shopping-bag',
|
||||
label: 'دوره های فروش رفته',
|
||||
value: toFaDigits(stats.coursesSold ?? 0),
|
||||
unit: 'عدد',
|
||||
subtitle: 'دوره فروش رفته',
|
||||
icon: 'book',
|
||||
label: 'آمار طلبههای ترم ۱',
|
||||
value: toFaDigits(stats.term1Students ?? 0),
|
||||
unit: 'نفر',
|
||||
subtitle: 'ترم اول',
|
||||
to: { name: 'admin-terms' },
|
||||
},
|
||||
{
|
||||
icon: 'book',
|
||||
label: 'آمار طلبههای ترم ۲',
|
||||
value: toFaDigits(stats.term2Students ?? 0),
|
||||
unit: 'نفر',
|
||||
subtitle: 'ترم دوم',
|
||||
to: { name: 'admin-terms' },
|
||||
},
|
||||
{
|
||||
icon: 'book',
|
||||
label: 'آمار طلبههای ترم ۳',
|
||||
value: toFaDigits(stats.term3Students ?? 0),
|
||||
unit: 'نفر',
|
||||
subtitle: 'ترم سوم',
|
||||
to: { name: 'admin-terms' },
|
||||
},
|
||||
{
|
||||
icon: 'graduation-cap',
|
||||
label: 'آمار فارغالتحصیلان',
|
||||
value: toFaDigits(stats.graduates ?? 0),
|
||||
unit: 'نفر',
|
||||
subtitle: 'فارغالتحصیل',
|
||||
to: { name: 'admin-users' },
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
+137
-7
@@ -8,10 +8,15 @@
|
||||
:show-close-button="true"
|
||||
>
|
||||
<template #default>
|
||||
<div v-if="!user" class="user-verification-details">
|
||||
<div v-if="detailsLoading || !user" class="user-verification-details">
|
||||
<p class="user-verification-details__loading">در حال بارگذاری…</p>
|
||||
</div>
|
||||
<div v-else class="user-verification-details">
|
||||
<div v-else ref="pdfContent" class="user-verification-details">
|
||||
<header class="user-verification-details__pdf-header">
|
||||
<h1>اطلاعات احراز هویت کاربر</h1>
|
||||
<p>{{ fullName }}</p>
|
||||
</header>
|
||||
|
||||
<section class="user-verification-details__section">
|
||||
<div class="user-verification-details__grid user-verification-details__grid--6">
|
||||
<LineInfoBlock title="نام و نام خانوادگی" :numeric-desc="fullName" />
|
||||
@@ -178,15 +183,33 @@
|
||||
class="user-verification-details__video"
|
||||
/>
|
||||
</section>
|
||||
|
||||
<div class="user-verification-details__divider" />
|
||||
|
||||
<div class="user-verification-details__actions" data-pdf-ignore>
|
||||
<BaseButton
|
||||
text="ذخیره به صورت PDF"
|
||||
:loading="pdfLoading"
|
||||
custom-class="user-verification-details__pdf-btn"
|
||||
@click="onSaveAsPdf"
|
||||
>
|
||||
<template #appendIcon>
|
||||
<SvgIcon name="arrow-left" :size="18" color="#fff" />
|
||||
</template>
|
||||
</BaseButton>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</BasicModal>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { computed } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
import { toast } from 'vue3-toastify'
|
||||
import useModal from '@/composables/useModal'
|
||||
import BasicModal from '@/components/BasicModal.vue'
|
||||
import BaseButton from '@/components/BaseButton.vue'
|
||||
import SvgIcon from '@/components/icons/SvgIcon.vue'
|
||||
import { formatJalaaliDate } from '@/utils/date-utils'
|
||||
import LineTitleBlock from '@/components/LineTitleBlock.vue'
|
||||
import VoiceRecorder from '@/components/form/VoiceRecorder.vue'
|
||||
@@ -213,15 +236,19 @@ const modalData = computed(() => getModal('UserVerificationDetailsModal')?.data
|
||||
const userId = computed(() => modalData.value.id ?? null)
|
||||
const userIdRef = computed(() => userId.value)
|
||||
|
||||
const { data: fetched } = useAdminUserQuery(userIdRef, {
|
||||
const { data: fetched, isLoading: userLoading } = useAdminUserQuery(userIdRef, {
|
||||
enabled: () => !!userIdRef.value,
|
||||
})
|
||||
|
||||
const { data: registerData } = useAdminUserRegisterDataQuery(userIdRef, {
|
||||
enabled: () => !!userIdRef.value,
|
||||
})
|
||||
const { data: registerData, isLoading: registerDataLoading } = useAdminUserRegisterDataQuery(
|
||||
userIdRef,
|
||||
{
|
||||
enabled: () => !!userIdRef.value,
|
||||
}
|
||||
)
|
||||
|
||||
const user = computed(() => modalData.value.user || fetched.value || null)
|
||||
const detailsLoading = computed(() => userLoading.value || registerDataLoading.value)
|
||||
|
||||
const profile = computed(() => ({ ...user.value?.profile, ...registerData.value }))
|
||||
|
||||
@@ -263,6 +290,49 @@ const onlinePlatformDetails = computed(
|
||||
// `faithProductionAudio` / `leaderMessageVideo` (each carries a `url`).
|
||||
const faithProduction = computed(() => profile.value.faithProductionAudio || null)
|
||||
const leaderMessage = computed(() => profile.value.leaderMessageVideo || null)
|
||||
|
||||
const pdfContent = ref(null)
|
||||
const pdfLoading = ref(false)
|
||||
|
||||
const onSaveAsPdf = async () => {
|
||||
if (!pdfContent.value || !userId.value || detailsLoading.value || pdfLoading.value) return
|
||||
|
||||
pdfLoading.value = true
|
||||
try {
|
||||
await document.fonts?.ready
|
||||
|
||||
const pdfSource = pdfContent.value.cloneNode(true)
|
||||
pdfSource.classList.add('user-verification-details--pdf')
|
||||
pdfSource.querySelectorAll('[data-pdf-ignore]').forEach((element) => element.remove())
|
||||
|
||||
const html2pdfModule = await import('html2pdf.js')
|
||||
const html2pdf = html2pdfModule.default || html2pdfModule
|
||||
|
||||
await html2pdf()
|
||||
.set({
|
||||
margin: [8, 8, 8, 8],
|
||||
filename: `user-verification-${userId.value}.pdf`,
|
||||
image: { type: 'jpeg', quality: 0.98 },
|
||||
html2canvas: {
|
||||
scale: 2,
|
||||
useCORS: true,
|
||||
backgroundColor: '#ffffff',
|
||||
logging: false,
|
||||
},
|
||||
jsPDF: { unit: 'mm', format: 'a4', orientation: 'portrait' },
|
||||
pagebreak: {
|
||||
mode: ['css', 'legacy'],
|
||||
avoid: ['.user-verification-details__section'],
|
||||
},
|
||||
})
|
||||
.from(pdfSource)
|
||||
.save()
|
||||
} catch {
|
||||
toast.error('ساخت فایل PDF با خطا مواجه شد.')
|
||||
} finally {
|
||||
pdfLoading.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
@@ -270,6 +340,10 @@ const leaderMessage = computed(() => profile.value.leaderMessageVideo || null)
|
||||
width: 100%;
|
||||
text-align: start;
|
||||
|
||||
&__pdf-header {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&__loading {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
@@ -439,5 +513,61 @@ const leaderMessage = computed(() => profile.value.leaderMessageVideo || null)
|
||||
&__pdf-btn {
|
||||
min-width: 12rem;
|
||||
}
|
||||
|
||||
&--pdf {
|
||||
width: 100%;
|
||||
padding: 0.25rem;
|
||||
background: #fff;
|
||||
box-sizing: border-box;
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
&--pdf &__pdf-header {
|
||||
display: block;
|
||||
margin-bottom: 1.5rem;
|
||||
padding-bottom: 0.75rem;
|
||||
border-bottom: 1px solid #eee;
|
||||
text-align: right;
|
||||
break-after: avoid;
|
||||
|
||||
h1 {
|
||||
margin: 0;
|
||||
font-family: var(--font-family-fa);
|
||||
font-size: 1.25rem;
|
||||
font-weight: 500;
|
||||
color: #4b4b4b;
|
||||
}
|
||||
|
||||
p {
|
||||
margin: 0.25rem 0 0;
|
||||
font-family: var(--font-family-fa);
|
||||
font-size: 0.875rem;
|
||||
color: #808080;
|
||||
}
|
||||
}
|
||||
|
||||
&--pdf &__section {
|
||||
margin-bottom: 1rem;
|
||||
break-inside: avoid;
|
||||
page-break-inside: avoid;
|
||||
}
|
||||
|
||||
&--pdf &__grid--4 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
&--pdf &__grid--6 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
&--pdf &__cell--span-3 {
|
||||
grid-column: span 3;
|
||||
}
|
||||
|
||||
&--pdf :deep(.line-info__title) {
|
||||
overflow: visible;
|
||||
text-overflow: initial;
|
||||
white-space: normal;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
:value="stat.value"
|
||||
:unit="stat.unit"
|
||||
:subtitle="stat.subtitle"
|
||||
:to="stat.to"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
@@ -91,6 +92,7 @@ const ticketStats = computed(() => {
|
||||
value: toFaDigits(stats.openTickets ?? 0),
|
||||
unit: 'تیکت',
|
||||
subtitle: 'در انتظار پاسخ',
|
||||
to: { name: 'counselor-consultations' },
|
||||
},
|
||||
{
|
||||
icon: 'check-circle',
|
||||
@@ -98,6 +100,7 @@ const ticketStats = computed(() => {
|
||||
value: toFaDigits(stats.answeredTickets ?? 0),
|
||||
unit: 'تیکت',
|
||||
subtitle: 'پاسخ داده شده',
|
||||
to: { name: 'counselor-consultations' },
|
||||
},
|
||||
{
|
||||
icon: 'check',
|
||||
@@ -105,6 +108,7 @@ const ticketStats = computed(() => {
|
||||
value: toFaDigits(stats.closedTickets ?? 0),
|
||||
unit: 'تیکت',
|
||||
subtitle: 'بسته شده',
|
||||
to: { name: 'counselor-consultations' },
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
:value="stat.value"
|
||||
:unit="stat.unit"
|
||||
:subtitle="stat.subtitle"
|
||||
:to="stat.to"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
@@ -91,6 +92,7 @@ const requestStats = computed(() => {
|
||||
value: toFaDigits(stats.totalRequests ?? 0),
|
||||
unit: 'درخواست',
|
||||
subtitle: 'ثبت شده',
|
||||
to: { name: 'missionary-requests' },
|
||||
},
|
||||
{
|
||||
icon: 'check-circle',
|
||||
@@ -98,6 +100,7 @@ const requestStats = computed(() => {
|
||||
value: toFaDigits(stats.acceptedRequests ?? 0),
|
||||
unit: 'درخواست',
|
||||
subtitle: 'پذیرفته شده',
|
||||
to: { name: 'missionary-requests' },
|
||||
},
|
||||
{
|
||||
icon: 'clock',
|
||||
@@ -105,6 +108,7 @@ const requestStats = computed(() => {
|
||||
value: toFaDigits(stats.pendingRequests ?? 0),
|
||||
unit: 'درخواست',
|
||||
subtitle: 'در انتظار',
|
||||
to: { name: 'missionary-requests' },
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
:value="stat.value"
|
||||
:unit="stat.unit"
|
||||
:subtitle="stat.subtitle"
|
||||
:to="stat.to"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
@@ -95,6 +96,7 @@ const performanceStats = computed(() => {
|
||||
value: toFaDigits(stats.attendedSessions ?? 0),
|
||||
unit: 'جلسه',
|
||||
subtitle: 'اعزام شده است',
|
||||
to: { name: 'student-terms' },
|
||||
},
|
||||
{
|
||||
icon: 'video',
|
||||
@@ -102,6 +104,7 @@ const performanceStats = computed(() => {
|
||||
value: toFaDigits(stats.enrolledTerms ?? 0),
|
||||
unit: 'دوره',
|
||||
subtitle: 'خریداری شده',
|
||||
to: { name: 'student-terms' },
|
||||
},
|
||||
{
|
||||
icon: 'clock',
|
||||
@@ -109,6 +112,7 @@ const performanceStats = computed(() => {
|
||||
value: toFaDigits(stats.hoursSpent ?? 0),
|
||||
unit: 'ساعت',
|
||||
subtitle: 'گذرانده شده',
|
||||
to: { name: 'student-terms' },
|
||||
},
|
||||
]
|
||||
})
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
<template>
|
||||
<div class="stat-card">
|
||||
<component
|
||||
:is="to ? RouterLink : 'div'"
|
||||
:to="to || undefined"
|
||||
class="stat-card"
|
||||
:class="{ 'stat-card--linked': to }"
|
||||
>
|
||||
<SvgIcon name="card-corner-arrow" :size="'1.5rem'" class="stat-card__corner" />
|
||||
|
||||
<div class="stat-card__head">
|
||||
@@ -14,10 +19,11 @@
|
||||
<span class="stat-card__subtitle">{{ subtitle }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { RouterLink } from 'vue-router'
|
||||
import SvgIcon from '@/components/icons/SvgIcon.vue'
|
||||
|
||||
defineProps({
|
||||
@@ -27,6 +33,7 @@ defineProps({
|
||||
value: { type: [String, Number], default: '' },
|
||||
unit: { type: String, default: '' },
|
||||
subtitle: { type: String, default: '' },
|
||||
to: { type: [String, Object], default: null },
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -41,6 +48,23 @@ defineProps({
|
||||
background: rgba(255, 255, 255, 58%);
|
||||
box-shadow: 0 6.75px 19.425px rgba(0, 0, 0, 4%);
|
||||
border-radius: 0.9375rem;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
||||
|
||||
&--linked {
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 9px 24px rgba(0, 0, 0, 7%);
|
||||
}
|
||||
|
||||
&:focus-visible {
|
||||
outline: 2px solid var(--color-primary);
|
||||
outline-offset: 3px;
|
||||
}
|
||||
}
|
||||
|
||||
&__corner {
|
||||
position: absolute;
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
<form class="csf__form" @submit.prevent="onSubmit">
|
||||
<div class="csf__row">
|
||||
<div class="csf__cell">
|
||||
<TextField
|
||||
<SelectField
|
||||
v-model="form.category"
|
||||
name="category"
|
||||
label="نوع خدمت"
|
||||
placeholder="نوع خدمت را وارد کنید"
|
||||
placeholder="نوع خدمت را انتخاب کنید"
|
||||
:options="serviceTypeOptions"
|
||||
option-label="label"
|
||||
option-value="value"
|
||||
:error="errors.category"
|
||||
/>
|
||||
</div>
|
||||
@@ -71,6 +74,7 @@ import useYup from '@/composables/useYup'
|
||||
import BaseButton from '@/components/BaseButton.vue'
|
||||
import SvgIcon from '@/components/icons/SvgIcon.vue'
|
||||
import TextField from '@/components/form/TextField.vue'
|
||||
import SelectField from '@/components/form/SelectField.vue'
|
||||
import FileUploader from '@/components/form/FileUploader.vue'
|
||||
import { objectToFormData } from '@/utils/object-to-formdata'
|
||||
import { useUploadMediaMutation } from '@/services/query/auth'
|
||||
@@ -82,6 +86,11 @@ defineProps({
|
||||
|
||||
const emit = defineEmits(['submit', 'file-error'])
|
||||
|
||||
const serviceTypeOptions = [
|
||||
{ value: 'خدمات رفاهی', label: 'خدمات رفاهی' },
|
||||
{ value: 'خدمات آموزشی', label: 'خدمات آموزشی' },
|
||||
]
|
||||
|
||||
const form = ref({
|
||||
category: '',
|
||||
subject: '',
|
||||
@@ -94,7 +103,7 @@ const form = ref({
|
||||
const files = ref([])
|
||||
|
||||
const schema = yup.object({
|
||||
category: yup.string().trim().required('نوع خدمت را وارد کنید'),
|
||||
category: yup.string().trim().required('نوع خدمت را انتخاب کنید'),
|
||||
subject: yup.string().trim().required('عنوان خدمت را وارد کنید'),
|
||||
message: yup
|
||||
.string()
|
||||
|
||||
@@ -84,12 +84,6 @@ const menuItems = computed(() => [
|
||||
to: { name: 'student-services' },
|
||||
active: route.name === 'student-services',
|
||||
},
|
||||
{
|
||||
title: 'مشاوره',
|
||||
icon: 'chat-teardrop-text',
|
||||
to: { name: 'student-consultants' },
|
||||
active: route.name === 'student-consultants',
|
||||
},
|
||||
{
|
||||
title: 'گواهینامه',
|
||||
icon: 'certificate',
|
||||
|
||||
@@ -11,10 +11,16 @@ export const adminDashboard = {
|
||||
openTickets: 32,
|
||||
},
|
||||
stats: {
|
||||
activeUsers: 11_000,
|
||||
totalUsers: 11_540,
|
||||
coursesCreated: 6,
|
||||
coursesSold: 12,
|
||||
totalApplicants: 18,
|
||||
awaitingEvaluation: 1,
|
||||
term1Students: 2,
|
||||
term2Students: 0,
|
||||
term3Students: 1,
|
||||
graduates: 0,
|
||||
activeUsers: 11,
|
||||
totalUsers: 24,
|
||||
coursesCreated: 4,
|
||||
coursesSold: 3,
|
||||
},
|
||||
recentRegistrations: [
|
||||
{
|
||||
|
||||
@@ -2,4 +2,8 @@ import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { adminDashboard } from '@/services/mock/fixtures/admin-dashboard'
|
||||
|
||||
register('GET', endpoints.getAdminDashboard, () => ({ data: adminDashboard }))
|
||||
register('GET', endpoints.getAdminDashboard, () => ({
|
||||
success: true,
|
||||
message: 'انجام شد.',
|
||||
data: adminDashboard,
|
||||
}))
|
||||
|
||||
@@ -2,4 +2,8 @@ import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { counselorDashboard } from '@/services/mock/fixtures/counselor-dashboard'
|
||||
|
||||
register('GET', endpoints.getCounselorDashboard, () => ({ data: counselorDashboard }))
|
||||
register('GET', endpoints.getCounselorDashboard, () => ({
|
||||
success: true,
|
||||
message: 'انجام شد.',
|
||||
data: counselorDashboard,
|
||||
}))
|
||||
|
||||
@@ -2,4 +2,8 @@ import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { missionaryDashboard } from '@/services/mock/fixtures/missionary-dashboard'
|
||||
|
||||
register('GET', endpoints.getMissionaryDashboard, () => ({ data: missionaryDashboard }))
|
||||
register('GET', endpoints.getMissionaryDashboard, () => ({
|
||||
success: true,
|
||||
message: 'انجام شد.',
|
||||
data: missionaryDashboard,
|
||||
}))
|
||||
|
||||
@@ -2,4 +2,8 @@ import { register } from '@/services/mock/registry'
|
||||
import { endpoints } from '@/services/api/endpoints'
|
||||
import { studentDashboard } from '@/services/mock/fixtures/student-dashboard'
|
||||
|
||||
register('GET', endpoints.getStudentDashboard, () => ({ data: studentDashboard }))
|
||||
register('GET', endpoints.getStudentDashboard, () => ({
|
||||
success: true,
|
||||
message: 'انجام شد.',
|
||||
data: studentDashboard,
|
||||
}))
|
||||
|
||||
Reference in New Issue
Block a user