280 lines
9.2 KiB
TypeScript
280 lines
9.2 KiB
TypeScript
"use client";
|
|
|
|
import { useState, useEffect } from "react";
|
|
import Link from "next/link";
|
|
import { User, ShoppingBag, Menu, Phone } from "lucide-react";
|
|
import { NavDropdown } from "./NavDropdown";
|
|
import { GlobalSearch } from "./GlobalSearch";
|
|
import { MobileMenu } from "./MobileMenu";
|
|
import { useCartStore } from "@/lib/cart-store";
|
|
import { companyDetails } from "@/content/company";
|
|
import { cn } from "@/lib/utils";
|
|
|
|
export function Header() {
|
|
const [isScrolled, setIsScrolled] = useState(false);
|
|
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
|
const [mounted, setMounted] = useState(false);
|
|
|
|
const cartItems = useCartStore((state) => state.items);
|
|
|
|
useEffect(() => {
|
|
setMounted(true);
|
|
const handleScroll = () => {
|
|
if (window.scrollY > 40) {
|
|
setIsScrolled(true);
|
|
} else {
|
|
setIsScrolled(false);
|
|
}
|
|
};
|
|
|
|
window.addEventListener("scroll", handleScroll);
|
|
return () => window.removeEventListener("scroll", handleScroll);
|
|
}, []);
|
|
|
|
const cartCount = mounted
|
|
? cartItems.reduce((total, item) => total + item.quantity, 0)
|
|
: 0;
|
|
|
|
const acSections = [
|
|
{
|
|
title: "Klimatyzatory",
|
|
items: [
|
|
{
|
|
label: "Ścienne split",
|
|
href: "/sklep?category=scienne",
|
|
description: "Klasyczne jednostki ścienne do mieszkań",
|
|
},
|
|
{
|
|
label: "Multisplit",
|
|
href: "/sklep?category=multisplit",
|
|
description: "Systemy wielopokojowe (2-5 pomieszczeń)",
|
|
},
|
|
{
|
|
label: "Przenośne",
|
|
href: "/sklep?category=przenosne",
|
|
description: "Mobilne chłodzenie bez stałej instalacji",
|
|
},
|
|
{
|
|
label: "Kasetonowe i konsolowe",
|
|
href: "/sklep?category=kasetonowe",
|
|
description: "Modele biurowe i przypodłogowe",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: "Usługi HVAC",
|
|
items: [
|
|
{
|
|
label: "Montaż klimatyzacji",
|
|
href: "/klimatyzacja",
|
|
description: "Kompleksowy dobór, audyt i montaż",
|
|
},
|
|
{
|
|
label: "Serwis i czyszczenie",
|
|
href: "/klimatyzacja",
|
|
description: "Odgrzybianie, naprawy i przeglądy",
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
const homeSections = [
|
|
{
|
|
title: "Prace wykończeniowe",
|
|
items: [
|
|
{
|
|
label: "Remonty i wykończenia",
|
|
href: "/uslugi-domowe/remonty",
|
|
description: "Kompleksowe remonty mieszkań i łazienek",
|
|
},
|
|
{
|
|
label: "Drobne naprawy",
|
|
href: "/uslugi-domowe",
|
|
description: "Pomoc „złotej rączki” w drobnych usterkach",
|
|
},
|
|
],
|
|
},
|
|
{
|
|
title: "Instalacje i AGD",
|
|
items: [
|
|
{
|
|
label: "Hydraulika",
|
|
href: "/uslugi-domowe/hydraulika",
|
|
description: "Montaż armatury, naprawy i instalacje wod-kan",
|
|
},
|
|
{
|
|
label: "Serwis AGD / Lodówki",
|
|
href: "/uslugi-domowe/serwis-agd",
|
|
description: "Szybka naprawa lodówek i urządzeń chłodniczych",
|
|
},
|
|
],
|
|
},
|
|
];
|
|
|
|
return (
|
|
<>
|
|
{/* ----------------- DESKTOP: TOP BAR ----------------- */}
|
|
<div className="hidden lg:block bg-muted py-2 border-b border-border/50">
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between">
|
|
{/* Top Bar Left: Logo */}
|
|
<Link href="/" className="shrink-0 flex items-center gap-3">
|
|
<span className="text-2xl font-bold font-heading text-primary">
|
|
{companyDetails.shortName}
|
|
<span className="text-accent">.</span>
|
|
</span>
|
|
<span className="text-xs text-muted-foreground font-medium border-l border-border pl-3">
|
|
Klimatyzacja i usługi domowe
|
|
</span>
|
|
</Link>
|
|
|
|
{/* Top Bar Right: Phone & Icons */}
|
|
<div className="flex items-center gap-6">
|
|
<a
|
|
href={`tel:${companyDetails.phoneRaw}`}
|
|
className="flex items-center gap-2 text-sm font-semibold text-primary hover:text-accent transition-colors whitespace-nowrap"
|
|
>
|
|
<Phone className="size-4 text-accent" />
|
|
<span>{companyDetails.phone}</span>
|
|
</a>
|
|
|
|
<div className="flex items-center gap-1">
|
|
<GlobalSearch />
|
|
|
|
<Link
|
|
href="/koszyk"
|
|
className="p-2 text-primary hover:text-accent hover:bg-background rounded-lg transition-colors relative outline-none"
|
|
aria-label={`Koszyk z ${cartCount} przedmiotami`}
|
|
>
|
|
<ShoppingBag className="size-5" />
|
|
{cartCount > 0 && (
|
|
<span className="absolute top-0 right-0 bg-cta text-white text-[10px] font-bold size-4 rounded-full flex items-center justify-center translate-x-0.5 -translate-y-0.5">
|
|
{cartCount}
|
|
</span>
|
|
)}
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{/* ----------------- DESKTOP: NAV BAR (STICKY) ----------------- */}
|
|
<header
|
|
className={cn(
|
|
"hidden lg:block sticky top-0 z-40 bg-background transition-all duration-300 border-b border-border",
|
|
isScrolled ? "shadow-md py-2" : "py-4"
|
|
)}
|
|
>
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center justify-between">
|
|
{/* Main Navigation */}
|
|
<nav className="flex items-center gap-8">
|
|
{isScrolled && (
|
|
<Link href="/" className="shrink-0 flex items-center mr-2">
|
|
<span className="text-xl font-bold font-heading text-primary">
|
|
{companyDetails.shortName}
|
|
<span className="text-accent">.</span>
|
|
</span>
|
|
</Link>
|
|
)}
|
|
|
|
<NavDropdown
|
|
label="Klimatyzacja"
|
|
triggerHref="/klimatyzacja"
|
|
sections={acSections}
|
|
align="left"
|
|
/>
|
|
<Link
|
|
href="/pompy-ciepla"
|
|
className="text-sm font-medium text-primary hover:text-accent transition-colors"
|
|
>
|
|
Pompy ciepła
|
|
</Link>
|
|
<NavDropdown
|
|
label="Usługi domowe"
|
|
triggerHref="/uslugi-domowe"
|
|
sections={homeSections}
|
|
/>
|
|
<Link
|
|
href="/realizacje"
|
|
className="text-sm font-medium text-primary hover:text-accent transition-colors"
|
|
>
|
|
Realizacje
|
|
</Link>
|
|
<Link
|
|
href="/blog"
|
|
className="text-sm font-medium text-primary hover:text-accent transition-colors"
|
|
>
|
|
Blog
|
|
</Link>
|
|
<Link
|
|
href="/o-nas"
|
|
className="text-sm font-medium text-primary hover:text-accent transition-colors"
|
|
>
|
|
O nas
|
|
</Link>
|
|
<Link
|
|
href="/kontakt"
|
|
className="text-sm font-medium text-primary hover:text-accent transition-colors"
|
|
>
|
|
Kontakt
|
|
</Link>
|
|
</nav>
|
|
|
|
{/* CTA Button */}
|
|
<Link href="/kontakt" className="hidden lg:flex">
|
|
<button className="btn btn-primary font-bold">
|
|
Darmowa wycena
|
|
</button>
|
|
</Link>
|
|
</div>
|
|
</header>
|
|
|
|
{/* ----------------- MOBILE: HEADER (STICKY) ----------------- */}
|
|
<header
|
|
className={cn(
|
|
"lg:hidden sticky top-0 z-40 bg-background border-b border-border transition-all duration-300",
|
|
isScrolled ? "shadow-md py-3" : "py-4"
|
|
)}
|
|
>
|
|
<div className="max-w-7xl mx-auto px-4 sm:px-6 flex items-center justify-between">
|
|
{/* Mobile Logo */}
|
|
<Link href="/" className="shrink-0 flex items-center">
|
|
<span className="text-xl font-bold font-heading text-primary">
|
|
{companyDetails.shortName}
|
|
<span className="text-accent">.</span>
|
|
</span>
|
|
</Link>
|
|
|
|
{/* Mobile Icons (Cart + Hamburger) */}
|
|
<div className="flex items-center gap-3">
|
|
<Link
|
|
href="/koszyk"
|
|
className="p-2 text-primary hover:text-accent transition-colors relative outline-none"
|
|
aria-label={`Koszyk z ${cartCount} przedmiotami`}
|
|
>
|
|
<ShoppingBag className="size-6" />
|
|
{cartCount > 0 && (
|
|
<span className="absolute top-0 right-0 bg-cta text-white text-[10px] font-bold size-4 rounded-full flex items-center justify-center translate-x-0.5 -translate-y-0.5">
|
|
{cartCount}
|
|
</span>
|
|
)}
|
|
</Link>
|
|
<button
|
|
onClick={() => setIsMobileMenuOpen(true)}
|
|
className="p-2 text-primary hover:text-accent hover:bg-muted transition-colors rounded-lg outline-none"
|
|
aria-label="Otwórz menu"
|
|
>
|
|
<Menu className="size-6" />
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</header>
|
|
|
|
{/* ----------------- MOBILE MENU DRAWER ----------------- */}
|
|
<MobileMenu
|
|
isOpen={isMobileMenuOpen}
|
|
onClose={() => setIsMobileMenuOpen(false)}
|
|
/>
|
|
</>
|
|
);
|
|
}
|