дизабл кнопки при некорректных условиях
This commit is contained in:
parent
f5a4bdc36f
commit
f0a977031d
@ -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",
|
||||
|
Loading…
Reference in New Issue
Block a user