fix: bugs

This commit is contained in:
sajjadtalkhabi
2026-07-30 17:38:27 +03:30
parent e8b1e4add6
commit 36b747d267
34 changed files with 301 additions and 84 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
<meta charset="UTF-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Banu</title>
<title>مدرسه بانو</title>
</head>
<body>
<div id="app"></div>
+4
View File
@@ -4,6 +4,10 @@
box-sizing: border-box;
}
html {
font-size: 106.25%;
}
body {
margin: 0 !important;
padding: 0 !important;
+21 -21
View File
@@ -1,6 +1,6 @@
@font-face {
font-family: montserrat;
src: url('../fonts/montserrat/Montserrat-ExtraLight.ttf') format('truetype');
src: url('../fonts/montserrat/Montserrat-Regular.ttf') format('truetype');
font-weight: 200;
font-style: normal;
font-display: swap;
@@ -16,8 +16,8 @@
@font-face {
font-family: aria;
src: url('../fonts/aria/AriaWebFaNum-Light.woff2') format('woff2');
font-weight: 300;
src: url('../fonts/aria/AriaWeb-Normal.woff2') format('woff2');
font-weight: 200;
font-style: normal;
font-display: swap;
}
@@ -25,7 +25,7 @@
@font-face {
font-family: aria;
src: url('../fonts/aria/AriaWebFaNum-Regular.woff2') format('woff2');
font-weight: 400;
font-weight: 300;
font-style: normal;
font-display: swap;
}
@@ -33,6 +33,14 @@
@font-face {
font-family: aria;
src: url('../fonts/aria/AriaWebFaNum-Medium.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: aria;
src: url('../fonts/aria/AriaWebFaNum-SemiBold.woff2') format('woff2');
font-weight: 500;
font-style: normal;
font-display: swap;
@@ -46,25 +54,17 @@
font-display: swap;
}
@font-face {
font-family: aria;
src: url('../fonts/aria/AriaWeb-Normal.woff2') format('woff2');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: iran-yekan;
src: url('../fonts/iran-yekan/iranyekanwebregularfanum.woff') format('woff');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: iran-yekan;
src: url('../fonts/iran-yekan/iranyekanwebmediumfanum.woff') format('woff');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: iran-yekan;
src: url('../fonts/iran-yekan/iranyekanwebboldfanum.woff') format('woff');
font-weight: 500;
font-style: normal;
font-display: swap;
@@ -80,7 +80,7 @@
@font-face {
font-family: iran-yekan;
src: url('../fonts/iran-yekan/iranyekanweblightfanum.woff') format('woff');
src: url('../fonts/iran-yekan/iranyekanwebregularfanum.woff') format('woff');
font-weight: 300;
font-style: normal;
font-display: swap;
+3 -3
View File
@@ -94,10 +94,10 @@ const props = defineProps({
name: { type: String, default: '' },
vibration: { type: Boolean, default: false },
bgColor: { type: String, default: '#f3f4f6' },
maxSize: { type: Number, default: 250 * 1024 },
maxSize: { type: Number, default: 5 * 1024 * 1024 },
helperText: {
type: String,
default: 'سایز تصویر رسمی 3x4 و حجم تصویر بیشتر از 250 کیلو بایت نباشد.',
default: 'سایز تصویر رسمی 3x4 و حجم تصویر بیشتر از 5 مگابایت نباشد.',
},
helperIcon: { type: String, default: 'warning' },
error: { type: String, default: '' },
@@ -144,7 +144,7 @@ const onFileChange = (event) => {
if (!file) return
if (props.maxSize > 0 && file.size > props.maxSize) {
emit('error', 'حجم تصویر نباید بیشتر از ۲۵۰ کیلوبایت باشد.')
emit('error', 'حجم تصویر نباید بیشتر از ۵ مگابایت باشد.')
event.target.value = null
return
}
+4 -1
View File
@@ -15,6 +15,10 @@ export const fields = {
lastName: 'نام خانوادگی',
nationalCode: 'کد ملی',
postalCode: 'کد پستی',
virtualPhoneNumber: 'شماره تلفن مجازی',
seminaryCode: 'کد حوزوی',
seminaryServiceCenterCode: 'کد مرکز خدمات حوزه',
childrenCount: 'تعداد فرزند',
birthDate: 'تاریخ تولد',
birthday: 'تاریخ تولد',
@@ -75,7 +79,6 @@ export const fields = {
seminaryLevel: 'مقطع حوزه',
universityLevel: 'مقطع دانشگاهی',
universityName: 'نام حوزه علمیه / دانشگاه',
workExperienceSummary: 'خلاصهٔ سوابق شغلی',
hijabApproach: 'رویکرد حجاب',
prerequisites: 'پیش‌نیازها',
-4
View File
@@ -53,8 +53,6 @@ export const USER_STATUS = Object.freeze({
export const MARITAL_STATUS = Object.freeze({
single: 'مجرد',
married: 'متاهل',
divorced: 'مطلقه',
widowed: 'بیوه',
})
export const GENDER = Object.freeze({
@@ -68,7 +66,6 @@ export const CHANGEABLE_ROLES = Object.freeze(ROLES.filter((r) => r.changeable).
export const EDUCATION_STATUS = Object.freeze({
seminary_student: 'طلبه',
seminary_and_university_student: 'طلبه و دانشجو',
graduate: 'فارغ التحصیلی',
})
@@ -76,7 +73,6 @@ export const SEMINARY_LEVEL = Object.freeze({
level_2: 'سطح دو',
level_3: 'سطح سه',
level_4: 'سطح چهار',
not_applicable: 'طلبه نیستم',
})
export const UNIVERSITY_LEVEL = Object.freeze({
@@ -1,9 +1,9 @@
<template>
<div class="dashboard">
<div class="dashboard__main">
<!-- اطلاعات موسسه -->
<!-- اطلاعات مدرسه -->
<section class="dashboard__section">
<BoxedIconTitleBlock title="اطلاعات موسسه" desc="آخرین اطلاعات موسسه شما.">
<BoxedIconTitleBlock title="اطلاعات مدرسه" desc="آخرین اطلاعات مدرسه شما.">
<template #icon>
<SvgIcon name="heart" :size="24" color="var(--color-primary)" />
</template>
+1 -1
View File
@@ -7,7 +7,7 @@ export default [
layout: 'admin',
role: 'admin',
title: 'سلام بر شما',
subtitle: 'به سامانه موسسه بانو خوش آمدید.',
subtitle: 'به سامانه مدرسه بانو خوش آمدید.',
},
},
{
@@ -59,12 +59,6 @@
<section class="user-verification-details__section">
<LineTitleBlock title="اطلاعات شغلی" title-en="Job information" />
<div class="user-verification-details__grid user-verification-details__grid--4">
<div class="user-verification-details__cell user-verification-details__cell--full">
<LineInfoBlock
title="خلاصه‌ای از سوابق شغلی"
:desc="profile.workExperienceSummary || ''"
/>
</div>
<div class="user-verification-details__cell user-verification-details__cell--full">
<LineInfoBlock
title="خلاصه‌ای از فعالیت‌ها در موقعیت‌های شغلی"
+1 -1
View File
@@ -1,6 +1,6 @@
<template>
<div class="auth-heading">
<img :src="logo" alt="banu" class="auth-heading__logo" />
<img :src="logo" alt="مدرسه بانو" class="auth-heading__logo" />
<h2 class="auth-heading__title">{{ title }}</h2>
<p v-if="step === 'otp'" class="auth-heading__subtitle">
<span class="auth-heading__phone-label">ارسال کد فعالسازی به شماره</span>
@@ -2,7 +2,7 @@
<div class="pattern-section">
<div class="pattern-section__bg" :style="{ backgroundImage: `url(${bgImage})` }" />
<div class="pattern-section__front">
<img :src="frontImage" alt="banu" />
<img :src="frontImage" alt="مدرسه بانو" />
</div>
</div>
</template>
@@ -144,7 +144,7 @@ const onResend = async () => {
const body = { phone: props.phoneNumber }
if (props.mode === 'forgotPassword') await forgotMutation.mutateAsync(body)
else if (props.mode === 'loginWithCode') await requestLoginOtpMutation.mutateAsync(body)
else await resendCodeMutation.mutateAsync({ phoneNumber: props.phoneNumber })
else await resendCodeMutation.mutateAsync(body)
}
</script>
@@ -28,7 +28,7 @@
<SelectField
v-model="form.universityLevel"
name="universityLevel"
label="آخرین مدرک تحصیلی"
label="آخرین مدرک تحصیلی دانشگاهی"
:options="universityLevelOptions"
option-label="label"
option-value="value"
@@ -65,20 +65,6 @@
<LineTitleBlock title="مشخصات شغلی" title-en="Job Details" />
<div class="educational-info__row">
<div class="educational-info__cell educational-info__cell--full">
<TextareaField
v-model="form.workExperienceSummary"
name="workExperienceSummary"
label="خلاصه ای از سوابق شغلی خود را ذکر بفرمایید."
:row="isMobile ? 5 : 1"
:error="errors.workExperienceSummary"
@blur="validateAt('workExperienceSummary', form.workExperienceSummary)"
>
<template #appendIcon>
<SvgIcon name="file" :size="20" color="var(--color-thd-gray)" />
</template>
</TextareaField>
</div>
<div class="educational-info__cell educational-info__cell--full">
<TextareaField
v-model="form.activitySummary"
@@ -75,6 +75,51 @@
:error="errors.gender"
/>
</div>
<div class="personal-info__cell">
<TextField
v-model="form.childrenCount"
name="childrenCount"
label="تعداد فرزند"
inputmode="numeric"
:convert-digits="true"
:error="errors.childrenCount"
@blur="validateAt('childrenCount', form.childrenCount)"
>
<template #appendIcon>
<SvgIcon name="users-three" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
<div class="personal-info__cell">
<TextField
v-model="form.seminaryCode"
name="seminaryCode"
label="کد حوزوی"
inputmode="numeric"
:convert-digits="true"
:error="errors.seminaryCode"
@blur="validateAt('seminaryCode', form.seminaryCode)"
>
<template #appendIcon>
<SvgIcon name="graduation-cap" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
<div class="personal-info__cell">
<TextField
v-model="form.seminaryServiceCenterCode"
name="seminaryServiceCenterCode"
label="کد مرکز خدمات حوزه"
inputmode="numeric"
:convert-digits="true"
:error="errors.seminaryServiceCenterCode"
@blur="validateAt('seminaryServiceCenterCode', form.seminaryServiceCenterCode)"
>
<template #appendIcon>
<SvgIcon name="check-square" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
</div>
<LineTitleBlock title="اطلاعات تماس" title-en="Contact Details" />
@@ -95,6 +140,36 @@
</template>
</TextField>
</div>
<div class="personal-info__cell">
<TextField
v-model="form.virtualPhoneNumber"
name="virtualPhoneNumber"
label="شماره تلفن مجازی"
inputmode="numeric"
:convert-digits="true"
:error="errors.virtualPhoneNumber"
@blur="validateAt('virtualPhoneNumber', form.virtualPhoneNumber)"
>
<template #appendIcon>
<SvgIcon name="phone" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
<div class="personal-info__cell">
<TextField
v-model="form.postalCode"
name="postalCode"
label="کد پستی"
inputmode="numeric"
:convert-digits="true"
:error="errors.postalCode"
@blur="validateAt('postalCode', form.postalCode)"
>
<template #appendIcon>
<SvgIcon name="map-pin-simple-area" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
<div class="personal-info__cell">
<SelectField
v-model="form.provinceId"
@@ -141,7 +216,11 @@
<StepActions
:show-back="false"
:loading="uploadMutation.isPending.value || updateProfileMutation.isPending.value"
:loading="
uploadMutation.isPending.value ||
updateProfileMutation.isPending.value ||
saveRegisterMutation.isPending.value
"
/>
</form>
</template>
@@ -166,7 +245,12 @@ import { personalInformationSchema } from '@/features/auth/schema/student-regist
import StepActions from '@/features/auth/components/studentRegister/StepActions.vue'
import { useStudentRegistrationStore } from '@/features/auth/store/student-registration'
import { useGetCitiesOfProvinceQuery, useGetProvincesQuery } from '@/services/query/common'
import { authKeys, useUpdateProfileMutation, useUploadMediaMutation } from '@/services/query/auth'
import {
authKeys,
useSaveRegisterDataMutation,
useUpdateProfileMutation,
useUploadMediaMutation,
} from '@/services/query/auth'
const store = useStudentRegistrationStore()
const { user } = useAuth()
@@ -212,6 +296,11 @@ const form = ref({
cityId: user.value?.cityId || store.personal.cityId || null,
address:
(typeof user.value?.address === 'string' && user.value.address) || store.personal.address || '',
postalCode: store.personal.postalCode || '',
virtualPhoneNumber: store.personal.virtualPhoneNumber || '',
seminaryCode: store.personal.seminaryCode || '',
seminaryServiceCenterCode: store.personal.seminaryServiceCenterCode || '',
childrenCount: store.personal.childrenCount ?? '',
avatar: initialAvatar,
avatarId: store.personal.avatarId || '',
})
@@ -258,6 +347,7 @@ const onAvatarCropped = async (file) => {
const onAvatarError = (msg) => toast.error(msg)
const updateProfileMutation = useUpdateProfileMutation()
const saveRegisterMutation = useSaveRegisterDataMutation()
const onSubmit = async () => {
const { isValid, payload } = await validate(form.value)
@@ -280,6 +370,13 @@ const onSubmit = async () => {
: {}),
}
await updateProfileMutation.mutateAsync(body)
await saveRegisterMutation.mutateAsync({
postalCode: payload.postalCode,
virtualPhoneNumber: payload.virtualPhoneNumber,
seminaryCode: payload.seminaryCode,
seminaryServiceCenterCode: payload.seminaryServiceCenterCode,
childrenCount: payload.childrenCount,
})
await queryClient.invalidateQueries({ queryKey: authKeys.me() })
store.personal = { ...store.personal, ...next }
store.markStepAsCompleted(STUDENT_REGISTRATION.PERSONAL_INFORMATION)
@@ -1,6 +1,6 @@
<template>
<form class="professional-info" @submit.prevent="onSubmit">
<LineTitleBlock title="مشخصات شغلی" title-en="Job Details" />
<LineTitleBlock title="مشخصات تبلیغی" title-en="Propagation Details" />
<div class="professional-info__row">
<div class="professional-info__cell professional-info__cell--5">
<TextField
@@ -49,7 +49,7 @@
<SelectField
v-model="form.propagationPlatforms"
name="propagationPlatforms"
label="در چه بستر هایی فعالیت تبلیغی داشته اید؟"
label="در چه بستر هایی فعالیت تبلیغی داشته اید؟ (امکان انتخاب چند گزینه وجود دارد)"
:options="platformOptions"
option-label="label"
option-value="value"
@@ -1,11 +1,11 @@
<template>
<aside class="sidebar-steps">
<div class="sidebar-steps__mobile-logo">
<img :src="logoPinkishRed" alt="banu" />
<img :src="logoPinkishRed" alt="مدرسه بانو" />
</div>
<div class="sidebar-steps__panel">
<div class="sidebar-steps__logo">
<img :src="logoWhite" alt="banu" />
<img :src="logoWhite" alt="مدرسه بانو" />
</div>
<ul class="sidebar-steps__list">
<li
@@ -93,8 +93,8 @@ const STEP_LABELS = {
desc: 'لطفاً اطلاعات تحصیلی و شغلی خود را به‌صورت کامل و دقیق وارد کنید',
},
[STUDENT_REGISTRATION.PROFESSIONAL_INFORMATION]: {
title: 'اطلاعات فعالیت تبلیغاتی و حرفه‌ای',
desc: 'لطفاً اطلاعات تبلیغاتی و حرفه‌ای خود را به‌صورت کامل و دقیق وارد کنید',
title: 'اطلاعات فعالیت‌های تبلیغی',
desc: 'لطفاً اطلاعات فعالیت‌های تبلیغی خود را به‌صورت کامل و دقیق وارد کنید',
},
[STUDENT_REGISTRATION.SKILL_ASSESSMENT_PART_1]: {
title: 'بخش مهارت (بخش اول)',
+9 -1
View File
@@ -20,6 +20,15 @@ export const personalInformationSchema = object().shape({
provinceId: mixed().required(),
cityId: mixed().required(),
address: requiredString(10),
postalCode: string()
.required()
.matches(/^\d{10}$/, 'کد پستی باید ۱۰ رقم باشد'),
virtualPhoneNumber: string()
.required()
.matches(/^\d{10,15}$/, 'شماره تلفن مجازی نامعتبر است'),
seminaryCode: requiredString(),
seminaryServiceCenterCode: requiredString(),
childrenCount: number().typeError('تعداد فرزند باید عدد باشد').required().min(0).max(20),
})
export const educationalInformationSchema = object().shape({
@@ -28,7 +37,6 @@ export const educationalInformationSchema = object().shape({
universityLevel: string().required(),
universityName: requiredString(5),
fieldOfStudy: requiredString(5),
workExperienceSummary: requiredString(10),
activitySummary: requiredString(10),
})
@@ -18,6 +18,11 @@ const emptyState = () => ({
provinceId: null,
cityId: null,
address: '',
postalCode: '',
virtualPhoneNumber: '',
seminaryCode: '',
seminaryServiceCenterCode: '',
childrenCount: '',
},
educational: {
educationStatus: '',
@@ -25,7 +30,6 @@ const emptyState = () => ({
universityLevel: '',
universityName: '',
fieldOfStudy: '',
workExperienceSummary: '',
activitySummary: '',
},
professional: {
@@ -83,6 +87,11 @@ const SECTION_FIELDS = {
'provinceId',
'cityId',
'address',
'postalCode',
'virtualPhoneNumber',
'seminaryCode',
'seminaryServiceCenterCode',
'childrenCount',
],
educational: [
'educationStatus',
@@ -90,7 +99,6 @@ const SECTION_FIELDS = {
'universityLevel',
'universityName',
'fieldOfStudy',
'workExperienceSummary',
'activitySummary',
],
professional: [
+1 -1
View File
@@ -7,7 +7,7 @@ export default [
layout: 'counselor',
role: 'counselor',
title: 'سلام بر شما',
subtitle: 'به پنل مشاوره بانو خوش آمدید.',
subtitle: 'به پنل مشاوره مدرسه بانو خوش آمدید.',
},
},
{
@@ -10,7 +10,7 @@
<template #default="{ data, close }">
<form class="sample-modal__form" @submit.prevent="onSubmit(close)">
<p class="sample-modal__intro">
این مودال الگوی استاندارد بنو است: عنوان با
این مودال الگوی استاندارد مدرسه بانو است: عنوان با
<code>LineTitleBlock</code>
در راست، دکمهٔ بستن داخلی در چپ.
</p>
@@ -82,6 +82,7 @@ const onSubmit = async (close) => {
close()
form.value = { subject: '', note: '' }
resetErrors()
// eslint-disable-next-line no-console
console.info('SampleModal submit', payload)
}
</script>
@@ -142,7 +142,7 @@
/>
<BaseButton
variant="secondary"
text="نمایش مودال نمونه (الگوی بنو)"
text="نمایش مودال نمونه (الگوی مدرسه بانو)"
customClass="global-components__btn-wide"
@click="openModal('SampleModal', { context: 'پیش‌نمایش' })"
/>
+1 -1
View File
@@ -7,7 +7,7 @@ export default [
layout: 'missionary',
role: 'missionary',
title: 'سلام بر شما',
subtitle: 'به پنل اعزام بانو خوش آمدید.',
subtitle: 'به پنل اعزام مدرسه بانو خوش آمدید.',
},
},
{
@@ -101,6 +101,66 @@
option-value="value"
/>
</div>
<div class="edit-profile__cell edit-profile__cell--third">
<TextField
v-model="form.childrenCount"
name="childrenCount"
label="تعداد فرزند"
inputmode="numeric"
:convert-digits="true"
:error="errors.childrenCount"
@blur="validateAt('childrenCount', form.childrenCount)"
>
<template #appendIcon>
<SvgIcon name="users-three" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
<div class="edit-profile__cell edit-profile__cell--third">
<TextField
v-model="form.virtualPhoneNumber"
name="virtualPhoneNumber"
label="شماره تلفن مجازی"
inputmode="numeric"
:convert-digits="true"
:error="errors.virtualPhoneNumber"
@blur="validateAt('virtualPhoneNumber', form.virtualPhoneNumber)"
>
<template #appendIcon>
<SvgIcon name="phone" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
<div class="edit-profile__cell edit-profile__cell--third">
<TextField
v-model="form.seminaryCode"
name="seminaryCode"
label="کد حوزوی"
inputmode="numeric"
:convert-digits="true"
:error="errors.seminaryCode"
@blur="validateAt('seminaryCode', form.seminaryCode)"
>
<template #appendIcon>
<SvgIcon name="graduation-cap" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
<div class="edit-profile__cell edit-profile__cell--third">
<TextField
v-model="form.seminaryServiceCenterCode"
name="seminaryServiceCenterCode"
label="کد مرکز خدمات حوزه"
inputmode="numeric"
:convert-digits="true"
:error="errors.seminaryServiceCenterCode"
@blur="validateAt('seminaryServiceCenterCode', form.seminaryServiceCenterCode)"
>
<template #appendIcon>
<SvgIcon name="check-square" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
</div>
<LineTitleBlock title="مشخصات محل سکونت" title-en="Address Details" />
@@ -127,6 +187,21 @@
:disabled="!form.provinceId"
/>
</div>
<div class="edit-profile__cell edit-profile__cell--third">
<TextField
v-model="form.postalCode"
name="postalCode"
label="کد پستی"
inputmode="numeric"
:convert-digits="true"
:error="errors.postalCode"
@blur="validateAt('postalCode', form.postalCode)"
>
<template #appendIcon>
<SvgIcon name="map-pin-simple-area" :size="20" color="var(--color-thd-gray)" />
</template>
</TextField>
</div>
<div class="edit-profile__cell edit-profile__cell--full">
<TextareaField
v-model="form.address"
@@ -227,6 +302,8 @@ import { studentProfileSchema, studentResetPasswordSchema } from '@/features/stu
import {
authKeys,
useGetMeQuery,
useGetRegisterDataQuery,
useSaveRegisterDataMutation,
useUpdateProfileMutation,
useUploadMediaMutation,
} from '@/services/query/auth'
@@ -262,6 +339,11 @@ const form = ref({
provinceId: '',
cityId: '',
address: '',
postalCode: '',
virtualPhoneNumber: '',
seminaryCode: '',
seminaryServiceCenterCode: '',
childrenCount: '',
avatarMediaId: null,
})
@@ -326,6 +408,24 @@ watch(
{ immediate: true }
)
const { data: registerData } = useGetRegisterDataQuery()
watch(
registerData,
(data) => {
if (!data) return
form.value = {
...form.value,
postalCode: data.postalCode || '',
virtualPhoneNumber: data.virtualPhoneNumber || '',
seminaryCode: data.seminaryCode || '',
seminaryServiceCenterCode: data.seminaryServiceCenterCode || '',
childrenCount: data.childrenCount ?? '',
}
},
{ immediate: true }
)
const uploadMutation = useUploadMediaMutation()
const onAvatarCropped = async (file) => {
@@ -343,6 +443,7 @@ const onAvatarCropped = async (file) => {
const onAvatarError = (msg) => toast.error(msg)
const updateMutation = useUpdateProfileMutation()
const saveRegisterDataMutation = useSaveRegisterDataMutation()
const resetPasswordMutation = useUpdateProfileMutation()
const onSubmit = async () => {
@@ -359,7 +460,18 @@ const onSubmit = async () => {
...(payload.avatarMediaId ? { avatarMediaId: payload.avatarMediaId } : {}),
}
await updateMutation.mutateAsync(body)
await saveRegisterDataMutation.mutateAsync({
postalCode: payload.postalCode || '',
virtualPhoneNumber: payload.virtualPhoneNumber || '',
seminaryCode: payload.seminaryCode || '',
seminaryServiceCenterCode: payload.seminaryServiceCenterCode || '',
childrenCount:
payload.childrenCount == null || payload.childrenCount === ''
? ''
: Number(payload.childrenCount),
})
await queryClient.invalidateQueries({ queryKey: authKeys.me() })
await queryClient.invalidateQueries({ queryKey: authKeys.registerData() })
toast.success('پروفایل با موفقیت به‌روز شد')
router.push({ name: 'student-dashboard' })
}
@@ -15,6 +15,20 @@ export const studentProfileSchema = object().shape({
provinceId: string().nullable().notRequired(),
cityId: string().nullable().notRequired(),
address: string().nullable().notRequired(),
postalCode: string()
.nullable()
.notRequired()
.matches(/^\d{10}$/, { message: 'کد پستی باید ۱۰ رقم باشد', excludeEmptyString: true }),
virtualPhoneNumber: string()
.nullable()
.notRequired()
.matches(/^\d{10,15}$/, { message: 'شماره تلفن مجازی نامعتبر است', excludeEmptyString: true }),
seminaryCode: string().nullable().notRequired(),
seminaryServiceCenterCode: string().nullable().notRequired(),
childrenCount: string()
.nullable()
.notRequired()
.matches(/^\d+$/, { message: 'تعداد فرزند باید عدد باشد', excludeEmptyString: true }),
})
export const studentResetPasswordSchema = object().shape({
+1 -1
View File
@@ -7,7 +7,7 @@ export default [
layout: 'student',
role: 'student',
title: 'سلام بر شما',
subtitle: 'به سامانه موسسه بانو خوش آمدید.',
subtitle: 'به سامانه مدرسه بانو خوش آمدید.',
},
},
{
+1 -1
View File
@@ -1,7 +1,7 @@
<template>
<aside class="admin-sidebar">
<div class="admin-sidebar__logo">
<img :src="logo" alt="banu" />
<img :src="logo" alt="مدرسه بانو" />
</div>
<nav class="admin-sidebar__nav">
<ul>
+1 -1
View File
@@ -1,7 +1,7 @@
<template>
<aside class="counselor-sidebar">
<div class="counselor-sidebar__logo">
<img :src="logo" alt="banu" />
<img :src="logo" alt="مدرسه بانو" />
</div>
<nav class="counselor-sidebar__nav">
<ul>
+1 -1
View File
@@ -1,7 +1,7 @@
<template>
<aside class="student-sidebar" :style="{ backgroundImage: `url(${bgPattern})` }">
<div class="student-sidebar__logo">
<img :src="logo" alt="banu" />
<img :src="logo" alt="مدرسه بانو" />
</div>
<nav class="student-sidebar__nav">
<ul>
+1 -1
View File
@@ -2,7 +2,7 @@ import { ROLE_HOME_ROUTES } from '@/enums'
import { useAuthStore } from '@/store/auth'
import { tokenService } from '@/services/api/token-service'
const APP_TITLE = 'بنو'
const APP_TITLE = 'مدرسه بانو'
const isPublic = (to) => to.meta?.public === true
+1 -1
View File
@@ -14,7 +14,7 @@ export const endpoints = {
verifyForgotPasswordCode: '/auth/password/verify-otp',
resetPassword: '/auth/password/reset',
resendVerificationCodeForRegister: '/resend-verification-code',
resendVerificationCodeForRegister: '/auth/login/otp/request',
verifyCode: '/auth/login/otp/verify',
completeProfile: '/complete-profile',
getRegistrationQuestionVideo: '/verification-registration-media',
@@ -32,7 +32,6 @@ const makeStudent = (i) => {
universityLevel: 'not_applicable',
universityName: 'حوزه علمیه قم',
fieldOfStudy: 'فقه و اصول',
workExperienceSummary: 'پنج سال تدریس در مدرسه دینی.',
activitySummary: 'برگزاری جلسات قرآن و حدیث به صورت هفتگی.',
propagationExperienceYears: 6,
propagationMethodDescription: 'محوریت بیان داستان‌های قرآنی و قرابت‌های اخلاقی.',
-1
View File
@@ -49,7 +49,6 @@ register('GET', endpoints.getUserRegisterData, ({ params }) => {
{ key: 'universityLevel', value: 'not_applicable' },
{ key: 'universityName', value: 'حوزه علمیه قم' },
{ key: 'fieldOfStudy', value: 'فقه و اصول' },
{ key: 'workExperienceSummary', value: 'پنج سال تدریس در مدرسه دینی.' },
{ key: 'activitySummary', value: 'برگزاری جلسات قرآن و حدیث به صورت هفتگی.' },
{ key: 'specializedTopics', value: 'تربیت دینی نوجوانان' },
{ key: 'propagationExperienceYears', value: 6 },
-4
View File
@@ -27,10 +27,6 @@ register('POST', endpoints.register, ({ data }) => ({
data: { user: { ...currentMe, ...data }, token: fakeToken },
}))
register('POST', endpoints.resendVerificationCodeForRegister, () => ({
data: { message: 'کد جدید ارسال شد' },
}))
register('POST', endpoints.forgotPassword, () => ({
success: true,
message: 'If the phone is registered, a code has been sent.',