feat: add social media fields to Clinic entity and update API documentation
This commit is contained in:
@@ -73,6 +73,8 @@ interface OptUuid { id: number; uuid: string; name: string; }
|
||||
|
||||
// ── Edit form schema ───────────────────────────────────────────────────────
|
||||
|
||||
const urlOrEmpty = z.string().refine(v => v === '' || /^https?:\/\/.+/.test(v), { message: 'آدرس URL معتبر نیست' });
|
||||
|
||||
const editSchema = z.object({
|
||||
name: z.string().min(1, 'نام الزامی است'),
|
||||
telephone: z.string().optional(),
|
||||
@@ -81,6 +83,11 @@ const editSchema = z.object({
|
||||
specialties: z.array(z.number()),
|
||||
insurance: z.array(z.number()),
|
||||
doctor_services: z.array(z.number()),
|
||||
sm_instagram: urlOrEmpty,
|
||||
sm_telegram: urlOrEmpty,
|
||||
sm_aparat: urlOrEmpty,
|
||||
sm_youtube: urlOrEmpty,
|
||||
sm_linkedin: urlOrEmpty,
|
||||
});
|
||||
type EditForm = z.infer<typeof editSchema>;
|
||||
|
||||
@@ -282,6 +289,11 @@ function EditModal({ clinic, onClose, onSaved }: {
|
||||
specialties: (clinic.specialties ?? []).map(s => Number(s.id)),
|
||||
insurance: (clinic.list_bime ?? []).map(s => Number(s.id)),
|
||||
doctor_services: (clinic.services ?? []).map(s => Number(s.id)),
|
||||
sm_instagram: clinic.social_media?.instagram ?? '',
|
||||
sm_telegram: clinic.social_media?.telegram ?? '',
|
||||
sm_aparat: clinic.social_media?.aparat ?? '',
|
||||
sm_youtube: clinic.social_media?.youtube ?? '',
|
||||
sm_linkedin: clinic.social_media?.linkedin ?? '',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -324,12 +336,19 @@ function EditModal({ clinic, onClose, onSaved }: {
|
||||
specialties: values.specialties,
|
||||
insurance: values.insurance,
|
||||
doctor_services: values.doctor_services,
|
||||
social_media: {
|
||||
instagram: values.sm_instagram || null,
|
||||
telegram: values.sm_telegram || null,
|
||||
aparat: values.sm_aparat || null,
|
||||
youtube: values.sm_youtube || null,
|
||||
linkedin: values.sm_linkedin || null,
|
||||
},
|
||||
}),
|
||||
onSuccess: () => { toast.success('اطلاعات کلینیک ذخیره شد'); onSaved(); onClose(); },
|
||||
onError: (e: Error) => toast.error(e.message),
|
||||
});
|
||||
|
||||
const [activeTab, setActiveTab] = useState<'basic' | 'tags'>('basic');
|
||||
const [activeTab, setActiveTab] = useState<'basic' | 'tags' | 'social'>('basic');
|
||||
|
||||
return (
|
||||
<div className="overlay" onClick={onClose}>
|
||||
@@ -343,7 +362,7 @@ function EditModal({ clinic, onClose, onSaved }: {
|
||||
|
||||
{/* Tab switcher */}
|
||||
<div style={{ borderBottom: '1px solid var(--border)', padding: '0 16px', display: 'flex', gap: 4 }}>
|
||||
{([['basic', 'اطلاعات پایه'], ['tags', 'تخصص و بیمه']] as const).map(([id, label]) => (
|
||||
{([['basic', 'اطلاعات پایه'], ['tags', 'تخصص و بیمه'], ['social', 'شبکههای اجتماعی']] as const).map(([id, label]) => (
|
||||
<button key={id} type="button" onClick={() => setActiveTab(id)}
|
||||
style={{
|
||||
padding: '10px 14px', fontSize: 13, fontWeight: 600, border: 'none', background: 'none',
|
||||
@@ -381,6 +400,25 @@ function EditModal({ clinic, onClose, onSaved }: {
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* ── Social tab ── */}
|
||||
{activeTab === 'social' && (
|
||||
<>
|
||||
{([
|
||||
['sm_instagram', 'اینستاگرام', 'https://instagram.com/...'],
|
||||
['sm_telegram', 'تلگرام', 'https://t.me/...'],
|
||||
['sm_aparat', 'آپارات', 'https://aparat.com/...'],
|
||||
['sm_youtube', 'یوتیوب', 'https://youtube.com/...'],
|
||||
['sm_linkedin', 'لینکدین', 'https://linkedin.com/...'],
|
||||
] as const).map(([field, label, placeholder]) => (
|
||||
<div key={field}>
|
||||
<label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>{label}</label>
|
||||
<input className="input" dir="ltr" placeholder={placeholder} {...register(field)} />
|
||||
{errors[field] && <div className="err-text">{errors[field]?.message}</div>}
|
||||
</div>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* ── Tags tab ── */}
|
||||
{activeTab === 'tags' && (
|
||||
<>
|
||||
|
||||
@@ -60,6 +60,13 @@ export interface ClinicDetail {
|
||||
clinic_logo: string | null;
|
||||
caption: string | null;
|
||||
images_clinic: { url: string; fid?: number }[];
|
||||
social_media: {
|
||||
instagram: string | null;
|
||||
telegram: string | null;
|
||||
aparat: string | null;
|
||||
youtube: string | null;
|
||||
linkedin: string | null;
|
||||
} | null;
|
||||
specialties: { id: string; uuid: string; name: string }[];
|
||||
services: { id: string; uuid: string; name: string }[];
|
||||
list_bime: { id: string; uuid: string; name: string }[];
|
||||
|
||||
Reference in New Issue
Block a user