439 lines
12 KiB
React
439 lines
12 KiB
React
import { useState } from "react";
|
|
import {
|
|
AppBar,
|
|
Toolbar,
|
|
Typography,
|
|
Button,
|
|
Box,
|
|
Drawer,
|
|
List,
|
|
ListItem,
|
|
ListItemText,
|
|
TextField,
|
|
IconButton,
|
|
Divider,
|
|
Menu,
|
|
MenuItem,
|
|
CircularProgress,
|
|
} from "@mui/material";
|
|
import { Link, useLocation, useNavigate } from "react-router-dom";
|
|
import MenuIcon from "@mui/icons-material/Menu";
|
|
import SearchIcon from "@mui/icons-material/Search";
|
|
import HomeIcon from "@mui/icons-material/Home";
|
|
import ArticleIcon from "@mui/icons-material/Article";
|
|
import InfoIcon from "@mui/icons-material/Info";
|
|
import ContactMailIcon from "@mui/icons-material/ContactMail";
|
|
import WorkIcon from "@mui/icons-material/Work";
|
|
import Logo from "../assets/logo-in3.svg";
|
|
import LogoM from "../assets/logo-in3-mobil.svg";
|
|
|
|
const Header = () => {
|
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
const [searchQuery, setSearchQuery] = useState("");
|
|
const [isSearching, setIsSearching] = useState(false);
|
|
const [anchorEl, setAnchorEl] = useState(null); // Pour gérer le menu Services
|
|
const location = useLocation();
|
|
const navigate = useNavigate();
|
|
|
|
const toggleDrawer = (open) => (event) => {
|
|
if (
|
|
event.type === "keydown" &&
|
|
(event.key === "Tab" || event.key === "Shift")
|
|
) {
|
|
return;
|
|
}
|
|
setDrawerOpen(open);
|
|
};
|
|
|
|
const handleSearch = () => {
|
|
if (searchQuery.trim()) {
|
|
setIsSearching(true);
|
|
setTimeout(() => {
|
|
navigate(`/search?query=${encodeURIComponent(searchQuery.trim())}`);
|
|
setIsSearching(false);
|
|
}, 500);
|
|
}
|
|
};
|
|
|
|
const handleMenuOpen = (event) => {
|
|
setAnchorEl(event.currentTarget);
|
|
};
|
|
|
|
const handleMenuClose = () => {
|
|
setAnchorEl(null);
|
|
};
|
|
|
|
const commonButtonStyles = {
|
|
transition: "color 0.3s",
|
|
position: "relative",
|
|
"&:hover": { color: " #00bcd4" },
|
|
"&:after": {
|
|
content: '""',
|
|
position: "absolute",
|
|
width: "0",
|
|
height: "2px",
|
|
bottom: 0,
|
|
left: 0,
|
|
backgroundColor: " #00bcd4",
|
|
transition: "width 0.3s",
|
|
},
|
|
"&:hover:after": {
|
|
width: "100%",
|
|
},
|
|
};
|
|
|
|
return (
|
|
<AppBar
|
|
position="fixed"
|
|
color="transparent"
|
|
elevation={0}
|
|
sx={{
|
|
background: "linear-gradient(to right, #294A9A, #3158b3)",
|
|
color: "white",
|
|
transition: "all 0.3s ease",
|
|
|
|
}}
|
|
>
|
|
<Toolbar>
|
|
{/* Mobile menu icon */}
|
|
<IconButton
|
|
edge="start"
|
|
color="inherit"
|
|
aria-label="menu"
|
|
onClick={toggleDrawer(true)}
|
|
sx={{
|
|
display: { xs: "block", md: "none" },
|
|
color: " #ffffff",
|
|
}}
|
|
>
|
|
<MenuIcon />
|
|
</IconButton>
|
|
|
|
{/* Logo */}
|
|
<Box
|
|
component={Link}
|
|
to="/"
|
|
sx={{
|
|
flexGrow: 1,
|
|
textAlign: { xs: "center", md: "left" },
|
|
alignItems: "center",
|
|
textDecoration: "none",
|
|
gap: 1,
|
|
}}
|
|
>
|
|
<img
|
|
src={Logo}
|
|
alt="Bureau d'études Le Mans"
|
|
style={{
|
|
width: "50px",
|
|
height: "50px",
|
|
objectFit: "contain",
|
|
}}
|
|
/>
|
|
</Box>
|
|
|
|
{/* Navigation Links */}
|
|
<Box sx={{ display: { xs: "none", md: "flex" }, gap: 2 }}>
|
|
{/* Services Dropdown */}
|
|
<Button
|
|
color="inherit"
|
|
aria-controls="services-menu"
|
|
aria-haspopup="true"
|
|
onClick={handleMenuOpen}
|
|
sx={{
|
|
fontWeight: location.pathname.includes("/services")
|
|
? "bold"
|
|
: "normal",
|
|
textDecoration: location.pathname.includes("/services")
|
|
? "underline"
|
|
: "none",
|
|
...commonButtonStyles,
|
|
}}
|
|
>
|
|
Services
|
|
</Button>
|
|
<Menu
|
|
id="services-menu"
|
|
anchorEl={anchorEl}
|
|
open={Boolean(anchorEl)}
|
|
onClose={handleMenuClose}
|
|
MenuListProps={{
|
|
"aria-labelledby": "services-button",
|
|
}}
|
|
>
|
|
<MenuItem
|
|
component={Link}
|
|
to="/services/prestation-maitrise-oeuvre"
|
|
onClick={handleMenuClose}
|
|
>
|
|
<WorkIcon sx={{ marginRight: 1 }} />
|
|
Prestation maitrise oeuvre
|
|
</MenuItem>
|
|
|
|
<MenuItem
|
|
component={Link}
|
|
to="/services/structure-beton-charpente-metallique-bois"
|
|
onClick={handleMenuClose}
|
|
>
|
|
<WorkIcon sx={{ marginRight: 1 }} />
|
|
Structure béton | charpente métallique / bois
|
|
</MenuItem>
|
|
|
|
<MenuItem
|
|
component={Link}
|
|
to="/services/electricite"
|
|
onClick={handleMenuClose}
|
|
>
|
|
<WorkIcon sx={{ marginRight: 1}} />
|
|
Électricité
|
|
</MenuItem>
|
|
|
|
<MenuItem
|
|
component={Link}
|
|
to="/services/ssi"
|
|
onClick={handleMenuClose}
|
|
>
|
|
<WorkIcon sx={{ marginRight: 1}} />
|
|
Systeme Sécurité Incendie (SSI)
|
|
</MenuItem>
|
|
|
|
</Menu>
|
|
|
|
<Button
|
|
component={Link}
|
|
to="/posts"
|
|
color="inherit"
|
|
sx={{
|
|
fontWeight: location.pathname === "/posts" ? "bold" : "normal",
|
|
textDecoration:
|
|
location.pathname === "/posts" ? "underline" : "none",
|
|
...commonButtonStyles,
|
|
}}
|
|
>
|
|
Réalisations
|
|
</Button>
|
|
<Button
|
|
component={Link}
|
|
to="/about"
|
|
color="inherit"
|
|
sx={{
|
|
fontWeight: location.pathname === "/about" ? "bold" : "normal",
|
|
textDecoration:
|
|
location.pathname === "/about" ? "underline" : "none",
|
|
...commonButtonStyles,
|
|
}}
|
|
>
|
|
À Propos
|
|
</Button>
|
|
<Button
|
|
component={Link}
|
|
to="/bureauEtude"
|
|
color="inherit"
|
|
sx={{
|
|
fontWeight: location.pathname === "/bureauEtude" ? "bold" : "normal",
|
|
textDecoration:
|
|
location.pathname === "/bureauEtude" ? "underline" : "none",
|
|
...commonButtonStyles,
|
|
}}
|
|
>
|
|
Bureau d'étude
|
|
</Button>
|
|
<Button
|
|
component={Link}
|
|
to="/contact"
|
|
color="inherit"
|
|
sx={{
|
|
fontWeight: location.pathname === "/contact" ? "bold" : "normal",
|
|
textDecoration:
|
|
location.pathname === "/contact" ? "underline" : "none",
|
|
...commonButtonStyles,
|
|
}}
|
|
>
|
|
Contact
|
|
</Button>
|
|
</Box>
|
|
|
|
{/* Search Field */}
|
|
<Box
|
|
component="form"
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
handleSearch();
|
|
}}
|
|
sx={{
|
|
display: { xs: "none", md: "flex" },
|
|
alignItems: "center",
|
|
gap: 1,
|
|
}}
|
|
>
|
|
<label
|
|
htmlFor="search-input"
|
|
style={{ position: "absolute", left: "-9999px" }}
|
|
>
|
|
Rechercher sur le site
|
|
</label>
|
|
<TextField
|
|
id="search-input"
|
|
variant="outlined"
|
|
size="small"
|
|
placeholder="Rechercher..."
|
|
value={searchQuery}
|
|
onChange={(e) => setSearchQuery(e.target.value)}
|
|
sx={{
|
|
backgroundColor: "rgba(255, 255, 255, 0.9)",
|
|
borderRadius: 1,
|
|
"& .MuiOutlinedInput-root": {
|
|
"& fieldset": {
|
|
borderColor: "white",
|
|
},
|
|
"&:hover fieldset": {
|
|
borderColor: " #00bcd4",
|
|
},
|
|
"&.Mui-focused fieldset": {
|
|
borderColor: " #00bcd4",
|
|
},
|
|
},
|
|
}}
|
|
/>
|
|
<IconButton type="submit" color="inherit" aria-label="Rechercher">
|
|
{isSearching ? (
|
|
<CircularProgress size={20} color="inherit" />
|
|
) : (
|
|
<SearchIcon />
|
|
)}
|
|
</IconButton>
|
|
</Box>
|
|
|
|
{/* Drawer for mobile */}
|
|
<Drawer anchor="left" open={drawerOpen} onClose={toggleDrawer(false)}>
|
|
<Box
|
|
sx={{
|
|
width: 250,
|
|
backgroundColor: " #f5f5f5",
|
|
height: "100%",
|
|
padding: 2,
|
|
}}
|
|
role="presentation"
|
|
onClick={toggleDrawer(false)}
|
|
onKeyDown={toggleDrawer(false)}
|
|
>
|
|
<Box
|
|
sx={{
|
|
display: "block",
|
|
textAlign: "center",
|
|
}}
|
|
>
|
|
<img
|
|
src={LogoM}
|
|
alt="Logo"
|
|
style={{
|
|
height: "50px",
|
|
width: "auto",
|
|
}}
|
|
/>
|
|
</Box>
|
|
<Typography
|
|
variant="h6"
|
|
sx={{ textAlign: "center", marginBottom: 2 }}
|
|
>
|
|
Menu
|
|
</Typography>
|
|
<Divider />
|
|
<List>
|
|
<ListItem
|
|
button
|
|
component={Link}
|
|
to="/"
|
|
selected={location.pathname === "/"}
|
|
>
|
|
<HomeIcon
|
|
sx={{
|
|
marginRight: 0.5,
|
|
}}
|
|
/>
|
|
<ListItemText primary="Accueil" />
|
|
</ListItem>
|
|
<ListItem
|
|
button
|
|
component={Link}
|
|
to="/services/prestation-maitrise-oeuvre"
|
|
selected={location.pathname.includes("/services/prestation-maitrise-oeuvre")}
|
|
>
|
|
<WorkIcon sx={{ marginRight: 0.5 }} />
|
|
<ListItemText primary="Prestation maitrise oeuvre" />
|
|
</ListItem>
|
|
|
|
<ListItem
|
|
button
|
|
component={Link}
|
|
to="/services/structure-beton-charpente-metallique-bois"
|
|
selected={location.pathname.includes("/services/structure-beton-charpente-metallique-bois")}
|
|
>
|
|
<WorkIcon sx={{ marginRight: 0.5 }} />
|
|
<ListItemText primary="Structure beton..." />
|
|
</ListItem>
|
|
|
|
<ListItem
|
|
button
|
|
component={Link}
|
|
to="/services/electricite"
|
|
selected={location.pathname.includes(
|
|
"/services/electricite"
|
|
)}
|
|
>
|
|
<WorkIcon sx={{ marginRight: 0.5 }} />
|
|
<ListItemText primary="Electricité..." />
|
|
</ListItem>
|
|
|
|
<ListItem
|
|
button
|
|
component={Link}
|
|
to="/services/ssi"
|
|
selected={location.pathname.includes(
|
|
"/services/ssi"
|
|
)}
|
|
>
|
|
<WorkIcon sx={{ marginRight: 0.5 }} />
|
|
<ListItemText primary="SSI..." />
|
|
</ListItem>
|
|
|
|
<ListItem
|
|
button
|
|
component={Link}
|
|
to="/posts"
|
|
selected={location.pathname === "/posts"}
|
|
>
|
|
<ArticleIcon sx={{ marginRight: 0.5 }} />
|
|
<ListItemText primary="Réalisations" />
|
|
</ListItem>
|
|
|
|
<ListItem
|
|
button
|
|
component={Link}
|
|
to="/about"
|
|
selected={location.pathname === "/about"}
|
|
>
|
|
<InfoIcon sx={{ marginRight: 0.5 }} />
|
|
<ListItemText primary="À propos" />
|
|
</ListItem>
|
|
|
|
<ListItem
|
|
button
|
|
component={Link}
|
|
to="/contact"
|
|
selected={location.pathname === "/contact"}
|
|
>
|
|
<ContactMailIcon sx={{ marginRight: 0.5 }} />
|
|
<ListItemText primary="Contact" />
|
|
</ListItem>
|
|
|
|
</List>
|
|
</Box>
|
|
</Drawer>
|
|
</Toolbar>
|
|
</AppBar>
|
|
);
|
|
};
|
|
|
|
export default Header;
|