корректные проверки селекта возраста

This commit is contained in:
Nastya 2025-06-03 21:07:37 +03:00
parent 2540dd8079
commit 8255fe6908

@ -10,7 +10,8 @@ import {
Grow, Grow,
ClickAwayListener, ClickAwayListener,
MenuList, MenuList,
useTheme useTheme,
FormHelperText
} from '@mui/material'; } from '@mui/material';
import ArrowDownIcon from "@/assets/icons/ArrowDownIcon"; import ArrowDownIcon from "@/assets/icons/ArrowDownIcon";
@ -23,13 +24,47 @@ const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => {
const theme = useTheme(); const theme = useTheme();
const [open, setOpen] = useState(false); const [open, setOpen] = useState(false);
const anchorRef = useRef<HTMLDivElement>(null); const anchorRef = useRef<HTMLDivElement>(null);
const [errorType, setErrorType] = useState<'format' | 'range' | false>(false);
// Валидация: только число или диапазон число-число, и диапазон 0-150
const validate = (val: string) => {
if (!val) return false;
// Число (только положительное)
if (/^\d+$/.test(val)) {
const num = Number(val);
if (num < 0 || num > 150) return 'range';
return false;
}
// Диапазон (только положительные числа)
const rangeMatch = val.match(/^(\d+)-(\d+)$/);
if (rangeMatch) {
const left = Number(rangeMatch[1]);
const right = Number(rangeMatch[2]);
if (left < 0 || left > 150 || right < 0 || right > 150 || left > right) return 'range';
return false;
}
// Если есть минус не в начале диапазона — это ошибка диапазона
if (/^-?\d+-\d+$/.test(val) || /^\d+-\d+-\d+$/.test(val)) {
return 'range';
}
return 'format';
};
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
onChange(e.target.value); const filtered = e.target.value.replace(/[^\d-]/g, '');
onChange(filtered);
setErrorType(false);
};
const handleInputBlur = (e: React.FocusEvent<HTMLInputElement>) => {
const trimmed = e.target.value.replace(/\s+/g, '');
onChange(trimmed);
setErrorType(validate(trimmed));
}; };
const handleSelectItemClick = (selectedValue: string) => { const handleSelectItemClick = (selectedValue: string) => {
onChange(selectedValue); onChange(selectedValue);
setErrorType(false);
setOpen(false); setOpen(false);
}; };
@ -66,8 +101,10 @@ const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => {
<InputBase <InputBase
value={value} value={value}
onChange={handleInputChange} onChange={handleInputChange}
onBlur={handleInputBlur}
fullWidth fullWidth
placeholder="Введите возраст" placeholder="Введите возраст"
inputProps={{ inputMode: 'numeric', pattern: '[0-9-]*' }}
sx={{ sx={{
height: "100%", height: "100%",
padding: "10px 20px", padding: "10px 20px",
@ -77,6 +114,16 @@ const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => {
} }
}} }}
/> />
{errorType === 'format' && (
<FormHelperText error sx={{ position: 'absolute', left: 0, top: '100%', mt: '2px', ml: '10px' }}>
можно только число или диапазон
</FormHelperText>
)}
{errorType === 'range' && (
<FormHelperText error sx={{ position: 'absolute', left: 0, top: '100%', mt: '2px', ml: '10px' }}>
таких возрастов нет
</FormHelperText>
)}
<IconButton <IconButton
onClick={handleToggle} onClick={handleToggle}
sx={{ sx={{