206 lines
6.0 KiB
TypeScript
206 lines
6.0 KiB
TypeScript
import React, { useState, useEffect } from "react";
|
||
import {
|
||
Box,
|
||
Typography,
|
||
IconButton,
|
||
Drawer,
|
||
List,
|
||
ListItem,
|
||
Button,
|
||
Link,
|
||
} from "@mui/material";
|
||
import MenuIcon from "@mui/icons-material/Menu";
|
||
import logo from "../assets/icon/autobro.png";
|
||
import { useResponsive } from "../theme/useResponsive";
|
||
import Feedback from "./Feedback";
|
||
import { scrollToAnchor } from "../utils/scrollUtils";
|
||
import { useNavigate } from "react-router-dom";
|
||
|
||
const Header = () => {
|
||
const { isMobile } = useResponsive();
|
||
const [drawerOpen, setDrawerOpen] = useState(false);
|
||
const [feedbackOpen, setFeedbackOpen] = useState(false);
|
||
const [scrolled, setScrolled] = useState(false);
|
||
const navigate = useNavigate();
|
||
|
||
const menuItems = [
|
||
// { title: "", anchor: "#main" },
|
||
{ title: "О нас", anchor: "#about-us" },
|
||
{ title: "Этапы работы", anchor: "#stages" },
|
||
{ title: "В наличии", anchor: "#available" },
|
||
{ title: "Калькулятор", anchor: "#calculator" },
|
||
{ title: "Команда", anchor: "#team" },
|
||
{ title: "Отзывы", anchor: "#reviews" },
|
||
{ title: "Контакты", anchor: "#contacts" },
|
||
// { title: "Доставленные авто", anchor: "#delivered" },
|
||
];
|
||
|
||
// Отслеживание скролла
|
||
useEffect(() => {
|
||
const handleScroll = () => {
|
||
if (window.scrollY > 10) {
|
||
setScrolled(true);
|
||
} else {
|
||
setScrolled(false);
|
||
}
|
||
};
|
||
|
||
window.addEventListener("scroll", handleScroll);
|
||
return () => {
|
||
window.removeEventListener("scroll", handleScroll);
|
||
};
|
||
}, []);
|
||
|
||
const toggleDrawer =
|
||
(open: boolean) => (event: React.KeyboardEvent | React.MouseEvent) => {
|
||
if (
|
||
event.type === "keydown" &&
|
||
((event as React.KeyboardEvent).key === "Tab" ||
|
||
(event as React.KeyboardEvent).key === "Shift")
|
||
) {
|
||
return;
|
||
}
|
||
setDrawerOpen(open);
|
||
};
|
||
|
||
// Используем глобальную функцию из utils
|
||
const handleScrollToAnchor = (anchor: string) => {
|
||
if (location.pathname.startsWith("/car")) {
|
||
navigate("/");
|
||
} else {
|
||
scrollToAnchor(anchor, setDrawerOpen, isMobile);
|
||
}
|
||
};
|
||
|
||
return (
|
||
<>
|
||
<Box
|
||
sx={{
|
||
display: "flex",
|
||
justifyContent: "center",
|
||
alignItems: "center",
|
||
height: isMobile ? "15vw" : "5vw",
|
||
gap: "2vw",
|
||
fontFamily: "Unbounded",
|
||
bgcolor: "#2D2D2D",
|
||
userSelect: "none",
|
||
color: "white",
|
||
padding: isMobile ? "0 4vw" : 0,
|
||
position: "fixed",
|
||
top: 0,
|
||
left: 0,
|
||
right: 0,
|
||
zIndex: 1000,
|
||
transition: "all 0.3s ease",
|
||
boxShadow: scrolled ? "0 2px 10px rgba(0,0,0,0.2)" : "none",
|
||
}}
|
||
>
|
||
<Box
|
||
component="img"
|
||
src={logo}
|
||
alt="logo"
|
||
onClick={() => handleScrollToAnchor("#main")}
|
||
sx={{
|
||
width: isMobile ? "17vw" : "9vw",
|
||
height: isMobile ? "6vw" : "2.8vw",
|
||
mb: "0.5vw",
|
||
cursor: "pointer",
|
||
"&:hover": { scale: 1.1 },
|
||
transition: "all 0.4s ease",
|
||
}}
|
||
></Box>
|
||
|
||
{isMobile ? (
|
||
<Box
|
||
sx={{ marginLeft: "auto", display: "flex", alignItems: "center" }}
|
||
>
|
||
<Button
|
||
variant="contained"
|
||
onClick={() => setFeedbackOpen(true)}
|
||
sx={{
|
||
bgcolor: "#C27664",
|
||
color: "white",
|
||
fontSize: "2.5vw",
|
||
padding: "1.5vw 3vw",
|
||
marginRight: "3vw",
|
||
textTransform: "none",
|
||
borderRadius: "3vw",
|
||
fontWeight: "light",
|
||
fontFamily: "Unbounded",
|
||
"&:hover": { bgcolor: "#945B4D" },
|
||
}}
|
||
>
|
||
Оставьте заявку
|
||
</Button>
|
||
<IconButton onClick={toggleDrawer(true)} sx={{ color: "white" }}>
|
||
<MenuIcon sx={{ fontSize: "7vw" }} />
|
||
</IconButton>
|
||
</Box>
|
||
) : (
|
||
// Desktop menu
|
||
menuItems.map((item, index) => (
|
||
<Link
|
||
key={index}
|
||
component="button"
|
||
onClick={() => handleScrollToAnchor(item.anchor)}
|
||
underline="none"
|
||
sx={{
|
||
fontFamily: "Unbounded",
|
||
fontSize: "1.2vw",
|
||
cursor: "pointer",
|
||
color: "white",
|
||
"&:hover": { color: "#C27664" },
|
||
transition: "all 0.3s ease",
|
||
}}
|
||
>
|
||
{item.title}
|
||
</Link>
|
||
))
|
||
)}
|
||
</Box>
|
||
|
||
{/* Пустой блок для компенсации фиксированного хедера */}
|
||
<Box sx={{ height: isMobile ? "15vw" : location.pathname.startsWith("/car") ? "5vw" : "10vw", bgcolor: "#2D2D2D" }} />
|
||
|
||
{/* Мобильное меню */}
|
||
<Drawer anchor="right" open={drawerOpen} onClose={toggleDrawer(false)}>
|
||
<Box
|
||
sx={{ width: "58vw", bgcolor: "#2D2D2D", height: "100%" }}
|
||
role="presentation"
|
||
>
|
||
<List>
|
||
{menuItems.map((item, index) => (
|
||
<ListItem
|
||
key={index}
|
||
onClick={() => handleScrollToAnchor(item.anchor)}
|
||
sx={{ cursor: "pointer" }}
|
||
>
|
||
<Typography
|
||
sx={{
|
||
fontFamily: "Unbounded",
|
||
fontSize: "4vw",
|
||
color: "white",
|
||
padding: "2vw 0",
|
||
"&:hover": { color: "#C27664" },
|
||
transition: "color 0.3s ease",
|
||
}}
|
||
>
|
||
{item.title}
|
||
</Typography>
|
||
</ListItem>
|
||
))}
|
||
</List>
|
||
</Box>
|
||
</Drawer>
|
||
|
||
<Feedback
|
||
open={feedbackOpen}
|
||
onClose={() => setFeedbackOpen(false)}
|
||
handleScrollToAnchor={handleScrollToAnchor}
|
||
/>
|
||
</>
|
||
);
|
||
};
|
||
|
||
export default Header;
|