feat: redesign Header and Footer to match premium UI
This commit is contained in:
@@ -27,54 +27,57 @@ export function Footer({
|
||||
const phone = getLocText(companyInfo.phone);
|
||||
const email = getLocText(companyInfo.email);
|
||||
const hours = getLocText(companyInfo.hours);
|
||||
const whatsapp = companyInfo.whatsappNumber?.[currentLocaleCode] || companyInfo.whatsappNumber?.pl || process.env.NEXT_PUBLIC_WHATSAPP_NUMBER || '';
|
||||
|
||||
const assocTitle = getLocText(association.title);
|
||||
const assocLink = association.link;
|
||||
const assocLogo = association.logo;
|
||||
|
||||
return (
|
||||
<footer className="bg-muted py-12 md:py-16 border-t border-border mt-auto">
|
||||
<div className="container-premium grid grid-cols-1 md:grid-cols-3 gap-12 md:gap-8">
|
||||
<footer className="bg-card py-16 md:py-24 mt-auto">
|
||||
<div className="container-premium grid grid-cols-1 md:grid-cols-3 gap-16 md:gap-12">
|
||||
|
||||
{/* Kolumna 1: Dane kontaktowe */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<Link href={`/${currentLocaleCode}`} className="group flex items-center gap-3 w-fit mb-2">
|
||||
<div className="w-10 h-10 rounded bg-[var(--accent-color)] text-white flex items-center justify-center font-heading font-bold text-xl group-hover:bg-[var(--accent-hover-color)] transition-colors shadow-sm">
|
||||
<div className="flex flex-col gap-6">
|
||||
<Link href={`/${currentLocaleCode}`} className="group flex items-center gap-3 w-fit mb-4">
|
||||
<div className="w-10 h-10 rounded bg-accent text-white flex items-center justify-center font-heading font-bold text-xl group-hover:bg-accent-hover transition-colors shadow-sm">
|
||||
JK
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-heading font-bold text-lg leading-tight tracking-tight text-foreground">
|
||||
Finanz- & Lohnbuchhaltung
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground uppercase tracking-widest font-medium">
|
||||
<span className="text-xs text-foreground/60 uppercase tracking-widest font-medium">
|
||||
Dipl.-Ing. Janusz Kędzierski
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
<ul className="flex flex-col gap-3 text-sm text-muted-foreground mt-2">
|
||||
<h3 className="text-sm font-semibold text-foreground/60 uppercase tracking-wider">
|
||||
{currentLocaleCode === 'de' ? 'Kontakt' : 'Kontakt'}
|
||||
</h3>
|
||||
|
||||
<ul className="flex flex-col gap-4 text-sm text-foreground/80">
|
||||
{address && (
|
||||
<li className="flex items-start gap-3">
|
||||
<MapPin size={18} className="shrink-0 text-foreground/50 mt-0.5" />
|
||||
<MapPin size={18} className="shrink-0 text-foreground/40 mt-0.5" />
|
||||
<span className="whitespace-pre-line">{address}</span>
|
||||
</li>
|
||||
)}
|
||||
{phone && (
|
||||
<li className="flex items-center gap-3">
|
||||
<Phone size={18} className="shrink-0 text-foreground/50" />
|
||||
<a href={`tel:${phone.replace(/\s+/g, '')}`} className="hover:text-foreground transition-colors">{phone}</a>
|
||||
<Phone size={18} className="shrink-0 text-foreground/40" />
|
||||
<a href={`tel:${phone.replace(/\s+/g, '')}`} className="hover:text-accent transition-colors">{phone}</a>
|
||||
</li>
|
||||
)}
|
||||
{email && (
|
||||
<li className="flex items-center gap-3">
|
||||
<Mail size={18} className="shrink-0 text-foreground/50" />
|
||||
<a href={`mailto:${email}`} className="hover:text-foreground transition-colors">{email}</a>
|
||||
<Mail size={18} className="shrink-0 text-foreground/40" />
|
||||
<a href={`mailto:${email}`} className="hover:text-accent transition-colors">{email}</a>
|
||||
</li>
|
||||
)}
|
||||
{hours && (
|
||||
<li className="flex items-start gap-3">
|
||||
<Clock size={18} className="shrink-0 text-foreground/50 mt-0.5" />
|
||||
<Clock size={18} className="shrink-0 text-foreground/40 mt-0.5" />
|
||||
<span className="whitespace-pre-line">{hours}</span>
|
||||
</li>
|
||||
)}
|
||||
@@ -82,36 +85,36 @@ export function Footer({
|
||||
</div>
|
||||
|
||||
{/* Kolumna 2: Nawigacja / Linki */}
|
||||
<div className="flex flex-col gap-4 md:px-8">
|
||||
<h3 className="font-heading font-semibold text-lg text-foreground">
|
||||
<div className="flex flex-col gap-6 md:px-8">
|
||||
<h3 className="text-sm font-semibold text-foreground/60 uppercase tracking-wider">
|
||||
{currentLocaleCode === 'de' ? 'Navigation' : 'Nawigacja'}
|
||||
</h3>
|
||||
<nav className="flex flex-col gap-3">
|
||||
<nav className="flex flex-col gap-4">
|
||||
{navItems.map((page, index) => (
|
||||
<LocalizedLink
|
||||
key={index}
|
||||
page={page}
|
||||
currentLocaleCode={currentLocaleCode}
|
||||
className="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors w-fit"
|
||||
className="text-foreground/80 hover:text-accent font-medium transition-colors w-fit"
|
||||
/>
|
||||
))}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
{/* Kolumna 3: Stowarzyszenie */}
|
||||
<div className="flex flex-col gap-4">
|
||||
<h3 className="font-heading font-semibold text-lg text-foreground">
|
||||
<div className="flex flex-col gap-6">
|
||||
<h3 className="text-sm font-semibold text-foreground/60 uppercase tracking-wider">
|
||||
{currentLocaleCode === 'de' ? 'Mitgliedschaft' : 'Członkostwo'}
|
||||
</h3>
|
||||
<div className="bg-background border border-border p-5 rounded-xl shadow-sm flex flex-col gap-4 items-start">
|
||||
<span className="text-sm text-muted-foreground leading-relaxed">
|
||||
<div className="bg-background border border-border p-6 rounded-2xl shadow-sm flex flex-col gap-5 items-start">
|
||||
<span className="text-sm text-foreground/80 leading-relaxed font-medium">
|
||||
{assocTitle}
|
||||
</span>
|
||||
{assocLogo && typeof assocLogo === 'object' && assocLogo.url && (
|
||||
<img
|
||||
src={assocLogo.url}
|
||||
alt={assocLogo.alt || 'Logo'}
|
||||
className="h-12 w-auto object-contain"
|
||||
className="h-14 w-auto object-contain"
|
||||
/>
|
||||
)}
|
||||
{assocLink && (
|
||||
@@ -119,10 +122,10 @@ export function Footer({
|
||||
href={assocLink}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-2 text-sm font-semibold text-[var(--accent-color)] hover:text-[var(--accent-hover-color)] transition-colors mt-2 group"
|
||||
className="flex items-center gap-2 text-sm font-semibold text-accent hover:text-accent-hover transition-colors mt-2 group"
|
||||
>
|
||||
<span>{currentLocaleCode === 'de' ? 'Website besuchen' : 'Odwiedź stronę'}</span>
|
||||
<ExternalLink size={14} className="group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform" />
|
||||
<ExternalLink size={16} className="group-hover:translate-x-0.5 group-hover:-translate-y-0.5 transition-transform" />
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
@@ -130,11 +133,11 @@ export function Footer({
|
||||
|
||||
</div>
|
||||
|
||||
<div className="container-premium mt-12 pt-8 border-t border-border/50 flex flex-col sm:flex-row justify-between items-center gap-4 text-xs text-muted-foreground">
|
||||
<div className="container-premium mt-16 pt-8 border-t border-border flex flex-col md:flex-row justify-between items-center gap-6 text-sm text-foreground/50">
|
||||
<p>© {new Date().getFullYear()} Finanz- & Lohnbuchhaltung Dipl.-Ing. Janusz Kędzierski. {currentLocaleCode === 'de' ? 'Alle Rechte vorbehalten.' : 'Wszelkie prawa zastrzeżone.'}</p>
|
||||
<p className="flex items-center gap-1">
|
||||
<p className="flex items-center gap-2 font-medium">
|
||||
{currentLocaleCode === 'de' ? 'Erstellt von' : 'Realizacja:'}
|
||||
<a href="#" className="font-medium hover:text-foreground transition-colors">Intecion</a>
|
||||
<a href="#" className="hover:text-accent transition-colors">Intecion</a>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@@ -4,7 +4,7 @@ import Link from "next/link";
|
||||
import { ThemeSwitcher } from "../ThemeSwitcher";
|
||||
import { LanguageSwitcher } from "../LanguageSwitcher";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { Menu, X, MessageCircle } from "lucide-react";
|
||||
import { i18n } from '../../i18n.config';
|
||||
import { LocalizedLink } from '../LocalizedLink';
|
||||
@@ -12,61 +12,78 @@ import { LocalizedLink } from '../LocalizedLink';
|
||||
export function Header({ navItems = [] }: { navItems?: any[] }) {
|
||||
const pathname = usePathname();
|
||||
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
|
||||
const [isScrolled, setIsScrolled] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
const handleScroll = () => {
|
||||
setIsScrolled(window.scrollY > 10);
|
||||
};
|
||||
window.addEventListener("scroll", handleScroll);
|
||||
return () => window.removeEventListener("scroll", handleScroll);
|
||||
}, []);
|
||||
|
||||
// Zabezpieczenie przed błędem, gdy pathname jest puste podczas SSR
|
||||
const currentLocaleCode = (pathname?.split('/').filter(Boolean)[0]) || i18n.defaultLocale;
|
||||
const currentLocale = i18n.locales.find(l => l.code === currentLocaleCode) || i18n.locales[0];
|
||||
|
||||
return (
|
||||
<header className="fixed top-0 left-0 right-0 z-40 bg-background/80 backdrop-blur-md border-b border-border">
|
||||
<div className="container-premium h-24 flex items-center justify-between">
|
||||
<>
|
||||
<header
|
||||
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
|
||||
isScrolled
|
||||
? "bg-background/90 backdrop-blur-md shadow-sm border-b border-border py-4"
|
||||
: "bg-transparent py-6"
|
||||
}`}
|
||||
>
|
||||
<div className="container-premium flex items-center justify-between">
|
||||
{/* Logo */}
|
||||
<Link href={`/${currentLocale.code}`} className="group flex items-center gap-3 z-50 relative">
|
||||
<div className="w-10 h-10 rounded bg-[var(--accent-color)] text-white flex items-center justify-center font-heading font-bold text-xl group-hover:bg-[var(--accent-hover-color)] transition-colors shadow-sm">
|
||||
<Link href={`/${currentLocale.code}`} className="group flex items-center gap-3 z-50">
|
||||
<div className="w-10 h-10 rounded bg-accent text-white flex items-center justify-center font-heading font-bold text-xl group-hover:bg-accent-hover transition-colors shadow-sm">
|
||||
JK
|
||||
</div>
|
||||
<div className="flex flex-col">
|
||||
<span className="font-heading font-bold text-lg leading-tight tracking-tight text-foreground">
|
||||
Finanz- & Lohnbuchhaltung
|
||||
</span>
|
||||
<span className="text-xs text-muted-foreground uppercase tracking-widest font-medium">
|
||||
<span className="text-xs text-foreground/60 uppercase tracking-widest font-medium">
|
||||
Dipl.-Ing. Janusz Kędzierski
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* Desktop Navigation */}
|
||||
<nav className="hidden lg:flex items-center gap-8 absolute left-1/2 -translate-x-1/2">
|
||||
<nav className="hidden xl:flex items-center gap-10">
|
||||
{navItems.map((page, index) => (
|
||||
<LocalizedLink
|
||||
key={index}
|
||||
page={page}
|
||||
currentLocaleCode={currentLocale.code}
|
||||
className="text-sm font-medium text-muted-foreground hover:text-foreground transition-colors"
|
||||
className="text-sm font-medium text-foreground/80 hover:text-accent transition-colors"
|
||||
/>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* Right Actions & Hamburger */}
|
||||
<div className="flex items-center gap-3 z-50 relative">
|
||||
<div className="hidden sm:flex items-center gap-3 mr-2">
|
||||
<div className="flex items-center gap-4 z-50">
|
||||
<div className="hidden sm:flex items-center gap-4">
|
||||
<Link
|
||||
href={process.env.NEXT_PUBLIC_WHATSAPP_NUMBER ? `https://wa.me/${process.env.NEXT_PUBLIC_WHATSAPP_NUMBER}` : '#'}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center justify-center w-10 h-10 rounded-full bg-green-500 hover:bg-green-600 text-white transition-colors"
|
||||
aria-label="WhatsApp"
|
||||
className="flex items-center gap-2 px-5 py-2.5 rounded-full bg-green-500 hover:bg-green-600 text-white transition-colors font-medium text-sm shadow-sm"
|
||||
>
|
||||
<MessageCircle size={20} />
|
||||
<MessageCircle size={18} />
|
||||
<span className="hidden lg:inline">WhatsApp</span>
|
||||
</Link>
|
||||
<div className="w-px h-6 bg-border" />
|
||||
<div className="w-px h-6 bg-border mx-2 hidden xl:block" />
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2">
|
||||
<ThemeSwitcher />
|
||||
<LanguageSwitcher />
|
||||
</div>
|
||||
|
||||
<button
|
||||
className="lg:hidden w-10 h-10 flex items-center justify-center text-foreground rounded-full hover:bg-accent transition-colors ml-2"
|
||||
className="xl:hidden w-11 h-11 flex items-center justify-center text-foreground rounded-full hover:bg-accent/10 transition-colors ml-1"
|
||||
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
|
||||
aria-label="Toggle menu"
|
||||
>
|
||||
@@ -74,35 +91,39 @@ export function Header({ navItems = [] }: { navItems?: any[] }) {
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
{/* Mobile Navigation */}
|
||||
{isMobileMenuOpen && (
|
||||
<div className="lg:hidden absolute top-24 left-0 right-0 bg-background border-b border-border p-6 shadow-xl flex flex-col gap-6 animate-in fade-in slide-in-from-top-4 duration-200">
|
||||
<nav className="flex flex-col gap-4">
|
||||
{/* Mobile Fullscreen Navigation */}
|
||||
<div
|
||||
className={`fixed inset-0 z-40 bg-background/95 backdrop-blur-xl transition-all duration-300 xl:hidden flex flex-col justify-center items-center ${
|
||||
isMobileMenuOpen ? "opacity-100 visible" : "opacity-0 invisible pointer-events-none"
|
||||
}`}
|
||||
>
|
||||
<nav className="flex flex-col gap-8 text-center w-full px-6">
|
||||
{navItems.map((page, index) => (
|
||||
<LocalizedLink
|
||||
key={index}
|
||||
page={page}
|
||||
currentLocaleCode={currentLocale.code}
|
||||
className="text-lg font-medium text-foreground py-2 border-b border-border/50"
|
||||
className="text-2xl font-bold text-foreground hover:text-accent transition-colors"
|
||||
onClick={() => setIsMobileMenuOpen(false)}
|
||||
/>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
<div className="flex items-center justify-center sm:hidden mt-4 pt-4 border-t border-border/50">
|
||||
<div className="absolute bottom-12 left-0 right-0 px-6 sm:hidden flex flex-col items-center">
|
||||
<div className="w-full h-px bg-border/50 mb-8 max-w-xs" />
|
||||
<Link
|
||||
href={process.env.NEXT_PUBLIC_WHATSAPP_NUMBER ? `https://wa.me/${process.env.NEXT_PUBLIC_WHATSAPP_NUMBER}` : '#'}
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="flex items-center gap-2 bg-green-500 hover:bg-green-600 text-white px-6 py-3 rounded-full transition-colors w-full justify-center"
|
||||
className="flex items-center justify-center gap-2 bg-green-500 hover:bg-green-600 text-white px-8 py-4 rounded-full transition-colors w-full max-w-xs shadow-lg"
|
||||
>
|
||||
<MessageCircle size={20} />
|
||||
<span className="font-medium">Napisz na WhatsApp</span>
|
||||
<MessageCircle size={24} />
|
||||
<span className="font-bold text-lg">WhatsApp</span>
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</header>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user