176 lines
6.1 KiB
TypeScript
176 lines
6.1 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import { Link, useLocation, NavLink } from 'react-router-dom';
|
|
import { Home, Info, Mail, ArrowUp } from 'lucide-react';
|
|
|
|
const Layout = ({ children }: { children: React.ReactNode }) => {
|
|
const location = useLocation();
|
|
const [showScrollTop, setShowScrollTop] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const handleScroll = () => {
|
|
setShowScrollTop(window.scrollY > 400);
|
|
};
|
|
|
|
const throttledScroll = () => {
|
|
window.requestAnimationFrame(handleScroll);
|
|
};
|
|
|
|
window.addEventListener('scroll', throttledScroll, { passive: true });
|
|
return () => window.removeEventListener('scroll', throttledScroll);
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
window.scrollTo(0, 0);
|
|
}, [location.pathname]);
|
|
|
|
const scrollToTop = () => {
|
|
window.scrollTo({ top: 0, behavior: 'smooth' });
|
|
};
|
|
|
|
return (
|
|
<div className="layout">
|
|
<header>
|
|
<div className="container">
|
|
<Link
|
|
to="/"
|
|
style={{ display: 'flex', alignItems: 'center' }}
|
|
aria-label="MB Grid Solutions - Zur Startseite"
|
|
>
|
|
<img
|
|
src="/assets/logo.png"
|
|
alt="MB Grid Solutions"
|
|
style={{ height: '80px' }}
|
|
loading="eager"
|
|
/>
|
|
</Link>
|
|
<nav style={{ display: 'flex', gap: '2rem' }} aria-label="Hauptnavigation">
|
|
<NavLink to="/" className={({ isActive }) => `nav-link ${isActive ? 'active' : ''}`}>
|
|
Startseite
|
|
</NavLink>
|
|
<NavLink to="/ueber-uns" className={({ isActive }) => `nav-link ${isActive ? 'active' : ''}`}>
|
|
Über uns
|
|
</NavLink>
|
|
<NavLink to="/kontakt" className={({ isActive }) => `nav-link ${isActive ? 'active' : ''}`}>
|
|
Kontakt
|
|
</NavLink>
|
|
</nav>
|
|
</div>
|
|
</header>
|
|
|
|
<main>
|
|
{children}
|
|
</main>
|
|
|
|
<button
|
|
onClick={scrollToTop}
|
|
className={`scroll-top-btn ${showScrollTop ? 'visible' : ''}`}
|
|
aria-label="Nach oben scrollen"
|
|
aria-hidden={!showScrollTop}
|
|
tabIndex={showScrollTop ? 0 : -1}
|
|
>
|
|
<ArrowUp size={24} strokeWidth={2.5} />
|
|
</button>
|
|
|
|
<nav className="mobile-nav" aria-label="Mobile Navigation">
|
|
<NavLink
|
|
to="/"
|
|
className={({ isActive }) => `mobile-nav-link ${isActive ? 'active' : ''}`}
|
|
aria-label="Startseite"
|
|
>
|
|
<Home size={22} strokeWidth={2} />
|
|
<span>Start</span>
|
|
</NavLink>
|
|
<NavLink
|
|
to="/ueber-uns"
|
|
className={({ isActive }) => `mobile-nav-link ${isActive ? 'active' : ''}`}
|
|
aria-label="Über uns"
|
|
>
|
|
<Info size={22} strokeWidth={2} />
|
|
<span>Über uns</span>
|
|
</NavLink>
|
|
<NavLink
|
|
to="/kontakt"
|
|
className={({ isActive }) => `mobile-nav-link ${isActive ? 'active' : ''}`}
|
|
aria-label="Kontakt"
|
|
>
|
|
<Mail size={22} strokeWidth={2} />
|
|
<span>Kontakt</span>
|
|
</NavLink>
|
|
</nav>
|
|
|
|
<footer style={{
|
|
borderTop: '1px solid var(--secondary-bg)',
|
|
padding: 'clamp(2rem, 4vw, 4rem) 0',
|
|
marginTop: 'clamp(2rem, 4vw, 4rem)',
|
|
background: 'white'
|
|
}}>
|
|
<div className="container">
|
|
<div className="grid" style={{
|
|
gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))',
|
|
marginBottom: 'clamp(1.5rem, 3vw, 3rem)'
|
|
}}>
|
|
<div>
|
|
<img
|
|
src="/assets/logo.png"
|
|
alt="MB Grid Solutions"
|
|
style={{
|
|
height: 'clamp(60px, 10vw, 80px)',
|
|
marginBottom: 'var(--spacing-lg)',
|
|
filter: 'grayscale(1)'
|
|
}}
|
|
loading="lazy"
|
|
/>
|
|
<p style={{
|
|
color: 'var(--text-secondary)',
|
|
fontSize: 'clamp(0.875rem, 2vw, 0.9rem)',
|
|
lineHeight: 1.6
|
|
}}>
|
|
Ihr Partner für Energiekabelprojekte bis 110 kV.
|
|
</p>
|
|
</div>
|
|
<div>
|
|
<h4 style={{
|
|
fontSize: 'clamp(0.9rem, 2vw, 1rem)',
|
|
marginBottom: 'var(--spacing-md)',
|
|
fontWeight: 600
|
|
}}>Navigation</h4>
|
|
<nav style={{ display: 'flex', flexDirection: 'column', gap: '0.625rem' }} aria-label="Footer Navigation">
|
|
<Link to="/" style={{ fontSize: 'clamp(0.875rem, 2vw, 0.95rem)' }}>Startseite</Link>
|
|
<Link to="/ueber-uns" style={{ fontSize: 'clamp(0.875rem, 2vw, 0.95rem)' }}>Über uns</Link>
|
|
<Link to="/kontakt" style={{ fontSize: 'clamp(0.875rem, 2vw, 0.95rem)' }}>Kontakt</Link>
|
|
</nav>
|
|
</div>
|
|
<div>
|
|
<h4 style={{
|
|
fontSize: 'clamp(0.9rem, 2vw, 1rem)',
|
|
marginBottom: 'var(--spacing-md)',
|
|
fontWeight: 600
|
|
}}>Rechtliches</h4>
|
|
<nav style={{ display: 'flex', flexDirection: 'column', gap: '0.625rem' }} aria-label="Legal Navigation">
|
|
<Link to="/impressum" style={{ fontSize: 'clamp(0.875rem, 2vw, 0.95rem)' }}>Impressum</Link>
|
|
<Link to="/datenschutz" style={{ fontSize: 'clamp(0.875rem, 2vw, 0.95rem)' }}>Datenschutz</Link>
|
|
<Link to="/agb" style={{ fontSize: 'clamp(0.875rem, 2vw, 0.95rem)' }}>AGB</Link>
|
|
</nav>
|
|
</div>
|
|
</div>
|
|
<div style={{
|
|
borderTop: '1px solid var(--secondary-bg)',
|
|
paddingTop: 'var(--spacing-xl)',
|
|
display: 'flex',
|
|
justifyContent: 'space-between',
|
|
color: 'var(--text-secondary)',
|
|
fontSize: 'clamp(0.75rem, 2vw, 0.85rem)',
|
|
gap: 'var(--spacing-md)',
|
|
flexWrap: 'wrap'
|
|
}}>
|
|
<div>© {new Date().getFullYear()} MB Grid Solutions GmbH. Alle Rechte vorbehalten.</div>
|
|
<div>Made with precision.</div>
|
|
</div>
|
|
</div>
|
|
</footer>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default Layout;
|