Files
clinicpro/assets/admin/components/ui/PriceInput.tsx
T
hamedandClaude Fable 5 15f1c8d1eb 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>
2026-07-17 10:58:55 +03:30

54 lines
1.3 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { toEnglishDigits } from '../../lib/utils';
interface PriceInputProps {
value: number | '';
onChange: (value: number) => void;
placeholder?: string;
className?: string;
style?: React.CSSProperties;
disabled?: boolean;
min?: number;
}
function formatDisplay(num: number): string {
if (num === 0) return '';
return new Intl.NumberFormat('fa-IR').format(num);
}
export default function PriceInput({
value,
onChange,
placeholder = '0',
className,
style,
disabled,
min = 0,
}: PriceInputProps) {
const [display, setDisplay] = useState(() => (value !== '' && value > 0 ? formatDisplay(value) : ''));
useEffect(() => {
setDisplay(value !== '' && Number(value) > 0 ? formatDisplay(Number(value)) : '');
}, [value]);
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const raw = toEnglishDigits(e.target.value).replace(/[^0-9]/g, '');
const num = raw === '' ? 0 : Math.max(min, parseInt(raw, 10));
onChange(num);
setDisplay(num > 0 ? formatDisplay(num) : '');
};
return (
<input
type="text"
inputMode="numeric"
value={display}
onChange={handleChange}
placeholder={placeholder}
className={className}
style={{ textAlign: 'left', direction: 'ltr', ...style }}
disabled={disabled}
/>
);
}