calculator(worked)

This commit is contained in:
aurinex
2025-07-10 17:23:04 +05:00
parent b88a2c4940
commit 1f6efd2def
9 changed files with 1315 additions and 484 deletions

10
package-lock.json generated
View File

@ -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",

View File

@ -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"
},

Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

View File

@ -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 = () => {
</Box>
{/* Пустой блок для компенсации фиксированного хедера */}
<Box sx={{ height: isMobile ? "15vw" : "10vw" }} />
<Box sx={{ height: isMobile ? "15vw" : "5vw" }} />
{/* Мобильное меню */}
<Drawer anchor="right" open={drawerOpen} onClose={toggleDrawer(false)}>

File diff suppressed because it is too large Load Diff

View File

@ -47,27 +47,45 @@ function DeliveryPage() {
fontSize: isMobile ? "6vw" : "4vw",
fontWeight: "bold",
marginBottom: "1vw",
maxWidth: isMobile ? "auto" :"50vw",
maxWidth: isMobile ? "auto" : "50vw",
}}
>
Мы доставляем автомобили из{" "}
<span style={{ color: "#C27664" }}>США, Китая и Кореи</span>
</Typography>
<Box sx={{ display: "flex", gap: "2vw", justifyContent: isMobile ? "center" : "none" }}>
<Box
sx={{
display: "flex",
gap: "2vw",
justifyContent: isMobile ? "center" : "none",
}}
>
<img
src={usa}
alt="usa"
style={{ width: isMobile ? "20vw" : "10vw", height: isMobile ? "19vw" : "9vw", pointerEvents: "none" }}
style={{
width: isMobile ? "20vw" : "10vw",
height: isMobile ? "19vw" : "9vw",
pointerEvents: "none",
}}
/>
<img
src={china}
alt="china"
style={{ width: isMobile ? "20vw" : "10vw", height: isMobile ? "19vw" : "9vw", pointerEvents: "none" }}
style={{
width: isMobile ? "20vw" : "10vw",
height: isMobile ? "19vw" : "9vw",
pointerEvents: "none",
}}
/>
<img
src={korea}
alt="korea"
style={{ width: isMobile ? "20vw" : "10vw", height: isMobile ? "19vw" : "9vw", pointerEvents: "none" }}
style={{
width: isMobile ? "20vw" : "10vw",
height: isMobile ? "19vw" : "9vw",
pointerEvents: "none",
}}
/>
</Box>
</Box>
@ -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",
}}
>

View File

@ -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<CurrencyRatesResponse> => {
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<string, number> = {
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<string, string> = {
"USD Доллар США": "USD",
"EUR Евро": "EUR",
"CNY Юань": "CNY",
"RUB Рубль": "RUB"
};
return currencyMap[userCurrency] || userCurrency;
};

View File

@ -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;