|
import React, { useState, useEffect, useRef } from "react"; |
|
import { Link, useLocation } from "react-router-dom"; |
|
import { Logo } from "../utils"; |
|
import styled from "styled-components"; |
|
|
|
|
|
const HeaderContainer = styled.header` |
|
z-index: 500; |
|
background: rgba(0, 0, 0, 0.8); |
|
font-family: "SF Pro", sans-serif; |
|
font-weight: 800; |
|
font-size: 15px; |
|
position: sticky; |
|
top: 0; |
|
width: 100%; |
|
margin: 0; |
|
padding: 0; |
|
`; |
|
|
|
const NavWrapper = styled.div` |
|
display: flex; |
|
justify-content: center; |
|
align-items: center; |
|
padding: 0.5rem 1rem; |
|
width: 100%; |
|
margin: 0; |
|
|
|
@media (max-width: 768px) { |
|
justify-content: space-between; |
|
} |
|
`; |
|
|
|
const SLogo = styled(Link)` |
|
display: flex; |
|
align-items: center; |
|
font-weight: bold; |
|
color: white; |
|
text-decoration: none; |
|
|
|
img { |
|
height: 50px; |
|
margin-right: 0.5rem; |
|
} |
|
`; |
|
|
|
const DesktopMenu = styled.nav` |
|
display: none; |
|
|
|
@media (min-width: 768px) { |
|
display: flex; |
|
gap: 1rem; |
|
position: relative; |
|
} |
|
`; |
|
|
|
const MenuLink = styled(Link)` |
|
color: ${(props) => (props.$active ? "transparent" : "white")}; |
|
padding: 0.5rem 2rem; |
|
text-decoration: none; |
|
position: relative; |
|
cursor: pointer; |
|
|
|
@media (min-width: 992px) { |
|
padding: 0.5rem 4rem; |
|
} |
|
|
|
&:hover, |
|
&:active { |
|
color: #3267B9; |
|
background-clip: text; |
|
-webkit-background-clip: text; |
|
} |
|
|
|
${(props) => |
|
props.$active && |
|
` |
|
color: #3267B9; |
|
background-clip: text; |
|
-webkit-background-clip: text; |
|
`} |
|
`; |
|
|
|
|
|
const DropdownMenu = styled.div` |
|
position: absolute; |
|
background: rgba(0, 0, 0, 0.9); |
|
border-radius: 5px; |
|
top: 100%; |
|
left: 0; |
|
min-width: 150px; |
|
display: ${(props) => (props.$isOpen ? "block" : "none")}; |
|
z-index: 1000; |
|
|
|
a { |
|
display: block; |
|
padding: 0.5rem; |
|
color: white; |
|
text-decoration: none; |
|
|
|
&:hover { |
|
background: #333; |
|
} |
|
} |
|
`; |
|
|
|
const ContactWrapper = styled.div` |
|
position: relative; |
|
cursor: pointer; |
|
`; |
|
|
|
|
|
const MobileMenuButton = styled.button` |
|
display: block; |
|
background: none; |
|
border: none; |
|
color: white; |
|
font-size: 2.5rem; |
|
cursor: pointer; |
|
transition: transform 0.2s ease; |
|
|
|
&:hover { |
|
color: #0ea8b6; |
|
} |
|
|
|
&:active { |
|
transform: scale(0.9); |
|
} |
|
|
|
@media (min-width: 768px) { |
|
display: none; |
|
} |
|
`; |
|
|
|
const MobileMenu = styled.nav` |
|
background: rgba(0, 0, 0, 0.9); |
|
position: absolute; |
|
top: 100%; |
|
left: 0; |
|
width: 100%; |
|
max-height: ${(props) => (props.$isOpen ? "400px" : "0")}; |
|
overflow: hidden; |
|
opacity: ${(props) => (props.$isOpen ? 1 : 0)}; |
|
transform: ${(props) => (props.$isOpen ? "translateY(0)" : "translateY(-10px)")}; |
|
transition: max-height 0.3s ease, opacity 0.3s ease, transform 0.3s ease; |
|
|
|
a { |
|
display: block; |
|
padding: 0.5rem 1rem; |
|
color: white; |
|
text-decoration: none; |
|
|
|
&:hover { |
|
background: #333; |
|
} |
|
} |
|
`; |
|
|
|
const Header = () => { |
|
const [isMenuOpen, setIsMenuOpen] = useState(false); |
|
const [isDropdownOpen, setIsDropdownOpen] = useState(false); |
|
const location = useLocation(); |
|
const menuRef = useRef(null); |
|
const buttonRef = useRef(null); |
|
const dropdownRef = useRef(null); |
|
|
|
const toggleMenu = () => setIsMenuOpen(prev => !prev); |
|
const toggleDropdown = () => setIsDropdownOpen(prev => !prev); |
|
|
|
|
|
useEffect(() => { |
|
const handleClickOutside = (event) => { |
|
if ( |
|
menuRef.current && |
|
!menuRef.current.contains(event.target) && |
|
buttonRef.current && |
|
!buttonRef.current.contains(event.target) |
|
) { |
|
setIsMenuOpen(false); |
|
} |
|
if ( |
|
dropdownRef.current && |
|
!dropdownRef.current.contains(event.target) |
|
) { |
|
setIsDropdownOpen(false); |
|
} |
|
}; |
|
|
|
document.addEventListener("mousedown", handleClickOutside); |
|
return () => { |
|
document.removeEventListener("mousedown", handleClickOutside); |
|
}; |
|
}, []); |
|
|
|
|
|
useEffect(() => { |
|
setIsMenuOpen(false); |
|
setIsDropdownOpen(false); |
|
}, [location.pathname]); |
|
|
|
return ( |
|
<HeaderContainer> |
|
<NavWrapper> |
|
<SLogo to="/"> |
|
<img src={Logo} alt="Logo" /> |
|
</SLogo> |
|
|
|
<DesktopMenu> |
|
{["/vardig", "/about", "/blogs", "/jobs"].map((path, i) => ( |
|
<MenuLink key={i} to={path} $active={location.pathname === path}> |
|
{path === "/vardig" |
|
? "VarDiG" |
|
: path.replace("/", "").charAt(0).toUpperCase() + |
|
path.replace("/", "").slice(1)} |
|
</MenuLink> |
|
))} |
|
|
|
{/* Contact with Dropdown */} |
|
<ContactWrapper ref={dropdownRef}> |
|
<MenuLink as="div" onClick={toggleDropdown}> |
|
Contact ▾ |
|
</MenuLink> |
|
<DropdownMenu $isOpen={isDropdownOpen}> |
|
<Link to="/contact">Contact</Link> |
|
<Link to="/privacy-policy">Privacy Policy</Link> |
|
</DropdownMenu> |
|
</ContactWrapper> |
|
</DesktopMenu> |
|
|
|
<MobileMenuButton |
|
onClick={toggleMenu} |
|
aria-expanded={isMenuOpen} |
|
ref={buttonRef} |
|
> |
|
☰ |
|
</MobileMenuButton> |
|
</NavWrapper> |
|
|
|
<MobileMenu $isOpen={isMenuOpen} ref={menuRef}> |
|
{["/", "/vardig", "/about", "/blogs", "/jobs"].map((path, i) => ( |
|
<Link key={i} to={path} onClick={() => setIsMenuOpen(false)}> |
|
{path === "/" ? "Home" : path.replace("/", "").charAt(0).toUpperCase() + path.slice(2)} |
|
</Link> |
|
))} |
|
|
|
{/* Mobile Contact Dropdown */} |
|
<div> |
|
<Link to="/contact" onClick={() => setIsMenuOpen(false)}>Contact</Link> |
|
<Link to="/privacy-policy" onClick={() => setIsMenuOpen(false)} style={{ paddingLeft: "20px" }}> |
|
Privacy Policy |
|
</Link> |
|
</div> |
|
</MobileMenu> |
|
</HeaderContainer> |
|
); |
|
}; |
|
|
|
export default Header; |