adaptive personal to mobile / fix calculator

This commit is contained in:
aurinex
2025-07-15 20:20:59 +05:00
parent b946f5ece0
commit f65d2554c1
3 changed files with 678 additions and 381 deletions

View File

@ -30,12 +30,12 @@ function CalculatorPage() {
// Состояния для полей формы // Состояния для полей формы
const [country, setCountry] = useState("russia"); // russia или belarus const [country, setCountry] = useState("russia"); // russia или belarus
const [age, setAge] = useState("3"); // Изменено на числовое значение для упрощения расчетов const [age, setAge] = useState("<3"); // Изменено на числовое значение для упрощения расчетов
const [price, setPrice] = useState(""); const [price, setPrice] = useState("");
const [currency, setCurrency] = useState("USD Доллар США"); const [currency, setCurrency] = useState("USD Доллар США");
const [engineType, setEngineType] = useState("Бензиновый"); const [engineType, setEngineType] = useState("Бензиновый");
const [hybridType, setHybridType] = useState("Не гибрид"); const [hybridType, setHybridType] = useState("Не гибрид");
const [engineVolume, setEngineVolume] = useState(""); const [engineVolume, setEngineVolume] = useState("2000");
const [enginePower, setEnginePower] = useState(""); const [enginePower, setEnginePower] = useState("");
const [enginePowerUnit, setEnginePowerUnit] = useState("л.с."); const [enginePowerUnit, setEnginePowerUnit] = useState("л.с.");
const [electricMotorPower, setElectricMotorPower] = useState(""); const [electricMotorPower, setElectricMotorPower] = useState("");
@ -79,222 +79,400 @@ function CalculatorPage() {
loadCurrencyRates(); loadCurrencyRates();
}, []); }, []);
// const handleCalculate = () => {
// const calculatorResults = document.getElementById("calculator-results");
// if (calculatorResults) {
// calculatorResults.scrollIntoView({ behavior: "smooth" });
// }
// // Получаем курс выбранной валюты
// const currencyCode = mapCurrencyCodeToApiCode(currency);
// const exchangeRate =
// currencyCode === "RUB" ? 1 : getCurrencyRate(currencyRates, currencyCode);
// // Конвертация цены в рубли для расчета
// let priceInRub = parseFloat(price) || 0;
// // Конвертация из валюты пользователя в рубли
// if (currencyCode !== "RUB") {
// priceInRub *= exchangeRate;
// }
// // Минимальная стоимость для расчета (устанавливается таможней)
// const eurRate = getCurrencyRate(currencyRates, "EUR");
// const minCustomValue = 8500 * eurRate; // минимальная стоимость в рублях (8500 евро)
// const calculationValue = Math.max(priceInRub, minCustomValue);
// let customDuty = 0;
// let exciseTax = 0;
// let vat = 0;
// let utilityFee = 0;
// let totalFees = 0;
// // Расчет для физических лиц
// if (calculationType === "Физ. лица") {
// // Коэффициент для возраста
// let ageCoef = 1;
// switch (age) {
// case "3": // менее 3 лет
// ageCoef = 0.54; // 54% от стоимости
// break;
// case "3-5": // от 3 до 5 лет
// ageCoef = 0.48; // 48% от стоимости
// break;
// case "5+": // более 5 лет
// ageCoef = 0.48; // 48% от стоимости (но не менее 2.5 евро/см3)
// break;
// default:
// ageCoef = 0.54;
// }
// // Расчет пошлины для ДВС
// if (engineType === "Бензиновый" || engineType === "Дизельный") {
// const engineVolumeNum = parseFloat(engineVolume) || 0;
// let engineVolumeCoefficient = 1.0;
// if (age === "3-5") {
// if (engineVolumeNum <= 1000) {
// engineVolumeCoefficient = 1.5;
// } else if (engineVolumeNum <= 1500) {
// engineVolumeCoefficient = 1.7;
// } else if (engineVolumeNum <= 1800) {
// engineVolumeCoefficient = 2.5;
// } else if (engineVolumeNum <= 2300) {
// engineVolumeCoefficient = 2.7;
// } else if (engineVolumeNum <= 3000) {
// engineVolumeCoefficient = 3.0;
// } else if (engineVolumeNum > 3000) {
// engineVolumeCoefficient = 3.6;
// }
// }
// const engineVolumeDuty = engineVolumeCoefficient * engineVolumeNum * eurRate;
// // Для авто менее 3 лет
// if (age === "<3") {
// const percentDuty = calculationValue * 0.54;
// customDuty = Math.max(engineVolumeDuty, percentDuty);
// }
// // Для авто 3-5 лет
// else if (age === "3-5") {
// customDuty = engineVolumeDuty;
// }
// // Для авто старше 5 лет
// else if (age === "5-10" || age === ">10") {
// const ageCoefficient = 1.3; // Например, для 5-10 лет
// customDuty = engineVolumeCoefficient * engineVolumeNum * eurRate * ageCoefficient;
// }
// // Акцизы в зависимости от мощности
// const enginePowerNum = parseFloat(enginePower) || 0;
// let powerInHP = enginePowerNum;
// if (enginePowerUnit === "кВт") {
// powerInHP = enginePowerNum * 1.35962;
// }
// let ageCoefficient = 1.0;
// if (age === "3-5") {
// ageCoefficient = 1.1;
// } else if (age === "5-10") {
// ageCoefficient = 1.3;
// } else if (age === ">10") {
// ageCoefficient = 1.5;
// }
// // Акцизные ставки на 2024 год (в рублях за 1 л.с.)
// if (powerInHP <= 90) {
// exciseTax = powerInHP * 0 * ageCoefficient;
// } else if (powerInHP <= 150) {
// exciseTax = powerInHP * 54 * ageCoefficient;
// } else if (powerInHP <= 200) {
// exciseTax = powerInHP * 714 * ageCoefficient;
// } else if (powerInHP <= 300) {
// exciseTax = powerInHP * 1218 * ageCoefficient;
// } else if (powerInHP <= 400) {
// exciseTax = powerInHP * 1260 * ageCoefficient;
// } else if (powerInHP <= 500) {
// exciseTax = powerInHP * 1302 * ageCoefficient;
// } else if (powerInHP > 500) {
// exciseTax = powerInHP * 1374 * ageCoefficient;
// }
// }
// // Для электромобилей
// else if (engineType === "Электрический") {
// customDuty = 0; // Пошлина 0% для электромобилей
// exciseTax = 0; // Акциз 0 для электромобилей
// }
// // Для гибридов
// else if (engineType === "Гибридный") {
// // Для гибридов применяются те же ставки, что и для ДВС
// const engineVolumeNum = parseFloat(engineVolume) || 0;
// if (age === "3") {
// customDuty = calculationValue * 0.54;
// } else if (age === "3-5") {
// customDuty = calculationValue * 0.48;
// } else {
// const dutyPerCm3 = 2.5; // евро за см3
// const dutyInEur = engineVolumeNum * dutyPerCm3;
// customDuty = dutyInEur * eurRate;
// customDuty = Math.max(customDuty, calculationValue * 0.48);
// }
// // Акциз для гибридов рассчитывается так же, как для ДВС
// const enginePowerNum = parseFloat(enginePower) || 0;
// let powerInHP = enginePowerNum;
// if (enginePowerUnit === "кВт") {
// powerInHP = enginePowerNum * 1.35962;
// }
// let ageCoefficient = 1.0;
// if (age === "3-5") {
// ageCoefficient = 1.1;
// } else if (age === "5-10") {
// ageCoefficient = 1.3;
// } else if (age === ">10") {
// ageCoefficient = 1.5;
// }
// if (powerInHP <= 90) {
// exciseTax = powerInHP * 0 * ageCoefficient;
// } else if (powerInHP <= 150) {
// exciseTax = powerInHP * 54 * ageCoefficient;
// } else if (powerInHP <= 200) {
// exciseTax = powerInHP * 714 * ageCoefficient;
// } else if (powerInHP <= 300) {
// exciseTax = powerInHP * 1218 * ageCoefficient;
// } else if (powerInHP <= 400) {
// exciseTax = powerInHP * 1260 * ageCoefficient;
// } else if (powerInHP <= 500) {
// exciseTax = powerInHP * 1302 * ageCoefficient;
// } else if (powerInHP > 500) {
// exciseTax = powerInHP * 1374 * ageCoefficient;
// }
// }
// // НДС 20% от (стоимость + пошлина + акциз)
// vat = (calculationValue + customDuty + exciseTax) * 0.2;
// // Утилизационный сбор
// if (engineType === "Электрический") {
// utilityFee = 3400; // Для электромобилей
// } else {
// utilityFee = enhancedPermeability ? 27000 : 3400; // Для внедорожников выше
// }
// }
// // Расчет для юридических лиц
// else {
// // Здесь должна быть другая логика расчета для юр.лиц
// // В данном примере используем упрощенный расчет, аналогичный физ.лицам
// customDuty = calculationValue * 0.12; // Примерная ставка для юр.лиц
// // Акцизы в зависимости от мощности
// const enginePowerNum = parseFloat(enginePower) || 0;
// let powerInHP = enginePowerNum;
// if (enginePowerUnit === "кВт") {
// powerInHP = enginePowerNum * 1.35962;
// }
// // Акцизные ставки для юр.лиц могут отличаться
// if (powerInHP <= 90) {
// exciseTax = powerInHP * 0;
// } else if (powerInHP <= 150) {
// exciseTax = powerInHP * 55;
// } else {
// exciseTax = powerInHP * 531;
// }
// // НДС 20%
// vat = (calculationValue + customDuty + exciseTax) * 0.2;
// // Утилизационный сбор для юр.лиц
// utilityFee = engineType === "Электрический" ? 3500 : 5000;
// }
// // Итоговая сумма таможенных платежей
// totalFees = customDuty + exciseTax + vat + utilityFee;
// // Сохраняем результаты расчетов
// const results = {
// priceInRub: priceInRub.toFixed(2),
// customDuty: customDuty.toFixed(2),
// exciseTax: exciseTax.toFixed(2),
// vat: vat.toFixed(2),
// utilityFee: utilityFee.toFixed(2),
// totalFees: totalFees.toFixed(2),
// totalWithCar: (priceInRub + totalFees).toFixed(2),
// };
// setCalculationResults(results);
// // После расчетов установить флаг анимации
// setSlideIn(true);
// // Выводим результаты также в консоль для отладки
// console.log({
// original: {
// price,
// currency,
// currencyRate: exchangeRate,
// country,
// age,
// engineType,
// hybridType,
// engineVolume,
// enginePower,
// enginePowerUnit,
// electricMotorPower,
// electricMotorPowerUnit,
// powerRatio,
// calculationType,
// enhancedPermeability,
// },
// calculation: results,
// });
// };
const handleCalculate = () => { const handleCalculate = () => {
const calculatorResults = document.getElementById("calculator-results"); const calculatorResults = document.getElementById("calculator-results");
if (calculatorResults) { if (calculatorResults) {
calculatorResults.scrollIntoView({ behavior: "smooth" }); calculatorResults.scrollIntoView({ behavior: "smooth" });
} }
// Получаем курс выбранной валюты
// Получаем курс валют
const currencyCode = mapCurrencyCodeToApiCode(currency); const currencyCode = mapCurrencyCodeToApiCode(currency);
const exchangeRate = const exchangeRate = currencyCode === "RUB" ? 1 : getCurrencyRate(currencyRates, currencyCode);
currencyCode === "RUB" ? 1 : getCurrencyRate(currencyRates, currencyCode); const eurRate = getCurrencyRate(currencyRates, "EUR");
// Конвертация цены в рубли для расчета // Конвертация цены в рубли
let priceInRub = parseFloat(price) || 0; let priceInRub = parseFloat(price) || 0;
// Конвертация из валюты пользователя в рубли
if (currencyCode !== "RUB") { if (currencyCode !== "RUB") {
priceInRub *= exchangeRate; priceInRub *= exchangeRate;
} }
// Минимальная стоимость для расчета (устанавливается таможней) // Инициализация переменных
const eurRate = getCurrencyRate(currencyRates, "EUR");
const minCustomValue = 8500 * eurRate; // минимальная стоимость в рублях (8500 евро)
const calculationValue = Math.max(priceInRub, minCustomValue);
let customDuty = 0; let customDuty = 0;
let exciseTax = 0; let exciseTax = 0;
let vat = 0; let vat = 0;
let utilityFee = 0; let utilityFee = 0;
let totalFees = 0; let totalFees = 0;
// Расчет для физических лиц // Расчет только для физ. лиц
if (calculationType === "Физ. лица") { if (calculationType === "Физ. лица") {
// Коэффициент для возраста
let ageCoef = 1;
switch (age) {
case "3": // менее 3 лет
ageCoef = 0.54; // 54% от стоимости
break;
case "3-5": // от 3 до 5 лет
ageCoef = 0.48; // 48% от стоимости
break;
case "5+": // более 5 лет
ageCoef = 0.48; // 48% от стоимости (но не менее 2.5 евро/см3)
break;
default:
ageCoef = 0.54;
}
// Расчет пошлины для ДВС
if (engineType === "Бензиновый" || engineType === "Дизельный") {
const engineVolumeNum = parseFloat(engineVolume) || 0; const engineVolumeNum = parseFloat(engineVolume) || 0;
// Для авто менее 3 лет
if (age === "3") {
customDuty = calculationValue * 0.54; // 54% от стоимости
}
// Для авто 3-5 лет
else if (age === "3-5") {
customDuty = calculationValue * 0.48; // 48% от стоимости
}
// Для авто старше 5 лет
else {
const dutyPerCm3 = 2.5; // евро за см3
const dutyInEur = engineVolumeNum * dutyPerCm3;
customDuty = dutyInEur * eurRate; // переводим в рубли по курсу евро
// Берем максимум между процентом и фиксированной ставкой
customDuty = Math.max(customDuty, calculationValue * 0.48);
}
// Акцизы в зависимости от мощности
const enginePowerNum = parseFloat(enginePower) || 0; const enginePowerNum = parseFloat(enginePower) || 0;
let powerInHP = enginePowerNum; let powerInHP = enginePowerUnit === "кВт" ? enginePowerNum * 1.35962 : enginePowerNum;
if (enginePowerUnit === "кВт") { // Корректировка стоимости только для авто до 3 лет
powerInHP = enginePowerNum * 1.35962; let calculationValue = priceInRub;
if (age === "<3") {
const minCustomValue = 8500 * eurRate;
calculationValue = Math.max(priceInRub, minCustomValue);
} }
// Акцизные ставки на 2024 год (в рублях за 1 л.с.) // Расчет пошлины
if (powerInHP <= 90) {
exciseTax = powerInHP * 0;
} else if (powerInHP <= 150) {
exciseTax = powerInHP * 53;
} else if (powerInHP <= 200) {
exciseTax = powerInHP * 511;
} else if (powerInHP <= 300) {
exciseTax = powerInHP * 836;
} else if (powerInHP <= 400) {
exciseTax = powerInHP * 1425;
} else {
exciseTax = powerInHP * 1475;
}
}
// Для электромобилей
else if (engineType === "Электрический") {
customDuty = 0; // Пошлина 0% для электромобилей
exciseTax = 0; // Акциз 0 для электромобилей
}
// Для гибридов
else if (engineType === "Гибридный") {
// Для гибридов применяются те же ставки, что и для ДВС
const engineVolumeNum = parseFloat(engineVolume) || 0;
if (age === "3") {
customDuty = calculationValue * 0.54;
} else if (age === "3-5") {
customDuty = calculationValue * 0.48;
} else {
const dutyPerCm3 = 2.5; // евро за см3
const dutyInEur = engineVolumeNum * dutyPerCm3;
customDuty = dutyInEur * eurRate;
customDuty = Math.max(customDuty, calculationValue * 0.48);
}
// Акциз для гибридов рассчитывается так же, как для ДВС
const enginePowerNum = parseFloat(enginePower) || 0;
let powerInHP = enginePowerNum;
if (enginePowerUnit === "кВт") {
powerInHP = enginePowerNum * 1.35962;
}
if (powerInHP <= 90) {
exciseTax = powerInHP * 0;
} else if (powerInHP <= 150) {
exciseTax = powerInHP * 53;
} else if (powerInHP <= 200) {
exciseTax = powerInHP * 511;
} else if (powerInHP <= 300) {
exciseTax = powerInHP * 836;
} else if (powerInHP <= 400) {
exciseTax = powerInHP * 1425;
} else {
exciseTax = powerInHP * 1475;
}
}
// НДС 20% от (стоимость + пошлина + акциз)
vat = (calculationValue + customDuty + exciseTax) * 0.2;
// Утилизационный сбор
if (engineType === "Электрический") { if (engineType === "Электрический") {
utilityFee = 3400; // Для электромобилей customDuty = 0;
} else {
utilityFee = enhancedPermeability ? 27000 : 3400; // Для внедорожников выше
} }
}
// Расчет для юридических лиц
else { else {
// Здесь должна быть другая логика расчета для юр.лиц // Для ДВС и гибридов
// В данном примере используем упрощенный расчет, аналогичный физ.лицам if (age === "<3") {
customDuty = calculationValue * 0.12; // Примерная ставка для юр.лиц const percentDuty = priceInRub * 0.54;
const volumeDuty = engineVolumeNum * 2.5 * eurRate;
customDuty = Math.max(percentDuty, volumeDuty);
}
else if (age === "3-5") {
// Ставки для авто 3-5 лет
let rate;
if (engineVolumeNum <= 1000) rate = 1.5;
else if (engineVolumeNum <= 1500) rate = 1.7;
else if (engineVolumeNum <= 1800) rate = 2.5;
else if (engineVolumeNum <= 2300) rate = 2.7;
else if (engineVolumeNum <= 3000) rate = 3.0;
else rate = 3.6;
// Акцизы в зависимости от мощности customDuty = engineVolumeNum * rate * eurRate;
const enginePowerNum = parseFloat(enginePower) || 0; }
let powerInHP = enginePowerNum; else {
// Ставки для авто старше 5 лет
let rate;
if (engineVolumeNum <= 1000) rate = 3.0;
else if (engineVolumeNum <= 1500) rate = 3.2;
else if (engineVolumeNum <= 1800) rate = 3.5;
else if (engineVolumeNum <= 2300) rate = 4.8;
else if (engineVolumeNum <= 3000) rate = 5.0;
else rate = 5.7;
if (enginePowerUnit === "кВт") { const ageCoef = age === "5-10" ? 1.3 : 1.5;
powerInHP = enginePowerNum * 1.35962; customDuty = engineVolumeNum * rate * eurRate * ageCoef;
}
} }
// Акцизные ставки для юр.лиц могут отличаться // Расчет акциза (только для ДВС и гибридов)
if (engineType !== "Электрический") {
let ageCoefficient = 1.0;
if (age === "3-5") ageCoefficient = 1.1;
else if (age === "5-10") ageCoefficient = 1.3;
else if (age === ">10") ageCoefficient = 1.5;
if (powerInHP <= 90) { if (powerInHP <= 90) {
exciseTax = powerInHP * 0; exciseTax = 0;
} else if (powerInHP <= 150) { } else if (powerInHP <= 150) {
exciseTax = powerInHP * 55; exciseTax = powerInHP * 54 * ageCoefficient;
} else if (powerInHP <= 200) {
exciseTax = powerInHP * 714 * ageCoefficient;
} else if (powerInHP <= 300) {
exciseTax = powerInHP * 1218 * ageCoefficient;
} else if (powerInHP <= 400) {
exciseTax = powerInHP * 1260 * ageCoefficient;
} else if (powerInHP <= 500) {
exciseTax = powerInHP * 1302 * ageCoefficient;
} else { } else {
exciseTax = powerInHP * 531; exciseTax = powerInHP * 1374 * ageCoefficient;
}
} }
// НДС 20% // НДС 20%
vat = (calculationValue + customDuty + exciseTax) * 0.2; vat = (calculationValue + customDuty + exciseTax) * 0.2;
// Утилизационный сбор для юр.лиц // Утилизационный сбор
utilityFee = engineType === "Электрический" ? 3500 : 5000; utilityFee = engineType === "Электрический" ? 0 :
enhancedPermeability ? 27000 : 3400;
} }
// Итоговая сумма таможенных платежей // Итоговые расчеты
totalFees = customDuty + exciseTax + vat + utilityFee; totalFees = customDuty + exciseTax + vat + utilityFee;
// Сохраняем результаты расчетов // Округление до целых рублей
const round = (value) => Math.round(value);
// Сохранение результатов
const results = { const results = {
priceInRub: priceInRub.toFixed(2), priceInRub: round(priceInRub),
customDuty: customDuty.toFixed(2), customDuty: round(customDuty),
exciseTax: exciseTax.toFixed(2), exciseTax: round(exciseTax),
vat: vat.toFixed(2), vat: round(vat),
utilityFee: utilityFee.toFixed(2), utilityFee: round(utilityFee),
totalFees: totalFees.toFixed(2), totalFees: round(totalFees),
totalWithCar: (priceInRub + totalFees).toFixed(2), totalWithCar: round(priceInRub + totalFees),
}; };
setCalculationResults(results); setCalculationResults(results);
// После расчетов установить флаг анимации
setSlideIn(true); setSlideIn(true);
// Выводим результаты также в консоль для отладки // Логирование для отладки
console.log({ console.log({
original: { input: {
price, price, currency, age, engineType,
currency, engineVolume, enginePower, enginePowerUnit,
currencyRate: exchangeRate, calculationType, enhancedPermeability
country,
age,
engineType,
hybridType,
engineVolume,
enginePower,
enginePowerUnit,
electricMotorPower,
electricMotorPowerUnit,
powerRatio,
calculationType,
enhancedPermeability,
}, },
calculation: results, calculation: results,
rates: { eurRate, exchangeRate }
}); });
}; };
@ -538,9 +716,10 @@ function CalculatorPage() {
displayEmpty displayEmpty
sx={selectStyles} sx={selectStyles}
> >
<MenuItem value="3">Менее 3х лет</MenuItem> <MenuItem value="<3">Менее 3х лет</MenuItem>
<MenuItem value="3-5">3-5 лет</MenuItem> <MenuItem value="3-5">3-5 лет</MenuItem>
<MenuItem value="5+">5+ лет</MenuItem> <MenuItem value="5-10">5-10 лет</MenuItem>
<MenuItem value=">10">10+ лет</MenuItem>
</Select> </Select>
</Box> </Box>

View File

@ -42,6 +42,7 @@ import PersonIcon from '@mui/icons-material/Person';
import BadgeIcon from '@mui/icons-material/Badge'; import BadgeIcon from '@mui/icons-material/Badge';
import WorkIcon from '@mui/icons-material/Work'; import WorkIcon from '@mui/icons-material/Work';
import { useAuth } from '../../context/AuthContext'; import { useAuth } from '../../context/AuthContext';
import { useResponsive } from "../../theme/useResponsive";
import { import {
fetchTeam, fetchTeam,
createTeamMember, createTeamMember,
@ -66,6 +67,7 @@ interface TeamResponse {
const Personal = () => { const Personal = () => {
const { token } = useAuth(); const { token } = useAuth();
const { isMobile } = useResponsive();
const [staff, setStaff] = useState<TeamMember[]>([]); const [staff, setStaff] = useState<TeamMember[]>([]);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [error, setError] = useState(''); const [error, setError] = useState('');
@ -246,8 +248,8 @@ const Personal = () => {
component={Paper} component={Paper}
elevation={3} elevation={3}
sx={{ sx={{
borderRadius: 2, borderRadius: isMobile ? "2vw" : "1vw",
overflow: 'hidden' overflow: isMobile ? "scroll" : "hidden"
}} }}
> >
<Table> <Table>
@ -278,9 +280,9 @@ const Personal = () => {
src={getImageUrl(member.photo)} src={getImageUrl(member.photo)}
alt={`${member.name} ${member.surname}`} alt={`${member.name} ${member.surname}`}
sx={{ sx={{
width: 56, width: isMobile ? "15vw" : 56,
height: 56, height: isMobile ? "15vw" : 56,
boxShadow: '0 2px 4px rgba(0,0,0,0.1)' boxShadow: '0 0.2vw 0.4vw rgba(0,0,0,0.1)'
}} }}
> >
{getInitials(member.name, member.surname)} {getInitials(member.name, member.surname)}
@ -302,11 +304,13 @@ const Personal = () => {
onClick={() => handleOpenEditDialog(member)} onClick={() => handleOpenEditDialog(member)}
color="primary" color="primary"
sx={{ sx={{
bgcolor: 'rgba(25, 118, 210, 0.1)', color: "black",
mr: 1, "&:hover": {
'&:hover': { color: "#C27664",
bgcolor: 'rgba(25, 118, 210, 0.2)', bgcolor: "transparent",
} },
transition: "all 0.2s ease",
mr: 1
}} }}
> >
<EditIcon /> <EditIcon />
@ -317,10 +321,11 @@ const Personal = () => {
onClick={() => handleOpenDeleteDialog(member)} onClick={() => handleOpenDeleteDialog(member)}
color="error" color="error"
sx={{ sx={{
bgcolor: 'rgba(211, 47, 47, 0.1)', "&:hover": {
'&:hover': { color: "#C27664",
bgcolor: 'rgba(211, 47, 47, 0.2)', bgcolor: "transparent",
} },
transition: "all 0.2s ease",
}} }}
> >
<DeleteIcon /> <DeleteIcon />
@ -336,7 +341,7 @@ const Personal = () => {
// Рендер сетки карточек // Рендер сетки карточек
const renderGrid = () => ( const renderGrid = () => (
<Grid container spacing={3}> <Grid container spacing={3} style={{ justifyContent: isMobile ? "center" : "auto" }}>
{filteredStaff.map((member) => ( {filteredStaff.map((member) => (
<Grid item xs={12} sm={6} md={4} lg={3} key={member.id}> <Grid item xs={12} sm={6} md={4} lg={3} key={member.id}>
<Card <Card
@ -345,11 +350,12 @@ const Personal = () => {
height: '100%', height: '100%',
display: 'flex', display: 'flex',
flexDirection: 'column', flexDirection: 'column',
borderRadius: 2, borderRadius: isMobile ? "5vw" : "1vw",
transition: 'transform 0.3s, box-shadow 0.3s', transition: "transform 0.3s, box-shadow 0.3s",
'&:hover': { boxShadow: "0 0.5vw 1vw rgba(0,0,0,0.15)",
transform: 'translateY(-5px)', "&:hover": {
boxShadow: '0 10px 20px rgba(0,0,0,0.1)' transform: "translateY(-0.2vw)",
boxShadow: "0 0.5vw 1vw rgba(0,0,0,0.1)",
} }
}} }}
> >
@ -364,12 +370,19 @@ const Personal = () => {
left: 0, left: 0,
width: '100%', width: '100%',
height: '100%', height: '100%',
objectFit: 'cover' objectFit: 'cover',
userSelect: "none",
pointerEvents: "none",
}} }}
/> />
</Box> </Box>
<CardContent sx={{ flexGrow: 1, pt: 2 }}> <CardContent sx={{ flexGrow: 1, pt: isMobile ? "3vw" : "2vw" }}>
<Typography gutterBottom variant="h6" component="div" sx={{ fontWeight: 'bold', mb: 0.5 }}> <Typography gutterBottom variant="h6" component="div" sx={{
fontWeight: "bold",
mb: "0.5vw",
fontFamily: "Unbounded",
fontSize: isMobile ? "4vw" : "1.2vw"
}}>
{member.name} {member.surname} {member.name} {member.surname}
</Typography> </Typography>
@ -380,21 +393,26 @@ const Personal = () => {
sx={{ sx={{
bgcolor: '#e3f2fd', bgcolor: '#e3f2fd',
color: '#1565c0', color: '#1565c0',
mt: 1 mt: 1,
fontSize: isMobile ? "3vw" : "inherit"
}} }}
/> />
</CardContent> </CardContent>
<Divider /> <Divider />
<CardActions sx={{ justifyContent: 'space-between', p: 1.5 }}> <CardActions sx={{ justifyContent: 'space-between', p: isMobile ? "3vw" : "1.5vw" }}>
<Button <Button
size="small" size="small"
startIcon={<EditIcon />} startIcon={<EditIcon />}
onClick={() => handleOpenEditDialog(member)} onClick={() => handleOpenEditDialog(member)}
sx={{ sx={{
color: '#1976d2', color: "black",
'&:hover': { bgcolor: 'rgba(25, 118, 210, 0.1)' } "&:hover": { color: "#C27664", bgcolor: "transparent" },
transition: "all 0.2s ease",
fontFamily: "Unbounded",
fontWeight: "bold",
fontSize: isMobile ? "4.5vw" : "0.8vw",
}} }}
> >
Изменить Изменить
@ -404,8 +422,15 @@ const Personal = () => {
startIcon={<DeleteIcon />} startIcon={<DeleteIcon />}
onClick={() => handleOpenDeleteDialog(member)} onClick={() => handleOpenDeleteDialog(member)}
sx={{ sx={{
color: '#d32f2f', color: "rgb(214, 74, 74)",
'&:hover': { bgcolor: 'rgba(211, 47, 47, 0.1)' } "&:hover": {
color: "rgba(150, 0, 0, 1)",
bgcolor: "transparent",
},
transition: "all 0.2s ease",
fontFamily: "Unbounded",
fontWeight: "bold",
fontSize: isMobile ? "4.5vw" : "0.8vw",
}} }}
> >
Удалить Удалить
@ -417,33 +442,57 @@ const Personal = () => {
</Grid> </Grid>
); );
// Общие стили для компонентов формы
const textFieldStyles = {
"& .MuiOutlinedInput-root": {
borderRadius: isMobile ? "5vw" : "1vw",
bgcolor: "white",
height: isMobile ? "8vw" : "4vw",
width: "100%",
border: "0.1vw solid #C27664",
fontFamily: "Unbounded",
fontSize: isMobile ? "4vw" : "1.2vw",
color: "#C27664",
mb: isMobile ? "3vw" : "0",
"& fieldset": {
border: "none",
},
},
};
return ( return (
<Box sx={{ p: 3 }}> <Box sx={{ p: isMobile ? "4vw" : "3vw" }}>
{/* Заголовок и кнопки управления */} {/* Заголовок и кнопки управления */}
<Paper <Paper
elevation={3} elevation={3}
sx={{ sx={{
p: 3, mt: isMobile ? "3vw" : "0",
mb: 3, p: isMobile ? "3vw" : "2vw",
borderRadius: 2, mb: isMobile ? "5vw" : "2vw",
background: 'linear-gradient(to right, #2D2D2D, #3D3D3D)' borderRadius: isMobile ? "5vw" : "1vw",
background: "linear-gradient(to right, #2D2D2D, #3D3D3D)"
}} }}
> >
<Box sx={{ <Box sx={{
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: isMobile ? "center" : "space-between",
alignItems: 'center', alignItems: 'center',
flexWrap: 'wrap', flexWrap: 'wrap',
gap: 2 gap: isMobile ? "1vw" : "2vw"
}}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: isMobile ? "1vw" : "2vw" }}>
<PersonIcon sx={{ fontSize: isMobile ? "9vw" : "2vw", color: "#C27664" }} />
<Typography variant="h5" sx={{
fontFamily: "Unbounded",
fontWeight: "bold",
color: "white",
fontSize: isMobile ? "4vw" : "2vw"
}}> }}>
<Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
<PersonIcon sx={{ fontSize: 40, color: '#C27664' }} />
<Typography variant="h5" sx={{ fontFamily: 'Unbounded', fontWeight: 'bold', color: 'white' }}>
Управление персоналом Управление персоналом
</Typography> </Typography>
</Box> </Box>
<Box sx={{ display: 'flex', gap: 2 }}> <Box sx={{ display: 'flex', gap: "1vw" }}>
<Button <Button
variant="contained" variant="contained"
onClick={handleOpenCreateDialog} onClick={handleOpenCreateDialog}
@ -453,8 +502,9 @@ const Personal = () => {
color: "white", color: "white",
textTransform: "none", textTransform: "none",
fontFamily: "Unbounded", fontFamily: "Unbounded",
borderRadius: 2, borderRadius: isMobile ? "5vw" : "1vw",
px: 3, margin: isMobile ? "2vw" : "0",
px: isMobile ? "5vw" : "2vw",
"&:hover": { bgcolor: "#945B4D" }, "&:hover": { bgcolor: "#945B4D" },
}} }}
> >
@ -468,14 +518,15 @@ const Personal = () => {
<Paper <Paper
elevation={2} elevation={2}
sx={{ sx={{
p: 2, p: isMobile ? "3.5vw" : "1.5vw",
mb: 3, mb: isMobile ? "5vw" : "2vw",
display: 'flex', display: 'flex',
justifyContent: 'space-between', justifyContent: 'space-between',
alignItems: 'center', alignItems: 'center',
borderRadius: 2, borderRadius: isMobile ? "5vw" : "1vw",
flexWrap: 'wrap', flexWrap: 'wrap',
gap: 2 gap: "1vw",
boxShadow: "0 0.5vw 1vw rgba(0,0,0,0.15)",
}} }}
> >
<TextField <TextField
@ -486,8 +537,9 @@ const Personal = () => {
size="small" size="small"
sx={{ sx={{
minWidth: 300, minWidth: 300,
'& .MuiOutlinedInput-root': { "& .MuiOutlinedInput-root": {
borderRadius: 2 borderRadius: isMobile ? "5vw" : "1vw",
width: isMobile ? "95%" : "auto",
} }
}} }}
InputProps={{ InputProps={{
@ -499,8 +551,12 @@ const Personal = () => {
}} }}
/> />
<Box sx={{ display: 'flex', alignItems: 'center' }}> <Box sx={{ display: "flex", alignItems: "center", flexDirection: isMobile ? "column" : "row", width: isMobile ? "100%" : "auto", justifyContent: isMobile ? "center" : "auto" }}>
<Typography variant="body2" color="text.secondary" sx={{ mr: 2 }}> <Typography
variant="body2"
color="text.secondary"
sx={{ mr: isMobile ? "0" : "1vw", mt: isMobile ? "2vw" : "0", fontFamily: "Unbounded", fontSize: isMobile ? "5vw" : "1vw" }}
>
Всего: {totalStaff} сотрудников Всего: {totalStaff} сотрудников
</Typography> </Typography>
@ -529,7 +585,7 @@ const Personal = () => {
{/* Сообщения об ошибках */} {/* Сообщения об ошибках */}
{error && ( {error && (
<Alert severity="error" sx={{ mb: 2, borderRadius: 2 }}> <Alert severity="error" sx={{ mb: isMobile ? "5vw" : "1vw", borderRadius: isMobile ? "5vw" : "1vw", border: isMobile ? "0.1vw solid #C27664" : "none" }}>
{error} {error}
</Alert> </Alert>
)} )}
@ -537,10 +593,10 @@ const Personal = () => {
{/* Индикатор загрузки */} {/* Индикатор загрузки */}
{loading ? ( {loading ? (
<Box sx={{ <Box sx={{
display: 'flex', display: "flex",
justifyContent: 'center', justifyContent: "center",
alignItems: 'center', alignItems: "center",
minHeight: 400 minHeight: "10vw"
}}> }}>
<CircularProgress sx={{ color: '#C27664' }} /> <CircularProgress sx={{ color: '#C27664' }} />
</Box> </Box>
@ -548,16 +604,17 @@ const Personal = () => {
<Paper <Paper
elevation={2} elevation={2}
sx={{ sx={{
p: 4, p: "4vw",
textAlign: 'center', textAlign: "center",
borderRadius: 2, borderRadius: "1vw",
bgcolor: '#f9f9f9' bgcolor: "#f9f9f9",
boxShadow: "0 0.5vw 1vw rgba(0,0,0,0.15)",
}} }}
> >
<Typography variant="h6" color="text.secondary"> <Typography variant="h6" color="text.secondary" sx={{ fontFamily: "Unbounded" }}>
Сотрудники не найдены Сотрудники не найдены
</Typography> </Typography>
<Typography variant="body2" color="text.secondary" sx={{ mt: 1 }}> <Typography variant="body2" color="text.secondary" sx={{ fontFamily: "Unbounded" }}>
Попробуйте изменить параметры поиска или добавьте нового сотрудника Попробуйте изменить параметры поиска или добавьте нового сотрудника
</Typography> </Typography>
</Paper> </Paper>
@ -573,66 +630,75 @@ const Personal = () => {
maxWidth="md" maxWidth="md"
fullWidth fullWidth
PaperProps={{ PaperProps={{
sx: { borderRadius: 2 } sx: { borderRadius: isMobile ? "5vw" : "1vw" }
}} }}
> >
<DialogTitle sx={{ <DialogTitle sx={{
fontFamily: 'Unbounded', fontFamily: "Unbounded",
bgcolor: '#2D2D2D', bgcolor: "#2D2D2D",
color: 'white', color: "white",
display: 'flex', display: "flex",
alignItems: 'center', alignItems: "center",
gap: 1 gap: "1vw"
}}> }}>
<AddIcon /> Добавить сотрудника <AddIcon /> Добавить сотрудника
</DialogTitle> </DialogTitle>
<DialogContent sx={{ mt: 2 }}> <DialogContent sx={{ mt: isMobile ? "3vw" : "1vw" }}>
<Grid container spacing={3}> <Grid container spacing={3}>
<Grid item xs={12} md={6}> <Grid
item
xs={12}
md={6}
style={{
display: isMobile ? "block" : "grid",
gridTemplateColumns: isMobile ? "auto" : "repeat(1, 1fr)",
gap: "1vw",
}}
>
<TextField <TextField
name="name" name="name"
label="Имя" placeholder="Имя"
value={formData.name} value={formData.name}
onChange={handleInputChange} onChange={handleInputChange}
fullWidth fullWidth
margin="normal"
variant="outlined" variant="outlined"
sx={textFieldStyles}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
<PersonIcon color="action" /> <PersonIcon sx={{ color: "#C27664", fontSize: isMobile ? "5vw" : "2vw" }} />
</InputAdornment> </InputAdornment>
), ),
}} }}
/> />
<TextField <TextField
name="surname" name="surname"
label="Фамилия" placeholder="Фамилия"
value={formData.surname} value={formData.surname}
onChange={handleInputChange} onChange={handleInputChange}
fullWidth fullWidth
margin="normal"
variant="outlined" variant="outlined"
sx={textFieldStyles}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
<BadgeIcon color="action" /> <BadgeIcon sx={{ color: "#C27664", fontSize: isMobile ? "5vw" : "2vw" }} />
</InputAdornment> </InputAdornment>
), ),
}} }}
/> />
<TextField <TextField
name="role" name="role"
label="Должность" placeholder="Должность"
value={formData.role} value={formData.role}
onChange={handleInputChange} onChange={handleInputChange}
fullWidth fullWidth
margin="normal"
variant="outlined" variant="outlined"
sx={textFieldStyles}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
<WorkIcon color="action" /> <WorkIcon sx={{ color: "#C27664", fontSize: isMobile ? "5vw" : "2vw" }} />
</InputAdornment> </InputAdornment>
), ),
}} }}
@ -641,15 +707,16 @@ const Personal = () => {
variant="outlined" variant="outlined"
component="label" component="label"
sx={{ sx={{
mt: 2, borderRadius: isMobile ? "5vw" : "1vw",
borderRadius: 2, p: isMobile ? "2vw" : "1vw",
p: 1.5, borderColor: "#C27664",
borderColor: '#C27664', fontFamily: "Unbounded",
color: '#C27664', color: "#C27664",
'&:hover': { fontSize: isMobile ? "3vw" : "1.2vw",
borderColor: '#945B4D', "&:hover": {
bgcolor: 'rgba(194, 118, 100, 0.1)' borderColor: "#945B4D",
} bgcolor: "rgba(194, 118, 100, 0.1)",
},
}} }}
fullWidth fullWidth
> >
@ -666,13 +733,14 @@ const Personal = () => {
<Paper <Paper
elevation={2} elevation={2}
sx={{ sx={{
height: '100%', height: "100%",
display: 'flex', display: "flex",
alignItems: 'center', alignItems: "center",
justifyContent: 'center', justifyContent: "center",
borderRadius: 2, borderRadius: "1vw",
overflow: 'hidden', overflow: "hidden",
bgcolor: '#f5f5f5' bgcolor: "#2D2D2D",
boxShadow: "0 0.5vw 1vw rgba(0,0,0,0.15)",
}} }}
> >
{photoPreview ? ( {photoPreview ? (
@ -681,14 +749,24 @@ const Personal = () => {
src={photoPreview} src={photoPreview}
alt="Предпросмотр" alt="Предпросмотр"
sx={{ sx={{
width: '100%', width: "100%",
height: '100%', height: "100%",
objectFit: 'contain', objectFit: "contain",
p: 2 p: "1vw",
userSelect: "none",
pointerEvents: "none",
}} }}
/> />
) : ( ) : (
<Typography color="text.secondary" sx={{ p: 4, textAlign: 'center' }}> <Typography
color="text.secondary"
sx={{
p: "3vw",
textAlign: "center",
color: "white",
fontFamily: "Unbounded",
}}
>
Предпросмотр фото Предпросмотр фото
</Typography> </Typography>
)} )}
@ -696,13 +774,16 @@ const Personal = () => {
</Grid> </Grid>
</Grid> </Grid>
</DialogContent> </DialogContent>
<DialogActions sx={{ p: 2, bgcolor: '#f5f5f5' }}> <DialogActions sx={{ p: "1vw", bgcolor: "#f5f5f5" }}>
<Button <Button
onClick={handleCloseDialogs} onClick={handleCloseDialogs}
sx={{ sx={{
color: '#666', color: "black",
borderRadius: 2, fontFamily: "Unbounded",
px: 3 borderRadius: "1vw",
px: "1vw",
"&:hover": { bgcolor: "transparent", color: "#C27664" },
transition: "all 0.2s ease",
}} }}
> >
Отмена Отмена
@ -714,8 +795,9 @@ const Personal = () => {
sx={{ sx={{
bgcolor: "#C27664", bgcolor: "#C27664",
color: "white", color: "white",
borderRadius: 2, fontFamily: "Unbounded",
px: 3, borderRadius: isMobile ? "5vw" : "1vw",
px: isMobile ? "4vw" : "2vw",
"&:hover": { bgcolor: "#945B4D" }, "&:hover": { bgcolor: "#945B4D" },
"&.Mui-disabled": { "&.Mui-disabled": {
bgcolor: "rgba(194, 118, 100, 0.5)", bgcolor: "rgba(194, 118, 100, 0.5)",
@ -734,66 +816,75 @@ const Personal = () => {
maxWidth="md" maxWidth="md"
fullWidth fullWidth
PaperProps={{ PaperProps={{
sx: { borderRadius: 2 } sx: { borderRadius: isMobile ? "5vw" : "1vw" }
}} }}
> >
<DialogTitle sx={{ <DialogTitle sx={{
fontFamily: 'Unbounded', fontFamily: "Unbounded",
bgcolor: '#2D2D2D', bgcolor: "#2D2D2D",
color: 'white', color: "white",
display: 'flex', display: "flex",
alignItems: 'center', alignItems: "center",
gap: 1 gap: "1vw"
}}> }}>
<EditIcon /> Редактировать сотрудника <EditIcon /> Редактировать сотрудника
</DialogTitle> </DialogTitle>
<DialogContent sx={{ mt: 2 }}> <DialogContent sx={{ mt: isMobile ? "3vw" : "1vw" }}>
<Grid container spacing={3}> <Grid container spacing={3}>
<Grid item xs={12} md={6}> <Grid
item
xs={12}
md={6}
style={{
display: isMobile ? "block" : "grid",
gridTemplateColumns: isMobile ? "auto" : "repeat(1, 1fr)",
gap: "1vw",
}}
>
<TextField <TextField
name="name" name="name"
label="Имя" placeholder="Имя"
value={formData.name} value={formData.name}
onChange={handleInputChange} onChange={handleInputChange}
fullWidth fullWidth
margin="normal"
variant="outlined" variant="outlined"
sx={textFieldStyles}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
<PersonIcon color="action" /> <PersonIcon sx={{ color: "#C27664", fontSize: isMobile ? "5vw" : "2vw" }} />
</InputAdornment> </InputAdornment>
), ),
}} }}
/> />
<TextField <TextField
name="surname" name="surname"
label="Фамилия" placeholder="Фамилия"
value={formData.surname} value={formData.surname}
onChange={handleInputChange} onChange={handleInputChange}
fullWidth fullWidth
margin="normal"
variant="outlined" variant="outlined"
sx={textFieldStyles}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
<BadgeIcon color="action" /> <BadgeIcon sx={{ color: "#C27664", fontSize: isMobile ? "5vw" : "2vw" }} />
</InputAdornment> </InputAdornment>
), ),
}} }}
/> />
<TextField <TextField
name="role" name="role"
label="Должность" placeholder="Должность"
value={formData.role} value={formData.role}
onChange={handleInputChange} onChange={handleInputChange}
fullWidth fullWidth
margin="normal"
variant="outlined" variant="outlined"
sx={textFieldStyles}
InputProps={{ InputProps={{
startAdornment: ( startAdornment: (
<InputAdornment position="start"> <InputAdornment position="start">
<WorkIcon color="action" /> <WorkIcon sx={{ color: "#C27664", fontSize: isMobile ? "5vw" : "2vw" }} />
</InputAdornment> </InputAdornment>
), ),
}} }}
@ -802,15 +893,18 @@ const Personal = () => {
variant="outlined" variant="outlined"
component="label" component="label"
sx={{ sx={{
mt: 2, borderRadius: isMobile ? "5vw" : "1vw",
borderRadius: 2, p: isMobile ? "2vw" : "1vw",
p: 1.5, borderColor: "#C27664",
borderColor: '#C27664', fontFamily: "Unbounded",
color: '#C27664', color: "#C27664",
'&:hover': { fontSize: isMobile ? "3vw" : "1.2vw",
borderColor: '#945B4D', "&:hover": {
bgcolor: 'rgba(194, 118, 100, 0.1)' borderColor: "#945B4D",
} bgcolor: "#C27664",
color: "white",
},
transition: "all 0.2s ease",
}} }}
fullWidth fullWidth
> >
@ -827,13 +921,14 @@ const Personal = () => {
<Paper <Paper
elevation={2} elevation={2}
sx={{ sx={{
height: '100%', height: "100%",
display: 'flex', display: "flex",
alignItems: 'center', alignItems: "center",
justifyContent: 'center', justifyContent: "center",
borderRadius: 2, borderRadius: "1vw",
overflow: 'hidden', overflow: "hidden",
bgcolor: '#f5f5f5' bgcolor: "#2D2D2D",
boxShadow: "0 0.5vw 1vw rgba(0,0,0,0.15)",
}} }}
> >
{photoPreview ? ( {photoPreview ? (
@ -842,14 +937,24 @@ const Personal = () => {
src={photoPreview} src={photoPreview}
alt="Предпросмотр" alt="Предпросмотр"
sx={{ sx={{
width: '100%', width: "100%",
height: '100%', height: "100%",
objectFit: 'contain', objectFit: "contain",
p: 2 p: "1vw",
userSelect: "none",
pointerEvents: "none",
}} }}
/> />
) : ( ) : (
<Typography color="text.secondary" sx={{ p: 4, textAlign: 'center' }}> <Typography
color="text.secondary"
sx={{
p: "3vw",
textAlign: "center",
color: "white",
fontFamily: "Unbounded",
}}
>
Предпросмотр фото Предпросмотр фото
</Typography> </Typography>
)} )}
@ -857,13 +962,16 @@ const Personal = () => {
</Grid> </Grid>
</Grid> </Grid>
</DialogContent> </DialogContent>
<DialogActions sx={{ p: 2, bgcolor: '#f5f5f5' }}> <DialogActions sx={{ p: "1vw", bgcolor: "#f5f5f5" }}>
<Button <Button
onClick={handleCloseDialogs} onClick={handleCloseDialogs}
sx={{ sx={{
color: '#666', color: "black",
borderRadius: 2, fontFamily: "Unbounded",
px: 3 borderRadius: "1vw",
px: "1vw",
"&:hover": { bgcolor: "transparent", color: "#C27664" },
transition: "all 0.2s ease",
}} }}
> >
Отмена Отмена
@ -875,8 +983,9 @@ const Personal = () => {
sx={{ sx={{
bgcolor: "#C27664", bgcolor: "#C27664",
color: "white", color: "white",
borderRadius: 2, fontFamily: "Unbounded",
px: 3, borderRadius: isMobile ? "5vw" : "1vw",
px: isMobile ? "4vw" : "2vw",
"&:hover": { bgcolor: "#945B4D" }, "&:hover": { bgcolor: "#945B4D" },
"&.Mui-disabled": { "&.Mui-disabled": {
bgcolor: "rgba(194, 118, 100, 0.5)", bgcolor: "rgba(194, 118, 100, 0.5)",
@ -893,57 +1002,61 @@ const Personal = () => {
open={openDeleteDialog} open={openDeleteDialog}
onClose={handleCloseDialogs} onClose={handleCloseDialogs}
PaperProps={{ PaperProps={{
sx: { borderRadius: 2 } sx: { borderRadius: isMobile ? "5vw" : "1vw", maxWidth: isMobile ? "80vw" : "40vw", overflow: "hidden" }
}} }}
> >
<DialogTitle sx={{ <DialogTitle sx={{
fontFamily: 'Unbounded', fontFamily: "Unbounded",
bgcolor: '#2D2D2D', bgcolor: "#2D2D2D",
color: 'white', color: "white",
display: 'flex', display: "flex",
alignItems: 'center', alignItems: "center",
gap: 1 gap: "1vw"
}}> }}>
<DeleteIcon /> Удалить сотрудника <DeleteIcon /> Удалить сотрудника
</DialogTitle> </DialogTitle>
<DialogContent sx={{ mt: 2, minWidth: 400 }}> <DialogContent sx={{ mt: isMobile ? "3vw" : "1vw" }}>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}> <Box sx={{ display: "flex", alignItems: "center", mb: isMobile ? "3vw" : "1vw", flexDirection: isMobile ? "column" : "row" }}>
{selectedMember && ( {selectedMember && (
<Avatar <Avatar
src={getImageUrl(selectedMember.photo)} src={getImageUrl(selectedMember.photo)}
alt={`${selectedMember.name} ${selectedMember.surname}`} alt={`${selectedMember.name} ${selectedMember.surname}`}
sx={{ sx={{
width: 64, width: isMobile ? "20vw" : "5vw",
height: 64, height: isMobile ? "20vw" : "5vw",
mr: 2 mr: isMobile ? "0" : "2vw",
mb: isMobile ? "2vw" : "0",
}} }}
> >
{selectedMember && getInitials(selectedMember.name, selectedMember.surname)} {selectedMember && getInitials(selectedMember.name, selectedMember.surname)}
</Avatar> </Avatar>
)} )}
<Box> <Box>
<Typography variant="h6" sx={{ fontWeight: 'bold' }}> <Typography variant="h6" sx={{ fontWeight: "bold", fontFamily: "Unbounded" }}>
{selectedMember?.name} {selectedMember?.surname} {selectedMember?.name} {selectedMember?.surname}
</Typography> </Typography>
{selectedMember && ( {selectedMember && (
<Typography variant="body2" color="text.secondary"> <Typography variant="body2" color="text.secondary" sx={{ fontFamily: "Unbounded" }}>
{selectedMember.role} {selectedMember.role}
</Typography> </Typography>
)} )}
</Box> </Box>
</Box> </Box>
<Alert severity="warning" sx={{ mt: 2 }}> <Alert severity="warning" sx={{ mt: "1vw", fontFamily: "Unbounded", borderRadius: isMobile ? "5vw" : "1vw" }}>
Вы уверены, что хотите удалить этого сотрудника? Это действие нельзя отменить. Вы уверены, что хотите удалить этого сотрудника? Это действие нельзя отменить.
</Alert> </Alert>
</DialogContent> </DialogContent>
<DialogActions sx={{ p: 2, bgcolor: '#f5f5f5' }}> <DialogActions sx={{ p: "1vw", bgcolor: "#f5f5f5" }}>
<Button <Button
onClick={handleCloseDialogs} onClick={handleCloseDialogs}
sx={{ sx={{
color: '#666', color: "black",
borderRadius: 2, borderRadius: "1vw",
px: 3 px: "1vw",
fontFamily: "Unbounded",
"&:hover": { bgcolor: "transparent", color: "#C27664" },
transition: "all 0.2s ease",
}} }}
> >
Отмена Отмена
@ -953,8 +1066,13 @@ const Personal = () => {
variant="contained" variant="contained"
color="error" color="error"
sx={{ sx={{
borderRadius: 2, borderRadius: isMobile ? "5vw" : "1vw",
px: 3 px: isMobile ? "4vw" : "2vw",
fontFamily: "Unbounded",
bgcolor: "#C27664",
color: "white",
"&:hover": { bgcolor: "#945B4D" },
transition: "all 0.2s ease",
}} }}
> >
Удалить Удалить

View File

@ -1877,7 +1877,7 @@ const Vehicle = () => {
> >
<DeleteIcon /> Удалить автомобиль <DeleteIcon /> Удалить автомобиль
</DialogTitle> </DialogTitle>
<DialogContent sx={{ mt: isMobile ? "3vw" : "1vw", minWidth: "40vw" }}> <DialogContent sx={{ mt: isMobile ? "3vw" : "1vw" }}>
<Box sx={{ display: "flex", alignItems: "center", mb: isMobile ? "3vw" : "1vw", flexDirection: isMobile ? "column" : "row" }}> <Box sx={{ display: "flex", alignItems: "center", mb: isMobile ? "3vw" : "1vw", flexDirection: isMobile ? "column" : "row" }}>
{selectedCar && ( {selectedCar && (
<Box <Box