дизабл кнопки при некорректных условиях
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 { interface AgeInputWithSelectProps {
value: string; value: string;
onChange: (value: string) => void; onChange: (value: string) => void;
onErrorChange?: (isError: boolean) => void;
} }
const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => { const AgeInputWithSelect = ({ value, onChange, onErrorChange }: 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);
@ -30,36 +31,36 @@ const AgeInputWithSelect = ({ value, onChange }: AgeInputWithSelectProps) => {
const validate = (val: string) => { const validate = (val: string) => {
if (!val) return false; if (!val) return false;
// Число (только положительное) // Число (только положительное)
if (/^\d+$/.test(val)) { if (/^-?\d+$/.test(val)) {
const num = Number(val); const num = Number(val);
if (num < 0 || num > 150) return 'range'; if (num < 0 || num > 150) return 'range';
return false; return false;
} }
// Диапазон (только положительные числа) // Диапазон (только положительные числа)
const rangeMatch = val.match(/^(\d+)-(\d+)$/); const rangeMatch = val.match(/^(-?\d+)-(-?\d+)$/);
if (rangeMatch) { if (rangeMatch) {
const left = Number(rangeMatch[1]); const left = Number(rangeMatch[1]);
const right = Number(rangeMatch[2]); const right = Number(rangeMatch[2]);
if (left < 0 || left > 150 || right < 0 || right > 150 || left > right) return 'range'; if (left < 0 || left > 150 || right < 0 || right > 150 || left > right) return 'range';
return false; return false;
} }
// Если есть минус не в начале диапазона — это ошибка диапазона
if (/^-?\d+-\d+$/.test(val) || /^\d+-\d+-\d+$/.test(val)) {
return 'range';
}
return 'format'; return 'format';
}; };
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const filtered = e.target.value.replace(/[^\d-]/g, ''); const filtered = e.target.value.replace(/[^\d-]/g, '');
onChange(filtered); onChange(filtered);
setErrorType(false); const err = validate(filtered);
setErrorType(err);
if (onErrorChange) onErrorChange(!!err);
}; };
const handleInputBlur = (e: React.FocusEvent<HTMLInputElement>) => { const handleInputBlur = (e: React.FocusEvent<HTMLInputElement>) => {
const trimmed = e.target.value.replace(/\s+/g, ''); const trimmed = e.target.value.replace(/\s+/g, '');
onChange(trimmed); onChange(trimmed);
setErrorType(validate(trimmed)); const err = validate(trimmed);
setErrorType(err);
if (onErrorChange) onErrorChange(!!err);
}; };
const handleSelectItemClick = (selectedValue: string) => { const handleSelectItemClick = (selectedValue: string) => {

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