import { Box, Button, Divider, TextField, Typography } from '@mui/material';
import { useEffect, useState } from 'react';
import { PrimaryButton } from '../../components/common/Buttons/Buttons';
import Modal from '../../components/common/Modal/Modal';
import SelectWithOptions from '../AdminPanel/components/SelectWithOptions';
export const ModalCreateProject = ({
open,
onClose,
onCreate,
config = {},
initialData = null,
title = 'Создание проекта',
buttonText = 'Создать',
}) => {
const [projectData, setProjectData] = useState(() => {
if (initialData) {
return { ...initialData };
}
// Иначе создаем из конфига
const data = {};
Object.keys(config).forEach((key) => {
data[key] = config[key].defaultValue;
});
return data;
});
const [errors, setErrors] = useState({});
useEffect(() => {
if (initialData) {
setProjectData({ ...initialData });
} else {
const data = {};
Object.keys(config).forEach((key) => {
data[key] = config[key].defaultValue;
});
setProjectData(data);
}
setErrors({});
}, [initialData, config, open]);
const handleChange = (field, value) => {
setProjectData((prev) => ({
...prev,
[field]: value,
}));
if (errors[field]) {
setErrors((prev) => ({
...prev,
[field]: undefined,
}));
}
};
const validateField = (fieldName, config) => {
const value = projectData[fieldName];
if (config.required_field) {
if (config.type === 'multiselect') {
if (!value || (Array.isArray(value) && value.length === 0) || value === '') {
return `Поле "${fieldName}" обязательно для заполнения`;
}
} else if (config.type === 'text') {
if (!value || value.trim() === '') {
return `Поле "${fieldName}" обязательно для заполнения`;
}
} else if (config.type === 'number') {
if (value === null || value === undefined || value === '') {
return `Поле "${fieldName}" обязательно для заполнения`;
}
}
}
if (config.type === 'number' && value !== null && value !== undefined && value !== '') {
if (config.min !== undefined && Number(value) < config.min) {
return `Значение должно быть не меньше ${config.min}`;
}
if (config.max !== undefined && Number(value) > config.max) {
return `Значение должно быть не больше ${config.max}`;
}
}
return null;
};
const validateAllFields = () => {
const newErrors = {};
let hasErrors = false;
Object.entries(config).forEach(([fieldName, fieldConfig]) => {
const error = validateField(fieldName, fieldConfig);
if (error) {
newErrors[fieldName] = error;
hasErrors = true;
}
});
setErrors(newErrors);
return !hasErrors;
};
const handleClickCreate = () => {
if (validateAllFields()) {
onCreate(projectData);
onClose();
}
};
const handleClose = () => {
const resetData = {};
Object.keys(config).forEach((key) => {
resetData[key] = config[key].defaultValue;
});
setProjectData(resetData);
setErrors({});
onClose();
};
const renderField = (fieldName, config) => {
const hasError = !!errors[fieldName];
const errorText = errors[fieldName];
switch (config.type) {
case 'multiselect':
return (
{fieldName}
{config.required_field && *}
handleChange(fieldName, value)}
width='28.25rem'
style={{
borderColor: hasError ? 'var(--error-color, #d32f2f)' : undefined,
borderWidth: hasError ? '2px' : undefined,
}}
/>
{hasError && (
{errorText}
)}
);
case 'text':
return (
{fieldName}
{config.required_field && *}
handleChange(fieldName, e.target.value)}
placeholder={config.placeholder}
size='small'
error={hasError}
helperText={hasError ? errorText : ''}
FormHelperTextProps={{
sx: {
marginLeft: 0,
fontSize: '0.75rem',
},
}}
/>
);
case 'number':
return (
{fieldName}
{config.required_field && *}
{
const inputValue = e.target.value;
const isValidInput = /^\d*\.?\d*$/.test(inputValue) || inputValue === '';
if (isValidInput) {
handleChange(fieldName, inputValue);
}
}}
placeholder={config.placeholder}
size='small'
error={hasError}
helperText={hasError ? errorText : ''}
slotProps={{
htmlInput: {
min: config.min,
max: config.max || null,
step: config.step || 1,
},
}}
FormHelperTextProps={{
sx: {
marginLeft: 0,
fontSize: '0.75rem',
},
}}
/>
);
default:
return null;
}
};
return (
{buttonText}
>
}>
{Object.entries(config).map(([fieldName, config]) => renderField(fieldName, config))}
);
};