diff --git a/package-lock.json b/package-lock.json
index afb1954..ad1da57 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,6 +14,7 @@
"@mui/material": "^7.2.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
+ "react-icons": "^5.5.0",
"react-imask": "^7.6.1",
"react-router-dom": "^7.6.3"
},
@@ -3547,6 +3548,15 @@
"react": "^19.1.0"
}
},
+ "node_modules/react-icons": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-5.5.0.tgz",
+ "integrity": "sha512-MEFcXdkP3dLo8uumGI5xN3lDFNsRtrjbOEKDLD7yv76v4wpnEq2Lt2qeHaQOr34I/wPN3s3+N08WkQ+CW37Xiw==",
+ "license": "MIT",
+ "peerDependencies": {
+ "react": "*"
+ }
+ },
"node_modules/react-imask": {
"version": "7.6.1",
"resolved": "https://registry.npmjs.org/react-imask/-/react-imask-7.6.1.tgz",
diff --git a/package.json b/package.json
index f74a6ad..8df1524 100644
--- a/package.json
+++ b/package.json
@@ -16,6 +16,7 @@
"@mui/material": "^7.2.0",
"react": "^19.1.0",
"react-dom": "^19.1.0",
+ "react-icons": "^5.5.0",
"react-imask": "^7.6.1",
"react-router-dom": "^7.6.3"
},
diff --git a/src/assets/icon/autobro.png b/src/assets/icon/autobro.png
index fbe2db4..60cd662 100644
Binary files a/src/assets/icon/autobro.png and b/src/assets/icon/autobro.png differ
diff --git a/src/assets/icon/autobro_old.png b/src/assets/icon/autobro_old.png
new file mode 100644
index 0000000..fbe2db4
Binary files /dev/null and b/src/assets/icon/autobro_old.png differ
diff --git a/src/components/Header.tsx b/src/components/Header.tsx
index 38aa113..e6aa035 100644
--- a/src/components/Header.tsx
+++ b/src/components/Header.tsx
@@ -72,7 +72,7 @@ const Header = () => {
display: "flex",
justifyContent: "center",
alignItems: "center",
- height: isMobile ? "15vw" : "10vw",
+ height: isMobile ? "15vw" : "5vw",
gap: "2vw",
fontFamily: "Unbounded",
bgcolor: "#2D2D2D",
@@ -95,7 +95,8 @@ const Header = () => {
onClick={() => handleScrollToAnchor("#main")}
sx={{
width: isMobile ? "17vw" : "9vw",
- height: isMobile ? "17vw" : "9vw",
+ height: isMobile ? "6vw" : "2.8vw",
+ mb: "0.5vw",
cursor: "pointer",
"&:hover": { scale: 1.1 },
transition: "all 0.4s ease",
@@ -152,7 +153,7 @@ const Header = () => {
{/* Пустой блок для компенсации фиксированного хедера */}
-
+
{/* Мобильное меню */}
diff --git a/src/pages/CalculatorPage.tsx b/src/pages/CalculatorPage.tsx
index 39439df..ad3910e 100644
--- a/src/pages/CalculatorPage.tsx
+++ b/src/pages/CalculatorPage.tsx
@@ -1,4 +1,4 @@
-import React, { useState } from "react";
+import React, { useState, useEffect } from "react";
import {
Box,
Typography,
@@ -10,17 +10,25 @@ import {
FormControlLabel,
Radio,
InputAdornment,
+ Collapse,
+ Paper,
} from "@mui/material";
import { useResponsive } from "../theme/useResponsive";
import russia from "../assets/emoji/russia.png";
import belarus from "../assets/emoji/belarus.png";
+import {
+ fetchCurrencyRates,
+ getCurrencyRate,
+ mapCurrencyCodeToApiCode,
+ type CurrencyRatesResponse,
+} from "../utils/currencyService";
function CalculatorPage() {
const { isMobile } = useResponsive();
// Состояния для полей формы
const [country, setCountry] = useState("russia"); // russia или belarus
- const [age, setAge] = useState("Новые, не менее 3-х лет");
+ const [age, setAge] = useState("3"); // Изменено на числовое значение для упрощения расчетов
const [price, setPrice] = useState("");
const [currency, setCurrency] = useState("USD Доллар США");
const [engineType, setEngineType] = useState("Бензиновый");
@@ -29,34 +37,286 @@ function CalculatorPage() {
const [enginePower, setEnginePower] = useState("");
const [enginePowerUnit, setEnginePowerUnit] = useState("л.с.");
const [electricMotorPower, setElectricMotorPower] = useState("");
- const [electricMotorPowerUnit, setElectricMotorPowerUnit] = useState("л.с.");
+ const [electricMotorPowerUnit, setElectricMotorPowerUnit] = useState("кВт");
const [powerRatio, setPowerRatio] = useState("ДВС > ЭД");
const [calculationType, setCalculationType] = useState("Физ. лица");
const [enhancedPermeability, setEnhancedPermeability] = useState(false);
+ // Состояние для курсов валют
+ const [currencyRates, setCurrencyRates] =
+ useState(null);
+ const [isLoading, setIsLoading] = useState(false);
+
+ // Состояния для результатов расчета
+ const [calculationResults, setCalculationResults] = useState<{
+ priceInRub: string;
+ customDuty: string;
+ exciseTax: string;
+ vat: string;
+ utilityFee: string;
+ totalFees: string;
+ totalWithCar: string;
+ } | null>(null);
+
+ // Получение курсов валют при монтировании компонента
+ useEffect(() => {
+ const loadCurrencyRates = async () => {
+ setIsLoading(true);
+ try {
+ const rates = await fetchCurrencyRates();
+ setCurrencyRates(rates);
+ } catch (error) {
+ console.error("Не удалось загрузить курсы валют:", error);
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ 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;
+
+ // Для авто менее 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;
+ let powerInHP = enginePowerNum;
+
+ if (enginePowerUnit === "кВт") {
+ powerInHP = enginePowerNum * 1.35962;
+ }
+
+ // Акцизные ставки на 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 === "Электрический") {
+ 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);
+
+ // Выводим результаты также в консоль для отладки
console.log({
- country,
- age,
- price,
- currency,
- engineType,
- hybridType,
- engineVolume,
- enginePower,
- enginePowerUnit,
- electricMotorPower,
- electricMotorPowerUnit,
- powerRatio,
- calculationType,
- enhancedPermeability,
+ original: {
+ price,
+ currency,
+ currencyRate: exchangeRate,
+ country,
+ age,
+ engineType,
+ hybridType,
+ engineVolume,
+ enginePower,
+ enginePowerUnit,
+ electricMotorPower,
+ electricMotorPowerUnit,
+ powerRatio,
+ calculationType,
+ enhancedPermeability,
+ },
+ calculation: results,
});
};
+ // Функция для получения символа валюты
+ const getCurrencySymbol = () => {
+ switch (currency) {
+ case "USD Доллар США":
+ return "$";
+ case "EUR Евро":
+ return "€";
+ case "CNY Юань":
+ return "¥";
+ case "RUB Рубль":
+ return "₽";
+ default:
+ return "₽";
+ }
+ };
+
+ // Функция для определения видимости полей в зависимости от типа двигателя
+ const isEngineVolumeVisible = engineType !== "Электрический";
+ const isEngineICEPowerVisible = engineType !== "Электрический";
+ const isElectricMotorPowerVisible =
+ engineType === "Электрический" || engineType === "Гибридный";
+ const isHybridTypeVisible = engineType === "Гибридный";
+ const isPowerRatioVisible = engineType === "Гибридный";
+
return (
+ {isMobile && (
+
+
+ РАСЧИТАЙТЕ{" "}
+ СТОИМОСТЬ ДОСТАВКИ!
+
+
+
+ С помощью калькулятора
+ таможенных платежей за
+ автомобиль
+
+
+
+
+ Обсуждаем ваш запрос и бюджет, подбираем варианты. Заключаем
+ договор и вносим аванс (100 000 P, возвращается, если не
+ подберем авто).
+
+
+ Выкупаем авто
+
+
+ Оформляем документы и доставляем авто в РФ. На всех этапах
+ машина застрахована.
+
+
+ Проходим таможню, делаем документы для регистрации.
+
+
+ Передаём авто вам - с актом и финальной оплатой.
+
+
+
+ )}
{/* Левая часть - форма */}
{/* Первая линия */}
-
+
Рассчитать для
-
-
+ setCountry("russia")}
sx={{ cursor: "pointer", position: "relative" }}
>
@@ -106,17 +473,17 @@ function CalculatorPage() {
checked={country === "russia"}
sx={{ position: "absolute", opacity: 0 }}
/>
-
- setCountry("belarus")}
sx={{ cursor: "pointer", position: "relative" }}
>
@@ -124,12 +491,12 @@ function CalculatorPage() {
checked={country === "belarus"}
sx={{ position: "absolute", opacity: 0 }}
/>
-
@@ -137,58 +504,73 @@ function CalculatorPage() {
+
+
{/* Вторая линия */}
-
+
Возраст
- {/* setAge(e.target.value)}
- variant="outlined"
- placeholder="Новые, не менее 3-х лет"
+ displayEmpty
sx={{
- "& .MuiOutlinedInput-root": {
- borderRadius: "25px",
- bgcolor: "white",
- height: "40px",
- }
- }}
- /> */}
-
+ },
+ }}
+ >
+
+
+
+
{/* Третья линия */}
-
+
setPrice(e.target.value)}
variant="outlined"
InputProps={{
- endAdornment: ₽,
+ endAdornment: (
+
+ {getCurrencySymbol()}
+
+ ),
}}
sx={{
"& .MuiOutlinedInput-root": {
- borderRadius: "2vw",
+ borderRadius: isMobile ? "5vw" : "2vw",
bgcolor: "white",
- height: "3.5vw",
- width: "83%",
+ height: isMobile ? "4.5vw" : "2vw",
+ width: "100%",
border: "0.1vw solid #C27664",
fontFamily: "Unbounded",
- fontSize: "1.5vw",
+ fontSize: isMobile ? "2.5vw" : "1.2vw",
color: "#C27664",
- "& fieldset": {
- border: "none"
+ "& fieldset": {
+ border: "none",
},
- }
+ },
}}
/>
@@ -220,65 +618,67 @@ function CalculatorPage() {
onChange={(e) => setCurrency(e.target.value as string)}
displayEmpty
sx={{
- borderRadius: "2vw",
+ borderRadius: isMobile ? "5vw" : "2vw",
bgcolor: "white",
- height: "3.5vw",
- width: "83%",
+ height: isMobile ? "4.5vw" : "2vw",
+ width: "100%",
border: "0.1vw solid #C27664",
fontFamily: "Unbounded",
- fontSize: "1.5vw",
+ fontSize: isMobile ? "2.5vw" : "1.2vw",
color: "#C27664",
"& .MuiOutlinedInput-notchedOutline": {
- border: "none"
- }
+ border: "none",
+ },
+ "& .MuiSvgIcon-root": {
+ fontSize: isMobile ? "5vw" : "2vw",
+ color: "#C27664",
+ },
}}
>
-
-
-
+
+
+
+
- {/*
-
- */}
- {/* Четвертая линия - Валюта */}
- {/*
-
-
-
- */}
-
{/* Пятая линия */}
-
+
setEngineType(e.target.value as string)}
displayEmpty
sx={{
- borderRadius: "2vw",
+ borderRadius: isMobile ? "5vw" : "2vw",
bgcolor: "white",
- height: "3.5vw",
- width: "75%",
+ height: isMobile ? "4.5vw" : "2vw",
+ width: "100%",
border: "0.1vw solid #C27664",
fontFamily: "Unbounded",
- fontSize: "1.5vw",
+ fontSize: isMobile ? "2.5vw" : "1.2vw",
color: "#C27664",
"& .MuiOutlinedInput-notchedOutline": {
- border: "none"
- }
+ border: "none",
+ },
+ "& .MuiSvgIcon-root": {
+ fontSize: isMobile ? "5vw" : "2vw",
+ color: "#C27664",
+ },
}}
>
@@ -312,298 +716,370 @@ function CalculatorPage() {
- {/* Шестая линия */}
-
-
+
- Тип гибрида
-
-
-
-
-
+ Тип гибрида
+
+
+
+
+
+
- {/* Седьмая линия */}
-
- setEngineVolume(e.target.value)}
- variant="outlined"
+ {/* Седьмая линия - Объем двигателя */}
+
+
-
- см³
-
-
-
- {/* Восьмая линия */}
-
- setEnginePower(e.target.value)}
- variant="outlined"
- sx={{
- "& .MuiOutlinedInput-root": {
- borderRadius: "2vw",
- bgcolor: "white",
- height: "3.5vw",
- width: "98%",
- border: "0.1vw solid #C27664",
- fontFamily: "Unbounded",
- fontSize: "1.4vw",
- color: "#C27664",
- "& fieldset": {
- border: "none"
+ setEngineVolume(e.target.value)}
+ variant="outlined"
+ sx={{
+ "& .MuiOutlinedInput-root": {
+ borderRadius: isMobile ? "5vw" : "2vw",
+ bgcolor: "white",
+ height: isMobile ? "4.5vw" : "2vw",
+ width: "100%",
+ border: "0.1vw solid #C27664",
+ fontFamily: "Unbounded",
+ fontSize: isMobile ? "2.5vw" : "1.2vw",
+ color: "#C27664",
+ "& fieldset": {
+ border: "none",
+ },
},
- }
- }}
- />
-
- setEnginePowerUnit("л.с.")}
- sx={{
- color: "#C27664",
- "&.Mui-checked": { color: "#C27664" },
- "& .MuiSvgIcon-root": {
- fontSize: "1.5vw"
- }
- }}
- />
- }
- label="л.с."
- sx={{
- "& .MuiFormControlLabel-label": {
- fontSize: "2vw",
- fontFamily: "Unbounded",
- color: "#C27664",
- }
}}
/>
- setEnginePowerUnit("кВт")}
- sx={{
- color: "#C27664",
- "&.Mui-checked": { color: "#C27664" },
- "& .MuiSvgIcon-root": {
- fontSize: "1.5vw"
- }
- }}
- />
- }
- label="кВт"
- sx={{
- "& .MuiFormControlLabel-label": {
- fontSize: "2vw",
- fontFamily: "Unbounded",
- color: "#C27664",
- }
- }}
- />
-
-
-
- {/* Девятая линия */}
-
- setElectricMotorPower(e.target.value)}
- variant="outlined"
- sx={{
- "& .MuiOutlinedInput-root": {
- borderRadius: "2vw",
- bgcolor: "white",
- height: "3.5vw",
- width: "112%",
- border: "0.1vw solid #C27664",
+
-
- setElectricMotorPowerUnit("л.с.")}
- sx={{
- color: "#C27664",
- "&.Mui-checked": { color: "#C27664" },
- "& .MuiSvgIcon-root": {
- fontSize: "1.5vw"
- }
- }}
- />
- }
- label="л.с."
- sx={{
- "& .MuiFormControlLabel-label": {
- fontSize: "2vw",
- fontFamily: "Unbounded",
- color: "#C27664",
- }
}}
- />
- setElectricMotorPowerUnit("кВт")}
- sx={{
- color: "#C27664",
- "&.Mui-checked": { color: "#C27664" },
- "& .MuiSvgIcon-root": {
- fontSize: "1.5vw"
- }
- }}
- />
- }
- label="кВт"
- sx={{
- "& .MuiFormControlLabel-label": {
- fontSize: "2vw",
- fontFamily: "Unbounded",
- color: "#C27664",
- }
- }}
- />
+ >
+ см³
+
-
+
- {/* Десятая линия */}
-
-
+
- ДВС vs ЭД
-
-
- ЭД"}
- onChange={() => setPowerRatio("ДВС > ЭД")}
- sx={{
- color: "#C27664",
- "&.Mui-checked": { color: "#C27664" },
- }}
- />
- }
- label="ДВС > ЭД"
- sx={{
- "& .MuiFormControlLabel-label": {
- fontSize: "1.7vw",
+ setEnginePower(e.target.value)}
+ variant="outlined"
+ sx={{
+ "& .MuiOutlinedInput-root": {
+ borderRadius: isMobile ? "5vw" : "2vw",
+ bgcolor: "white",
+ height: isMobile ? "4.5vw" : "2vw",
+ width: "100%",
+ border: "0.1vw solid #C27664",
fontFamily: "Unbounded",
+ fontSize: isMobile ? "2.5vw" : "1.2vw",
color: "#C27664",
- }
+ "& fieldset": {
+ border: "none",
+ },
+ },
}}
/>
- setPowerRatio("ДВС < ЭД")}
- sx={{
- color: "#C27664",
- "&.Mui-checked": { color: "#C27664" },
- }}
- />
- }
- label="ДВС < ЭД"
- sx={{
- "& .MuiFormControlLabel-label": {
- fontSize: "1.7vw",
- fontFamily: "Unbounded",
- color: "#C27664",
- }
+
+ >
+ setEnginePowerUnit("л.с.")}
+ sx={{
+ color: "#C27664",
+ "&.Mui-checked": { color: "#C27664" },
+ "& .MuiSvgIcon-root": {
+ fontSize: isMobile ? "5vw" : "1.8vw",
+ },
+ }}
+ />
+ }
+ label="л.с."
+ sx={{
+ "& .MuiFormControlLabel-label": {
+ fontSize: isMobile ? "2.5vw" : "2vw",
+ fontFamily: "Unbounded",
+ color: "#C27664",
+ },
+ }}
+ />
+ setEnginePowerUnit("кВт")}
+ sx={{
+ color: "#C27664",
+ "&.Mui-checked": { color: "#C27664" },
+ "& .MuiSvgIcon-root": {
+ fontSize: isMobile ? "5vw" : "1.8vw",
+ },
+ }}
+ />
+ }
+ label="кВт"
+ sx={{
+ "& .MuiFormControlLabel-label": {
+ fontSize: isMobile ? "3vw" : "2vw",
+ fontFamily: "Unbounded",
+ color: "#C27664",
+ },
+ }}
+ />
+
-
+
+
+ {/* Девятая линия - Мощность электродвигателя */}
+
+
+ setElectricMotorPower(e.target.value)}
+ variant="outlined"
+ sx={{
+ "& .MuiOutlinedInput-root": {
+ borderRadius: isMobile ? "5vw" : "2vw",
+ bgcolor: "white",
+ height: isMobile ? "4.5vw" : "2vw",
+ width: "100%",
+ border: "0.1vw solid #C27664",
+ fontFamily: "Unbounded",
+ fontSize: isMobile ? "3vw" : "1.2vw",
+ color: "#C27664",
+ "& fieldset": {
+ border: "none",
+ },
+ },
+ }}
+ />
+
+ кВт
+
+
+ =
+
+
+ {electricMotorPower
+ ? `${(parseFloat(electricMotorPower) * 1.35962).toFixed(
+ 1
+ )} л.с.`
+ : "0 л.с."}
+
+
+
+
+ {/* Десятая линия - ДВС vs ЭД */}
+
+
+
+ {isMobile ? "Мощность ДВС vs ЭД" : "ДВС vs ЭД"}
+
+
+ ЭД"}
+ onChange={() => setPowerRatio("ДВС > ЭД")}
+ sx={{
+ color: "#C27664",
+ "&.Mui-checked": { color: "#C27664" },
+ "& .MuiSvgIcon-root": {
+ fontSize: isMobile ? "5vw" : "1.8vw",
+ },
+ }}
+ />
+ }
+ label="ДВС > ЭД"
+ sx={{
+ "& .MuiFormControlLabel-label": {
+ fontSize: isMobile ? "3vw" : "1.3vw",
+ fontFamily: "Unbounded",
+ color: "#C27664",
+ },
+ }}
+ />
+ setPowerRatio("ДВС < ЭД")}
+ sx={{
+ color: "#C27664",
+ "&.Mui-checked": { color: "#C27664" },
+ "& .MuiSvgIcon-root": {
+ fontSize: isMobile ? "5vw" : "1.8vw",
+ },
+ }}
+ />
+ }
+ label="ДВС < ЭД"
+ sx={{
+ "& .MuiFormControlLabel-label": {
+ fontSize: isMobile ? "3vw" : "1.3vw",
+ fontFamily: "Unbounded",
+ color: "#C27664",
+ },
+ }}
+ />
+
+
+
{/* Одиннадцатая линия */}
-
+
@@ -636,25 +1116,38 @@ function CalculatorPage() {
{/* Двенадцатая линия */}
-
+
setEnhancedPermeability(!enhancedPermeability)}
+ onChange={() =>
+ setEnhancedPermeability(!enhancedPermeability)
+ }
sx={{
color: "#C27664",
"&.Mui-checked": { color: "#C27664" },
+ "& .MuiSvgIcon-root": {
+ fontSize: isMobile ? "5vw" : "2vw",
+ },
}}
/>
}
label="Повышенной проходимости"
- sx={{
+ sx={{
"& .MuiFormControlLabel-label": {
- fontSize: "2vw",
+ fontSize: isMobile ? "3vw" : "1.5vw",
color: "#C27664",
fontFamily: "Unbounded",
- }
+ },
}}
/>
@@ -665,13 +1158,13 @@ function CalculatorPage() {
variant="contained"
onClick={handleCalculate}
sx={{
- maxWidth: "30vw",
+ maxWidth: isMobile ? "50vw" : "30vw",
bgcolor: "#C27664",
color: "white",
- fontSize: "2vw",
- padding: "1vw",
+ fontSize: isMobile ? "3.5vw" : "2vw",
+ padding: isMobile ? "2vw" : "1vw",
textTransform: "none",
- borderRadius: "3vw",
+ borderRadius: isMobile ? "5vw" : "3vw",
fontFamily: "Unbounded",
position: "relative",
left: "50%",
@@ -682,86 +1175,331 @@ function CalculatorPage() {
Рассчитать
+ {/* Блок с результатами расчета */}
+ {calculationResults && (
+
+
+ Результаты расчета:
+
+
+
+
+
+
+ Стоимость авто:
+
+
+ {Number(calculationResults.priceInRub).toLocaleString(
+ "ru-RU"
+ )}{" "}
+ ₽
+
+
+
+
+
+ Таможенная пошлина:
+
+
+ {Number(calculationResults.customDuty).toLocaleString(
+ "ru-RU"
+ )}{" "}
+ ₽
+
+
+
+
+
+ Акциз:
+
+
+ {Number(calculationResults.exciseTax).toLocaleString(
+ "ru-RU"
+ )}{" "}
+ ₽
+
+
+
+
+
+ НДС:
+
+
+ {Number(calculationResults.vat).toLocaleString("ru-RU")} ₽
+
+
+
+
+
+ Утилизационный сбор:
+
+
+ {Number(calculationResults.utilityFee).toLocaleString(
+ "ru-RU"
+ )}{" "}
+ ₽
+
+
+
+
+
+
+
+
+
+
+ Всего таможенных платежей:
+
+
+
+
+ {Number(calculationResults.totalFees).toLocaleString("ru-RU")}{" "}
+ ₽
+
+
+
+
+
+ Итоговая стоимость с авто:
+
+
+
+
+ {Number(calculationResults.totalWithCar).toLocaleString(
+ "ru-RU"
+ )}{" "}
+ ₽
+
+
+
+
+ )}
{/* Правая часть - описание */}
-
-
- РАСЧИТАЙТЕ СТОИМОСТЬ ДОСТАВКИ!
-
+
+ РАСЧИТАЙТЕ{" "}
+ СТОИМОСТЬ ДОСТАВКИ!
+
-
- С помощью калькулятора таможенных платежей за автомобиль
-
+
+ С помощью калькулятора
+ таможенных платежей за
+ автомобиль
+
-
-
- Обсуждаем ваш запрос и бюджет, подбираем варианты. Заключаем договор и вносим аванс (100 000 P, возвращается, если не подберем авто).
-
-
- Выкупаем авто
-
-
- Оформляем документы и доставляем авто в РФ. На всех этапах машина застрахована.
-
-
- Проходим таможню, делаем документы для регистрации.
-
-
- Передаём авто вам - с актом и финальной оплатой.
-
+
+ Обсуждаем ваш запрос и бюджет, подбираем варианты. Заключаем
+ договор и вносим аванс (100 000 P, возвращается, если не
+ подберем авто).
+
+
+ Выкупаем авто
+
+
+ Оформляем документы и доставляем авто в РФ. На всех этапах
+ машина застрахована.
+
+
+ Проходим таможню, делаем документы для регистрации.
+
+
+ Передаём авто вам - с актом и финальной оплатой.
+
+
-
+ )}
);
diff --git a/src/pages/DeliveryPage.tsx b/src/pages/DeliveryPage.tsx
index 4bde7b2..82603a9 100644
--- a/src/pages/DeliveryPage.tsx
+++ b/src/pages/DeliveryPage.tsx
@@ -47,27 +47,45 @@ function DeliveryPage() {
fontSize: isMobile ? "6vw" : "4vw",
fontWeight: "bold",
marginBottom: "1vw",
- maxWidth: isMobile ? "auto" :"50vw",
+ maxWidth: isMobile ? "auto" : "50vw",
}}
>
Мы доставляем автомобили из{" "}
США, Китая и Кореи
-
+
@@ -82,7 +100,7 @@ function DeliveryPage() {
top: isMobile ? "0vw" : "-29vw",
left: isMobile ? "50%" : "56vw",
transform: isMobile ? "translateX(-50%)" : "none",
- borderRadius: "3vw",
+ borderRadius: isMobile ? "5vw" : "3vw",
border: "0.3vw solid #C27664",
}}
>
diff --git a/src/utils/currencyService.ts b/src/utils/currencyService.ts
new file mode 100644
index 0000000..e83ce81
--- /dev/null
+++ b/src/utils/currencyService.ts
@@ -0,0 +1,63 @@
+// Интерфейсы для данных от CBR XML Daily API
+export interface CurrencyRate {
+ ID: string;
+ NumCode: string;
+ CharCode: string;
+ Nominal: number;
+ Name: string;
+ Value: number;
+ Previous: number;
+}
+
+export interface CurrencyRatesResponse {
+ Date: string;
+ PreviousDate: string;
+ PreviousURL: string;
+ Timestamp: string;
+ Valute: {
+ [key: string]: CurrencyRate;
+ };
+}
+
+// Получение курсов валют с API cbr-xml-daily.ru
+export const fetchCurrencyRates = async (): Promise => {
+ try {
+ const response = await fetch('https://www.cbr-xml-daily.ru/daily_json.js');
+
+ if (!response.ok) {
+ throw new Error(`Ошибка HTTP: ${response.status}`);
+ }
+
+ return await response.json();
+ } catch (error) {
+ console.error('Ошибка при получении курсов валют:', error);
+ throw error;
+ }
+};
+
+// Функция для получения курса конкретной валюты (USD, EUR, CNY)
+export const getCurrencyRate = (rates: CurrencyRatesResponse | null, code: string): number => {
+ if (!rates || !rates.Valute || !rates.Valute[code]) {
+ // Резервные значения на случай недоступности API
+ const fallbackRates: Record = {
+ USD: 93,
+ EUR: 101,
+ CNY: 12.8
+ };
+ return fallbackRates[code] || 1;
+ }
+
+ return rates.Valute[code].Value;
+};
+
+// Преобразование кода валюты из пользовательского формата в формат API
+export const mapCurrencyCodeToApiCode = (userCurrency: string): string => {
+ const currencyMap: Record = {
+ "USD Доллар США": "USD",
+ "EUR Евро": "EUR",
+ "CNY Юань": "CNY",
+ "RUB Рубль": "RUB"
+ };
+
+ return currencyMap[userCurrency] || userCurrency;
+};
\ No newline at end of file
diff --git a/src/utils/scrollUtils.ts b/src/utils/scrollUtils.ts
index 3c03451..4d705b0 100644
--- a/src/utils/scrollUtils.ts
+++ b/src/utils/scrollUtils.ts
@@ -12,7 +12,7 @@ export const scrollToAnchor = (
const element = document.querySelector(anchor);
if (element) {
// Получаем высоту хедера (в соответствии с размерами в Header.tsx)
- const headerHeight = isMobile ? window.innerWidth * 0.15 : window.innerWidth * 0.10; // 15vw или 10vw
+ const headerHeight = isMobile ? window.innerWidth * 0.15 : window.innerWidth * 0.05; // 15vw или 10vw
// Получаем позицию элемента относительно верха страницы
const elementPosition = element.getBoundingClientRect().top + window.scrollY;