redesign
This commit is contained in:
@@ -1,29 +1,29 @@
|
||||
'use client';
|
||||
|
||||
import { ArrowUp, Home, Info, Mail } from 'lucide-react';
|
||||
import { ArrowUp, Home, Info, Mail, Menu, X } from 'lucide-react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { motion, AnimatePresence } from 'framer-motion';
|
||||
|
||||
const Layout = ({ children }: { children: React.ReactNode }) => {
|
||||
const pathname = usePathname();
|
||||
const [showScrollTop, setShowScrollTop] = useState(false);
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setShowScrollTop(window.scrollY > 400);
|
||||
setIsScrolled(window.scrollY > 20);
|
||||
};
|
||||
|
||||
const throttledScroll = () => {
|
||||
window.requestAnimationFrame(handleScroll);
|
||||
};
|
||||
|
||||
window.addEventListener('scroll', throttledScroll, { passive: true });
|
||||
return () => window.removeEventListener('scroll', throttledScroll);
|
||||
window.addEventListener('scroll', handleScroll, { passive: true });
|
||||
return () => window.removeEventListener('scroll', handleScroll);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
window.scrollTo(0, 0);
|
||||
setIsMobileMenuOpen(false);
|
||||
}, [pathname]);
|
||||
|
||||
const scrollToTop = () => {
|
||||
@@ -32,111 +32,160 @@ const Layout = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
const isActive = (path: string) => pathname === path;
|
||||
|
||||
const navLinks = [
|
||||
{ href: '/', label: 'Startseite', icon: Home },
|
||||
{ href: '/ueber-uns', label: 'Über uns', icon: Info },
|
||||
{ href: '/kontakt', label: 'Kontakt', icon: Mail },
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex flex-col">
|
||||
<header className="sticky top-0 z-[100] bg-bg-color/95 backdrop-blur-xl border-b border-secondary-bg pt-[env(safe-area-top)]">
|
||||
<div className="max-w-[1200px] mx-auto px-4 h-20 flex justify-between items-center">
|
||||
<div className="min-h-screen flex flex-col font-sans">
|
||||
<header
|
||||
className={`fixed top-0 left-0 right-0 z-[100] transition-all duration-300 ${
|
||||
isScrolled ? 'bg-white/80 backdrop-blur-lg border-b border-slate-200 py-2' : 'bg-transparent py-4'
|
||||
}`}
|
||||
>
|
||||
<div className="container-custom flex justify-between items-center">
|
||||
<Link
|
||||
href="/"
|
||||
className="flex items-center"
|
||||
className="relative z-10 flex items-center group"
|
||||
aria-label="MB Grid Solutions - Zur Startseite"
|
||||
>
|
||||
<img
|
||||
src="/assets/logo.png"
|
||||
alt="MB Grid Solutions"
|
||||
className="h-12 md:h-40 transition-all"
|
||||
className={`transition-all duration-300 ${isScrolled ? 'h-[90px]' : 'h-[120px] md:h-[150px]'}`}
|
||||
loading="eager"
|
||||
/>
|
||||
</Link>
|
||||
<nav className="hidden md:flex gap-8" aria-label="Hauptnavigation">
|
||||
<Link href="/" className={`text-xs font-semibold uppercase tracking-widest transition-colors ${isActive('/') ? 'text-accent-green' : 'text-text-primary hover:text-accent-green'}`}>
|
||||
Startseite
|
||||
</Link>
|
||||
<Link href="/ueber-uns" className={`text-xs font-semibold uppercase tracking-widest transition-colors ${isActive('/ueber-uns') ? 'text-accent-green' : 'text-text-primary hover:text-accent-green'}`}>
|
||||
Über uns
|
||||
</Link>
|
||||
<Link href="/kontakt" className={`text-xs font-semibold uppercase tracking-widest transition-colors ${isActive('/kontakt') ? 'text-accent-green' : 'text-text-primary hover:text-accent-green'}`}>
|
||||
Kontakt
|
||||
|
||||
{/* Desktop Navigation */}
|
||||
<nav className="hidden md:flex items-center gap-1" aria-label="Hauptnavigation">
|
||||
{navLinks.map((link) => (
|
||||
<Link
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
className={`px-4 py-2 rounded-full text-sm font-medium transition-all ${
|
||||
isActive(link.href)
|
||||
? 'text-accent bg-accent/5'
|
||||
: 'text-slate-600 hover:text-primary hover:bg-slate-50'
|
||||
}`}
|
||||
>
|
||||
{link.label}
|
||||
</Link>
|
||||
))}
|
||||
<Link
|
||||
href="/kontakt"
|
||||
className="ml-4 btn-primary !py-2 !px-5 !text-sm"
|
||||
>
|
||||
Projekt anfragen
|
||||
</Link>
|
||||
</nav>
|
||||
|
||||
{/* Mobile Menu Toggle */}
|
||||
<button
|
||||
className="md:hidden p-2 text-slate-600 hover:text-primary transition-colors"
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
aria-label="Menü öffnen"
|
||||
>
|
||||
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<main className="flex-grow pb-[calc(72px+env(safe-area-bottom))] md:pb-0">
|
||||
{/* Mobile Menu Overlay */}
|
||||
<AnimatePresence>
|
||||
{isMobileMenuOpen && (
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
animate={{ opacity: 1, y: 0 }}
|
||||
exit={{ opacity: 0, y: -20 }}
|
||||
className="fixed inset-0 z-[90] bg-white pt-24 px-6 md:hidden"
|
||||
>
|
||||
<nav className="flex flex-col gap-4">
|
||||
{navLinks.map((link) => (
|
||||
<Link
|
||||
key={link.href}
|
||||
href={link.href}
|
||||
className={`flex items-center gap-4 p-4 rounded-xl text-lg font-semibold transition-all ${
|
||||
isActive(link.href)
|
||||
? 'text-accent bg-accent/5'
|
||||
: 'text-slate-600 hover:text-primary hover:bg-slate-50'
|
||||
}`}
|
||||
>
|
||||
<link.icon size={24} />
|
||||
{link.label}
|
||||
</Link>
|
||||
))}
|
||||
<Link
|
||||
href="/kontakt"
|
||||
className="mt-4 btn-primary w-full py-4 text-center"
|
||||
>
|
||||
Projekt anfragen
|
||||
</Link>
|
||||
</nav>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
|
||||
<main className="flex-grow">
|
||||
{children}
|
||||
</main>
|
||||
|
||||
<button
|
||||
onClick={scrollToTop}
|
||||
className={`fixed bottom-24 md:bottom-8 right-5 md:right-8 w-12 md:w-14 h-12 md:h-14 bg-primary text-white rounded-full flex items-center justify-center cursor-pointer z-[900] shadow-lg transition-all duration-300 hover:-translate-y-1 hover:bg-accent-green ${showScrollTop ? 'opacity-100 visible translate-y-0' : 'opacity-0 invisible translate-y-2'}`}
|
||||
className={`fixed bottom-8 right-8 w-12 h-12 bg-primary text-white rounded-full flex items-center justify-center cursor-pointer z-[80] shadow-xl transition-all duration-300 hover:-translate-y-1 hover:bg-accent ${
|
||||
showScrollTop ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4 pointer-events-none'
|
||||
}`}
|
||||
aria-label="Nach oben scrollen"
|
||||
aria-hidden={!showScrollTop}
|
||||
tabIndex={showScrollTop ? 0 : -1}
|
||||
>
|
||||
<ArrowUp size={24} strokeWidth={2.5} />
|
||||
<ArrowUp size={20} strokeWidth={2.5} />
|
||||
</button>
|
||||
|
||||
<nav className="md:hidden fixed bottom-0 left-0 w-full h-[calc(72px+env(safe-area-bottom))] bg-white/95 backdrop-blur-2xl border-t border-black/10 flex justify-around items-start pt-2 z-[1000] px-2" aria-label="Mobile Navigation">
|
||||
<Link
|
||||
href="/"
|
||||
className={`flex flex-col items-center gap-1 text-[10px] font-semibold uppercase tracking-wider flex-1 py-2 transition-colors ${isActive('/') ? 'text-primary' : 'text-gray-400'}`}
|
||||
aria-label="Startseite"
|
||||
>
|
||||
<Home size={22} strokeWidth={2} className={isActive('/') ? 'text-accent-green scale-110' : ''} />
|
||||
<span>Start</span>
|
||||
</Link>
|
||||
<Link
|
||||
href="/ueber-uns"
|
||||
className={`flex flex-col items-center gap-1 text-[10px] font-semibold uppercase tracking-wider flex-1 py-2 transition-colors ${isActive('/ueber-uns') ? 'text-primary' : 'text-gray-400'}`}
|
||||
aria-label="Über uns"
|
||||
>
|
||||
<Info size={22} strokeWidth={2} className={isActive('/ueber-uns') ? 'text-accent-green scale-110' : ''} />
|
||||
<span>Über uns</span>
|
||||
</Link>
|
||||
<Link
|
||||
href="/kontakt"
|
||||
className={`flex flex-col items-center gap-1 text-[10px] font-semibold uppercase tracking-wider flex-1 py-2 transition-colors ${isActive('/kontakt') ? 'text-primary' : 'text-gray-400'}`}
|
||||
aria-label="Kontakt"
|
||||
>
|
||||
<Mail size={22} strokeWidth={2} className={isActive('/kontakt') ? 'text-accent-green scale-110' : ''} />
|
||||
<span>Kontakt</span>
|
||||
</Link>
|
||||
</nav>
|
||||
|
||||
<footer className="bg-white border-t border-secondary-bg py-8 md:py-16 mt-8 md:mt-16">
|
||||
<div className="max-w-[1200px] mx-auto px-4">
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-8 md:gap-12 mb-8 md:mb-12">
|
||||
<div className="flex flex-col items-center md:items-start text-center md:text-left">
|
||||
<footer className="bg-slate-900 text-slate-300 py-16 md:py-24">
|
||||
<div className="container-custom">
|
||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-12 mb-16">
|
||||
<div className="lg:col-span-2">
|
||||
<img
|
||||
src="/assets/logo.png"
|
||||
alt="MB Grid Solutions"
|
||||
className="h-16 md:h-20 mb-6 grayscale"
|
||||
className="h-20 mb-8 brightness-0 invert opacity-80"
|
||||
loading="lazy"
|
||||
/>
|
||||
<p className="text-text-secondary text-sm md:text-base leading-relaxed">
|
||||
Ihr Partner für Energiekabelprojekte bis 110 kV.
|
||||
<p className="text-slate-400 max-w-md leading-relaxed mb-8">
|
||||
Ihr spezialisierter Partner für herstellerneutrale technische Beratung und Projektbegleitung bei Energiekabelprojekten bis 110 kV.
|
||||
</p>
|
||||
<div className="flex gap-4">
|
||||
{/* Social links could go here */}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col items-center md:items-start text-center md:text-left">
|
||||
<h4 className="text-sm md:text-base font-semibold mb-4">Navigation</h4>
|
||||
<nav className="flex flex-col gap-3" aria-label="Footer Navigation">
|
||||
<Link href="/" className="text-sm md:text-[15px] hover:text-accent-green transition-colors">Startseite</Link>
|
||||
<Link href="/ueber-uns" className="text-sm md:text-[15px] hover:text-accent-green transition-colors">Über uns</Link>
|
||||
<Link href="/kontakt" className="text-sm md:text-[15px] hover:text-accent-green transition-colors">Kontakt</Link>
|
||||
|
||||
<div>
|
||||
<h4 className="text-white font-bold mb-6">Navigation</h4>
|
||||
<nav className="flex flex-col gap-4">
|
||||
{navLinks.map((link) => (
|
||||
<Link key={link.href} href={link.href} className="hover:text-accent transition-colors">
|
||||
{link.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
<div className="flex flex-col items-center md:items-start text-center md:text-left">
|
||||
<h4 className="text-sm md:text-base font-semibold mb-4">Rechtliches</h4>
|
||||
<nav className="flex flex-col gap-3" aria-label="Legal Navigation">
|
||||
<Link href="/impressum" className="text-sm md:text-[15px] hover:text-accent-green transition-colors">Impressum</Link>
|
||||
<Link href="/datenschutz" className="text-sm md:text-[15px] hover:text-accent-green transition-colors">Datenschutz</Link>
|
||||
<Link href="/agb" className="text-sm md:text-[15px] hover:text-accent-green transition-colors">AGB</Link>
|
||||
|
||||
<div>
|
||||
<h4 className="text-white font-bold mb-6">Rechtliches</h4>
|
||||
<nav className="flex flex-col gap-4">
|
||||
<Link href="/impressum" className="hover:text-accent transition-colors">Impressum</Link>
|
||||
<Link href="/datenschutz" className="hover:text-accent transition-colors">Datenschutz</Link>
|
||||
<Link href="/agb" className="hover:text-accent transition-colors">AGB</Link>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
<div className="border-t border-secondary-bg pt-8 flex flex-col md:flex-row justify-between items-center gap-4 text-text-secondary text-xs md:text-sm text-center">
|
||||
<div>© 2026 MB Grid Solutions GmbH. Alle Rechte vorbehalten.</div>
|
||||
<div>Made with precision.</div>
|
||||
|
||||
<div className="pt-8 border-t border-slate-800 flex flex-col md:flex-row justify-between items-center gap-4 text-sm text-slate-500">
|
||||
<p>© {new Date().getFullYear()} MB Grid Solutions GmbH. Alle Rechte vorbehalten.</p>
|
||||
<p className="flex items-center gap-2">
|
||||
Made with <span className="text-accent">precision</span> in Germany
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
Reference in New Issue
Block a user