дизабл кнопки при некорректных условиях
All checks were successful
Deploy / CreateImage (push) Successful in 5m0s
Deploy / DeployService (push) Successful in 27s

This commit is contained in:
Nastya 2025-06-03 21:50:07 +03:00
parent f5a4bdc36f
commit f0a977031d
2 changed files with 14 additions and 14 deletions

@ -18,9 +18,10 @@ import ArrowDownIcon from "@/assets/icons/ArrowDownIcon";
interface AgeInputWithSelectProps {
value: string;
onChange: (value: string) => void;
onErrorChange?: (isError: boolean) => void;
}
const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => {
const AgeInputWithSelect = ({ value, onChange, onErrorChange }: AgeInputWithSelectProps) => {
const theme = useTheme();
const [open, setOpen] = useState(false);
const anchorRef = useRef<HTMLDivElement>(null);
@ -30,36 +31,36 @@ const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => {
const validate = (val: string) => {
if (!val) return false;
// Число (только положительное)
if (/^\d+$/.test(val)) {
if (/^-?\d+$/.test(val)) {
const num = Number(val);
if (num < 0 || num > 150) return 'range';
return false;
}
// Диапазон (только положительные числа)
const rangeMatch = val.match(/^(\d+)-(\d+)$/);
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 filtered = e.target.value.replace(/[^\d-]/g, '');
onChange(filtered);
setErrorType(false);
const err = validate(filtered);
setErrorType(err);
if (onErrorChange) onErrorChange(!!err);
};
const handleInputBlur = (e: React.FocusEvent<HTMLInputElement>) => {
const trimmed = e.target.value.replace(/\s+/g, '');
onChange(trimmed);
setErrorType(validate(trimmed));
const err = validate(trimmed);
setErrorType(err);
if (onErrorChange) onErrorChange(!!err);
};
const handleSelectItemClick = (selectedValue: string) => {

@ -19,9 +19,8 @@ export default function GenderAndAgeSelector({ handleAdd }: GenderAndAgeSelector
const [selectOpen, setSelectOpen] = useState<boolean>(false);
const quiz = useCurrentQuiz();
const { enqueueSnackbar } = useSnackbar();
const isMobile = useMediaQuery(theme.breakpoints.down(800));
const isFormValid = gender && age;
const isMobile = useMediaQuery(theme.breakpoints.down(845));
const [ageError, setAgeError] = useState(false);
const addItem = async () => {
if (!quiz?.backendId) {
@ -172,14 +171,14 @@ export default function GenderAndAgeSelector({ handleAdd }: GenderAndAgeSelector
}}>Возраст</FormLabel>
<InfoPopover />
</Box>
<AgeInputWithSelect value={age} onChange={setAge} />
<AgeInputWithSelect value={age} onChange={setAge} onErrorChange={setAgeError} />
</FormControl>
</Box>
<Button
onClick={addItem}
variant="contained"
disabled={!isFormValid}
disabled={!gender || !age || ageError}
sx={{
bgcolor: theme.palette.brightPurple.main,
borderRadius: "8px",