fix: allow submit when picking an existing patient
Backend requires a valid national code for every appointment, but a picked patient record may have none stored. Show a selected-patient card with an editable national-code field (prefilled from the record) so submit can enable. Add happy-path and boundary tests for the picked-patient flow. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -86,4 +86,45 @@ describe('AppointmentCreatePage — افزودن نوبت', () => {
|
||||
fireEvent.change(screen.getByPlaceholderText('شماره تماس مراجعه کننده'), { target: { value: '09121234567' } });
|
||||
expect(btn).toBeDisabled();
|
||||
});
|
||||
|
||||
it('picking an existing patient WITH a national code enables submit and posts it (happy path)', async () => {
|
||||
get.mockImplementation((url: string) => {
|
||||
if (url.startsWith('/api/v1/patients?'))
|
||||
return Promise.resolve({ success: true, data: [{ uuid: 'rec1', user_name: 'حامد حسینی', user_mobile: '09210671745', user_national_code: '0012345675' }] });
|
||||
return Promise.resolve({ success: true, data: [] });
|
||||
});
|
||||
|
||||
renderWithProviders(<AppointmentCreatePage />, { route: '/admin/appointments/new' });
|
||||
|
||||
fireEvent.change(screen.getByPlaceholderText('جستجوی نام، شماره تماس، شماره پرونده...'), { target: { value: 'حامد' } });
|
||||
fireEvent.click(await screen.findByText(/حامد حسینی/));
|
||||
|
||||
const btn = screen.getByText('ثبت اطلاعات') as HTMLButtonElement;
|
||||
await waitFor(() => expect(btn).not.toBeDisabled());
|
||||
|
||||
fireEvent.click(btn);
|
||||
await waitFor(() => expect(post).toHaveBeenCalled());
|
||||
const [, body] = post.mock.calls[0];
|
||||
expect(body).toMatchObject({ patient_name: 'حامد حسینی', patient_mobile: '09210671745', patient_national_code: '0012345675' });
|
||||
});
|
||||
|
||||
it('picking an existing patient WITHOUT a national code keeps submit disabled until one is entered (boundary)', async () => {
|
||||
get.mockImplementation((url: string) => {
|
||||
if (url.startsWith('/api/v1/patients?'))
|
||||
return Promise.resolve({ success: true, data: [{ uuid: 'rec2', user_name: 'حامد حسینی', user_mobile: '09210671745', user_national_code: null }] });
|
||||
return Promise.resolve({ success: true, data: [] });
|
||||
});
|
||||
|
||||
renderWithProviders(<AppointmentCreatePage />, { route: '/admin/appointments/new' });
|
||||
|
||||
fireEvent.change(screen.getByPlaceholderText('جستجوی نام، شماره تماس، شماره پرونده...'), { target: { value: 'حامد' } });
|
||||
fireEvent.click(await screen.findByText(/حامد حسینی/));
|
||||
|
||||
const btn = screen.getByText('ثبت اطلاعات') as HTMLButtonElement;
|
||||
expect(btn).toBeDisabled();
|
||||
|
||||
// کد ملیِ خالیِ رکورد را دستی وارد کن → فعال میشود
|
||||
fireEvent.change(screen.getByPlaceholderText('کد ملی مراجعه کننده'), { target: { value: '0012345675' } });
|
||||
await waitFor(() => expect(btn).not.toBeDisabled());
|
||||
});
|
||||
});
|
||||
|
||||
@@ -194,15 +194,35 @@ export default function AppointmentCreatePage() {
|
||||
{!picked && patients.length > 0 && (
|
||||
<div style={{ border: '1px solid var(--border)', borderRadius: 'var(--r-sm)', marginBottom: 10, overflow: 'hidden', maxWidth: 400 }}>
|
||||
{patients.map(p => (
|
||||
<button key={p.uuid} onClick={() => setPicked(p)} style={{
|
||||
display: 'block', width: '100%', padding: '8px 10px', fontSize: 13, textAlign: 'right',
|
||||
background: 'transparent', border: 'none', cursor: 'pointer', fontFamily: 'inherit',
|
||||
}}>
|
||||
<button key={p.uuid}
|
||||
onClick={() => { setPicked(p); setNationalCode((p.user_national_code ?? '').replace(/\D/g, '').slice(0, 10)); }}
|
||||
style={{
|
||||
display: 'block', width: '100%', padding: '8px 10px', fontSize: 13, textAlign: 'right',
|
||||
background: 'transparent', border: 'none', cursor: 'pointer', fontFamily: 'inherit',
|
||||
}}>
|
||||
{p.user_name} <span style={{ color: 'var(--text-3)', direction: 'ltr' }}>{p.user_mobile}</span>
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* کارت بیمارِ انتخابشده + کد ملی (برای ثبت نوبت الزامی است) */}
|
||||
{picked && (
|
||||
<div style={{ maxWidth: 400, border: '1px solid var(--border-2)', borderRadius: 'var(--r-sm)', padding: 12, marginBottom: 8 }}>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 10 }}>
|
||||
<span style={{ fontSize: 13.5, fontWeight: 600 }}>
|
||||
{picked.user_name} <span style={{ color: 'var(--text-3)', direction: 'ltr', fontWeight: 400 }}>{picked.user_mobile}</span>
|
||||
</span>
|
||||
<button type="button" className="btn sm ghost"
|
||||
onClick={() => { setPicked(null); setNationalCode(''); }}>تغییر</button>
|
||||
</div>
|
||||
<label style={label}>کد ملی</label>
|
||||
<div className="field" style={{ marginTop: 6, height: 44 }}>
|
||||
<input value={nationalCode} onChange={e => setNationalCode(e.target.value.replace(/\D/g, '').slice(0, 10))}
|
||||
placeholder="کد ملی مراجعه کننده" dir="ltr" inputMode="numeric" maxLength={10} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user