143 lines
6.1 KiB
TypeScript
143 lines
6.1 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from 'react';
|
|
import Link from 'next/link';
|
|
import { useRouter } from 'next/navigation';
|
|
|
|
export default function Navbar() {
|
|
const [isOpen, setIsOpen] = useState(false);
|
|
const [mobileProductsOpen, setMobileProductsOpen] = useState(false);
|
|
const [isLogged, setIsLogged] = useState(false);
|
|
const [showLogoutConfirm, setShowLogoutConfirm] = useState(false);
|
|
const router = useRouter();
|
|
|
|
useEffect(() => {
|
|
const checkAuth = () => {
|
|
const uid = localStorage.getItem('vgproducts_uid') || sessionStorage.getItem('USERID');
|
|
setIsLogged(!!uid);
|
|
};
|
|
checkAuth();
|
|
// Check periodically or handle logout event
|
|
window.addEventListener('storage', checkAuth);
|
|
return () => window.removeEventListener('storage', checkAuth);
|
|
}, []);
|
|
|
|
const handleLogoutClick = () => {
|
|
setShowLogoutConfirm(true);
|
|
};
|
|
|
|
const performLogout = () => {
|
|
localStorage.removeItem('vgproducts_uid');
|
|
localStorage.removeItem('d4a_email');
|
|
sessionStorage.removeItem('USERID');
|
|
setIsLogged(false);
|
|
setIsOpen(false);
|
|
setShowLogoutConfirm(false);
|
|
router.push('/');
|
|
// trigger state update for other components
|
|
window.dispatchEvent(new Event('storage'));
|
|
};
|
|
|
|
const toggleMenu = () => setIsOpen(!isOpen);
|
|
|
|
return (
|
|
<>
|
|
<nav>
|
|
<Link href="/" className="nav-logo">
|
|
{/* <div className="lm">VG</div> */}
|
|
<img src="/assets/vg-fence.png" alt="VG Fence Products" />
|
|
</Link>
|
|
|
|
<ul className="nav-links">
|
|
<li className="nav-dropdown-wrap">
|
|
<Link href="#">Products <span className="chevron-down">⌵</span></Link>
|
|
<ul className="nav-dropdown">
|
|
<li><Link href="/products/chain-link-fence">Chain Link Fence</Link></li>
|
|
{/* <li><Link href="#">Aluminum Railing</Link></li>
|
|
<li><Link href="#">Composite Fences</Link></li>
|
|
<li><Link href="#">Glass Railing</Link></li>
|
|
<li><Link href="#">Ornamental Fence</Link></li>
|
|
<li><Link href="#">Expert Stain & Seal</Link></li>
|
|
<li><Link href="#">Fence Armor</Link></li>
|
|
<li><Link href="#">Temporary Fence</Link></li> */}
|
|
</ul>
|
|
</li>
|
|
<li><Link href="/services">Services</Link></li>
|
|
<li><Link href="/who-we-serve">Who We Serve</Link></li>
|
|
<li><Link href="/contact">Contact</Link></li>
|
|
</ul>
|
|
|
|
<div className="nav-right">
|
|
{isLogged ? (
|
|
<button onClick={handleLogoutClick} className="nav-login" style={{ background: 'none', cursor: 'pointer' }}>Logout</button>
|
|
) : (
|
|
<Link href="/login" className="nav-login">Contractor Login</Link>
|
|
)}
|
|
<Link href="/contact" className="nav-cta">Get a Quote</Link>
|
|
<button className="nav-hamburger" onClick={toggleMenu}>
|
|
<span></span>
|
|
<span></span>
|
|
<span></span>
|
|
</button>
|
|
</div>
|
|
</nav>
|
|
|
|
<div className={`mobile-menu ${isOpen ? 'open' : ''}`}>
|
|
<div className="mobile-dropdown-section">
|
|
<button
|
|
className="mobile-dropdown-btn"
|
|
onClick={() => setMobileProductsOpen(!mobileProductsOpen)}
|
|
>
|
|
Products
|
|
<span className={`chevron-down ${mobileProductsOpen ? 'rotated' : ''}`}>⌵</span>
|
|
</button>
|
|
|
|
<div className={`mobile-dropdown-content ${mobileProductsOpen ? 'show' : ''}`}>
|
|
<Link href="/products/chain-link-fence" onClick={() => setIsOpen(false)}>Chain Link Fence</Link>
|
|
{/* <Link href="#" onClick={() => setIsOpen(false)}>Aluminum Railing</Link>
|
|
<Link href="#" onClick={() => setIsOpen(false)}>Composite Fences</Link>
|
|
<Link href="#" onClick={() => setIsOpen(false)}>Glass Railing</Link>
|
|
<Link href="#" onClick={() => setIsOpen(false)}>Ornamental Fence</Link> */}
|
|
</div>
|
|
</div>
|
|
<Link href="/services" onClick={() => setIsOpen(false)}>Services</Link>
|
|
<Link href="/who-we-serve" onClick={() => setIsOpen(false)}>Who We Serve</Link>
|
|
<Link href="/contact" onClick={() => setIsOpen(false)}>Contact</Link>
|
|
|
|
<div className="mobile-menu-actions">
|
|
{isLogged ? (
|
|
<button onClick={() => { performLogout(); setIsOpen(false); }} className="mobile-login-btn">Logout</button>
|
|
) : (
|
|
<Link href="/login" onClick={() => setIsOpen(false)} className="mobile-login-btn">Contractor Login</Link>
|
|
)}
|
|
<Link href="/contact" className="mobile-cta" onClick={() => setIsOpen(false)}>Get a Quote</Link>
|
|
</div>
|
|
</div>
|
|
|
|
{showLogoutConfirm && (
|
|
<div style={{
|
|
position: 'fixed', top: 0, left: 0, right: 0, bottom: 0,
|
|
backgroundColor: 'rgba(0,10,30,0.7)', display: 'flex',
|
|
justifyContent: 'center', alignItems: 'center', zIndex: 99999,
|
|
backdropFilter: 'blur(4px)'
|
|
}}>
|
|
<div style={{
|
|
background: '#ffffff', padding: '32px', borderRadius: '12px',
|
|
width: '90%', maxWidth: '400px', boxShadow: '0 25px 50px -12px rgba(0, 0, 0, 0.25)',
|
|
textAlign: 'center'
|
|
}}>
|
|
<h3 style={{ fontSize: '24px', fontWeight: 800, color: 'var(--navy)', marginBottom: '12px', fontFamily: 'var(--fd)' }}>Confirm Logout</h3>
|
|
<p style={{ color: 'var(--gray-600)', marginBottom: '32px', fontSize: '15px', lineHeight: 1.5 }}>
|
|
Are you sure you want to log out of your account?
|
|
</p>
|
|
<div style={{ display: 'flex', gap: '16px', justifyContent: 'center' }}>
|
|
<button onClick={() => setShowLogoutConfirm(false)} className="btn-secondary" style={{ flex: 1, padding: '12px', border: '1px solid var(--gray-300)', color: 'var(--gray-700)', borderRadius: '6px', fontWeight: 600, cursor: 'pointer' }}>Cancel</button>
|
|
<button onClick={performLogout} className="btn-primary" style={{ flex: 1, padding: '12px', background: 'var(--orange)', color: '#fff', border: 'none', borderRadius: '6px', fontWeight: 600, cursor: 'pointer' }}>Logout</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</>
|
|
);
|
|
}
|