feat: add social media links field to Doctor entity and update API documentation

This commit is contained in:
hamed
2026-06-21 12:35:22 +03:30
parent 943784b64a
commit 3f1b2de971
6 changed files with 236 additions and 1 deletions
+45
View File
@@ -47,6 +47,10 @@ interface DoctorDetail {
img: { url: string; fid: number }[];
expertise: { id: string; uuid: string; name: string }[];
satisfaction: string; point: string;
social_media: {
instagram: string | null; telegram: string | null; aparat: string | null;
youtube: string | null; linkedin: string | null;
} | null;
address: AddressData[];
state: { id: string; name: string }[];
city: { id: string; name: string }[];
@@ -2116,6 +2120,8 @@ function EditSpecialtyPicker({ selected, onChange, specialties }: {
// ── Edit schema ────────────────────────────────────────────────────────────
const urlOrEmpty = z.string().url('آدرس نامعتبر است').optional().or(z.literal(''));
const editSchema = z.object({
name: z.string().min(2, 'نام حداقل ۲ کاراکتر'),
gender: z.enum(['man', 'woman']).optional().or(z.literal('')),
@@ -2125,6 +2131,11 @@ const editSchema = z.object({
info: z.string().max(2000).optional().or(z.literal('')),
specialties: z.array(z.number()).optional(),
services: z.array(z.number()).optional(),
social_instagram: urlOrEmpty,
social_telegram: urlOrEmpty,
social_aparat: urlOrEmpty,
social_youtube: urlOrEmpty,
social_linkedin: urlOrEmpty,
});
type EditForm = z.infer<typeof editSchema>;
@@ -2310,6 +2321,11 @@ export default function DoctorDetailPage({ isOwnProfile = false }: { isOwnProfil
info: doctor.detail ?? '',
specialties: doctor.specialties.map(s => Number(s.id)),
services: doctor.expertise.map(s => Number(s.id)),
social_instagram: doctor.social_media?.instagram ?? '',
social_telegram: doctor.social_media?.telegram ?? '',
social_aparat: doctor.social_media?.aparat ?? '',
social_youtube: doctor.social_media?.youtube ?? '',
social_linkedin: doctor.social_media?.linkedin ?? '',
});
setEditGender((doctor.gender as any) ?? '');
}
@@ -2337,6 +2353,13 @@ export default function DoctorDetailPage({ isOwnProfile = false }: { isOwnProfil
info: body.info || undefined,
specialties: body.specialties ?? [],
doctor_services: body.services ?? [],
social_media: {
instagram: body.social_instagram || null,
telegram: body.social_telegram || null,
aparat: body.social_aparat || null,
youtube: body.social_youtube || null,
linkedin: body.social_linkedin || null,
},
}),
onSuccess: () => {
toast.success('اطلاعات پزشک بروزرسانی شد');
@@ -2785,6 +2808,28 @@ export default function DoctorDetailPage({ isOwnProfile = false }: { isOwnProfil
</div>
</div>
{/* ── Section: شبکه‌های اجتماعی ── */}
<div className="cp-card" style={{ padding: 'var(--card-pad)' }}>
<EditSectionHeader icon={<DocumentTextIcon style={{ width: 16, height: 16 }} />} title="شبکه‌های اجتماعی" />
<div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 14 }}>
<EditField label="اینستاگرام">
<input type="text" dir="ltr" className="cp-input" placeholder="https://instagram.com/..." {...register('social_instagram')} />
</EditField>
<EditField label="تلگرام">
<input type="text" dir="ltr" className="cp-input" placeholder="https://t.me/..." {...register('social_telegram')} />
</EditField>
<EditField label="آپارات">
<input type="text" dir="ltr" className="cp-input" placeholder="https://aparat.com/..." {...register('social_aparat')} />
</EditField>
<EditField label="یوتیوب">
<input type="text" dir="ltr" className="cp-input" placeholder="https://youtube.com/..." {...register('social_youtube')} />
</EditField>
<EditField label="لینکدین">
<input type="text" dir="ltr" className="cp-input" placeholder="https://linkedin.com/in/..." {...register('social_linkedin')} />
</EditField>
</div>
</div>
{/* ── Section: تخصص‌ها ── */}
<div className="cp-card" style={{ padding: 'var(--card-pad)' }}>
<EditSectionHeader