79 lines
3.3 KiB
TypeScript
79 lines
3.3 KiB
TypeScript
import { useForm } from 'react-hook-form';
|
|
import { zodResolver } from '@hookform/resolvers/zod';
|
|
import { z } from 'zod';
|
|
import { useMutation } from '@tanstack/react-query';
|
|
import { XMarkIcon } from '@heroicons/react/24/outline';
|
|
import { toast } from 'sonner';
|
|
import { api } from '../../lib/api';
|
|
import type { ApiResponse } from '../../lib/api';
|
|
import MobileInput from './MobileInput';
|
|
import Portal from './Portal';
|
|
import { iranMobileSchema } from '../../lib/utils';
|
|
|
|
const inviteSchema = z.object({
|
|
mobile: iranMobileSchema,
|
|
name: z.string().optional(),
|
|
specialty: z.string().optional(),
|
|
});
|
|
type InviteForm = z.infer<typeof inviteSchema>;
|
|
|
|
interface Props {
|
|
clinicUuid: string;
|
|
onClose: () => void;
|
|
onInvited?: () => void;
|
|
}
|
|
|
|
export default function InviteDoctorModal({ clinicUuid, onClose, onInvited }: Props) {
|
|
const { register, handleSubmit, formState: { errors } } = useForm<InviteForm>({
|
|
resolver: zodResolver(inviteSchema),
|
|
});
|
|
|
|
const inviteMut = useMutation({
|
|
mutationFn: (d: InviteForm) =>
|
|
api.post<ApiResponse<unknown>>(`/api/v1/admin/clinic/${clinicUuid}/invite-doctor`, d),
|
|
onSuccess: () => {
|
|
toast.success('دعوتنامه ارسال شد');
|
|
onInvited?.();
|
|
onClose();
|
|
},
|
|
onError: (e: Error) => toast.error(e.message),
|
|
});
|
|
|
|
return (
|
|
<Portal>
|
|
<div className="overlay" onClick={onClose}>
|
|
<div className="modal" style={{ maxWidth: 420 }} onClick={e => e.stopPropagation()}>
|
|
<div className="modal-head">
|
|
<b>دعوت پزشک به کلینیک</b>
|
|
<button className="mini-btn" onClick={onClose}><XMarkIcon style={{ width: 16, height: 16 }} /></button>
|
|
</div>
|
|
<form onSubmit={handleSubmit(d => inviteMut.mutate(d))}>
|
|
<div className="modal-body" style={{ display: 'flex', flexDirection: 'column', gap: 14 }}>
|
|
<div>
|
|
<label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>شماره موبایل پزشک *</label>
|
|
<MobileInput className="input" hasError={!!errors.mobile} {...register('mobile')} />
|
|
{errors.mobile && <div className="err-text">{errors.mobile.message}</div>}
|
|
</div>
|
|
<div>
|
|
<label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>نام پزشک (اختیاری)</label>
|
|
<input className="input" placeholder="دکتر نام و نام خانوادگی" {...register('name')} />
|
|
</div>
|
|
<div>
|
|
<label style={{ fontSize: 13, fontWeight: 600, display: 'block', marginBottom: 6 }}>تخصص (اختیاری)</label>
|
|
<input className="input" placeholder="مثال: قلب و عروق" {...register('specialty')} />
|
|
</div>
|
|
<p className="muted" style={{ fontSize: 12 }}>پیامک دعوتنامه با لینک ۷۲ ساعته ارسال میشود</p>
|
|
</div>
|
|
<div className="modal-foot">
|
|
<button type="button" className="btn ghost sm" onClick={onClose}>انصراف</button>
|
|
<button type="submit" className="btn primary sm" disabled={inviteMut.isPending}>
|
|
{inviteMut.isPending ? 'در حال ارسال...' : 'ارسال دعوتنامه'}
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</Portal>
|
|
);
|
|
}
|