feat(admin): force Latin digits in numeric fields globally

- Add a numeric prop to the base Input component that sets inputMode,
  dir=ltr, lang=en and normalizes Persian/Arabic digits to Latin via the
  shared toEnglishDigits on every change.
- Dedupe digit conversion: PriceInput now uses toEnglishDigits instead of
  its local map; AppointmentsPage mobile handler uses sanitizeMobileInput.
- Fix raw national-code / mobile inputs in NewAppointmentModal and
  NewAppointmentDrawer that stripped Persian digits without converting.
- Cover the numeric Input behaviour with unit tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
hamed
2026-07-17 10:58:55 +03:30
co-authored by Claude Fable 5
parent 2638b70162
commit 15f1c8d1eb
5 changed files with 54 additions and 27 deletions
@@ -9,7 +9,7 @@ import PersianDateInput from './ui/PersianDateInput';
import PriceInput from './ui/PriceInput';
import SearchableSelect from './ui/SearchableSelect';
import { WalletChargeLink } from './AppointmentActions';
import { tehranWallClockToUnix, tomanToRial } from '../lib/utils';
import { tehranWallClockToUnix, tomanToRial, toEnglishDigits, sanitizeMobileInput } from '../lib/utils';
interface Option { uuid: string; name?: string; full_name?: string }
interface PatientRow { uuid: string; user_name?: string; user_mobile?: string; user_national_code?: string }
@@ -191,12 +191,12 @@ export default function NewAppointmentDrawer({ doctorUuid, defaultDate, queryKey
</div>
<label style={label}>شماره تماس</label>
<div className="field" style={{ margin: '6px 0 12px' }}>
<input value={mobile} onChange={e => setMobile(e.target.value)} placeholder="شماره تماس مراجعه کننده را وارد نمایید" dir="ltr" />
<input value={mobile} onChange={e => setMobile(sanitizeMobileInput(e.target.value))} placeholder="شماره تماس مراجعه کننده را وارد نمایید" dir="ltr" inputMode="numeric" lang="en" maxLength={11} />
</div>
<label style={label}>کد ملی</label>
<div className="field" style={{ margin: '6px 0 12px' }}>
<input value={nationalCode} onChange={e => setNationalCode(e.target.value.replace(/\D/g, '').slice(0, 10))}
placeholder="کد ملی مراجعه کننده را وارد نمایید" dir="ltr" inputMode="numeric" maxLength={10} />
<input value={nationalCode} onChange={e => setNationalCode(toEnglishDigits(e.target.value).replace(/\D/g, '').slice(0, 10))}
placeholder="کد ملی مراجعه کننده را وارد نمایید" dir="ltr" inputMode="numeric" lang="en" maxLength={10} />
</div>
</>
)}