feat(doctors): add activity start date field with Persian calendar in admin panel

This commit is contained in:
hamed
2026-07-02 11:35:59 +03:30
parent 4565f521c4
commit 0a1e03d0ce
9 changed files with 257 additions and 1 deletions
+21 -1
View File
@@ -22,12 +22,13 @@ import 'leaflet/dist/leaflet.css';
import { api, ApiError } from '../lib/api';
import { useAuthStore } from '../stores/authStore';
import type { ApiResponse } from '../lib/api';
import { formatNumber, iranMobileOptionalSchema } from '../lib/utils';
import { formatNumber, iranMobileOptionalSchema, toDate, toGregorianDate } from '../lib/utils';
import MobileInput from '../components/ui/MobileInput';
import Modal from '../components/ui/Modal';
import ConfirmDialog from '../components/ui/ConfirmDialog';
import NotificationMobileCard from '../components/ui/NotificationMobileCard';
import GlobalSearchableSelect from '../components/ui/SearchableSelect';
import PersianDatePicker from '../components/ui/PersianDatePicker';
// Fix leaflet default marker icons
delete (L.Icon.Default.prototype as any)._getIconUrl;
@@ -2338,6 +2339,7 @@ export default function DoctorDetailPage({ isOwnProfile = false }: { isOwnProfil
const [editingAddr, setEditingAddr] = useState<AddressData | null>(null);
const [deletingAddrId, setDeletingAddrId] = useState<string | null>(null);
const [editGender, setEditGender] = useState<'man' | 'woman' | ''>('');
const [editActivityDate, setEditActivityDate] = useState('');
// ── Queries ──
@@ -2396,6 +2398,9 @@ export default function DoctorDetailPage({ isOwnProfile = false }: { isOwnProfil
social_linkedin: doctor.social_media?.linkedin ?? '',
});
setEditGender((doctor.gender as any) ?? '');
setEditActivityDate(
doctor.activity_time ? toGregorianDate(toDate(Number(doctor.activity_time))!) : ''
);
}
}, [doctor, reset]);
@@ -2419,6 +2424,9 @@ export default function DoctorDetailPage({ isOwnProfile = false }: { isOwnProfil
medical_system_code: body.medical_system_code || undefined,
mobile_number: body.mobile_number || undefined,
info: body.info || undefined,
...(editActivityDate
? { activity_time: Math.floor(new Date(`${editActivityDate}T12:00:00`).getTime() / 1000) }
: {}),
specialties: body.specialties ?? [],
doctor_services: body.services ?? [],
social_media: {
@@ -2877,6 +2885,18 @@ export default function DoctorDetailPage({ isOwnProfile = false }: { isOwnProfil
</EditField>
</div>
<div style={{ marginTop: 14 }}>
<EditField label="تاریخ شروع فعالیت" hint="مبنای محاسبهٔ سال تجربه">
<PersianDatePicker
value={editActivityDate}
onChange={setEditActivityDate}
placeholder="انتخاب تاریخ"
enableYearPicker
minWidth={200}
/>
</EditField>
</div>
<div style={{ marginTop: 14 }}>
<EditField label="بیوگرافی">
<textarea rows={3} className="cp-textarea" placeholder="معرفی کوتاهی از پزشک..." {...register('info')} style={{ resize: 'none' }} />
+17
View File
@@ -14,6 +14,7 @@ import { api } from '../lib/api';
import type { ApiResponse } from '../lib/api';
import SearchableSelect from '../components/ui/SearchableSelect';
import MobileInput from '../components/ui/MobileInput';
import PersianDatePicker from '../components/ui/PersianDatePicker';
import { iranMobileSchema } from '../lib/utils';
import { useAuthStore } from '../stores/authStore';
@@ -261,6 +262,7 @@ export default function DoctorFormPage() {
primaryRole === 'representation' ? '/api/v1/representation/doctor' : '/api/v1/admin/doctors';
const [selectedSpecialties, setSelectedSpecialties] = useState<number[]>([]);
const [gender, setGender] = useState<'man' | 'woman' | ''>('');
const [activityDate, setActivityDate] = useState('');
const specialtiesQ = useQuery({
queryKey: ['specialties-list'],
@@ -286,6 +288,9 @@ export default function DoctorFormPage() {
degree: values.degree || undefined,
medical_system_code: values.medical_system_code || undefined,
info: values.info || undefined,
...(activityDate
? { activity_time: Math.floor(new Date(`${activityDate}T12:00:00`).getTime() / 1000) }
: {}),
specialties: selectedSpecialties,
}),
onSuccess: (res) => {
@@ -369,6 +374,18 @@ export default function DoctorFormPage() {
</Field>
</div>
<div style={{ marginTop: 14 }}>
<Field label="تاریخ شروع فعالیت">
<PersianDatePicker
value={activityDate}
onChange={setActivityDate}
placeholder="انتخاب تاریخ"
enableYearPicker
minWidth={200}
/>
</Field>
</div>
<div style={{ marginTop: 14 }}>
<Field label="بیوگرافی">
<textarea rows={3} className="cp-textarea" placeholder="معرفی کوتاهی از پزشک..." {...register('info')} style={{ resize: 'none' }} />