feat: setup globals (Footer), sqlite migration, seed update and access rules

This commit is contained in:
MichalC
2026-08-31 22:37:06 +02:00
parent 5f2eaa0b37
commit 5a9128e2f5
31 changed files with 2281 additions and 362 deletions
+108
View File
@@ -0,0 +1,108 @@
"use client";
import Link from "next/link";
import { ThemeSwitcher } from "../ThemeSwitcher";
import { LanguageSwitcher } from "../LanguageSwitcher";
import { usePathname } from "next/navigation";
import { useState } from "react";
import { Menu, X, MessageCircle } from "lucide-react";
import { i18n } from '../../i18n.config';
import { LocalizedLink } from '../LocalizedLink';
export function Header({ navItems = [] }: { navItems?: any[] }) {
const pathname = usePathname();
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
// 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">
{/* 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">
JK
</div>
<div className="flex flex-col">
<span className="font-heading font-bold text-lg leading-tight tracking-tight text-foreground">
Janusz Kędzierski
</span>
<span className="text-xs text-muted-foreground uppercase tracking-widest font-medium">
Doradztwo Podatkowe
</span>
</div>
</Link>
{/* Desktop Navigation */}
<nav className="hidden lg:flex items-center gap-8 absolute left-1/2 -translate-x-1/2">
{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"
/>
))}
</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">
<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"
>
<MessageCircle size={20} />
</Link>
<div className="w-px h-6 bg-border" />
</div>
<ThemeSwitcher />
<LanguageSwitcher />
<button
className="lg:hidden w-10 h-10 flex items-center justify-center text-foreground rounded-full hover:bg-accent transition-colors ml-2"
onClick={() => setIsMobileMenuOpen(!isMobileMenuOpen)}
aria-label="Toggle menu"
>
{isMobileMenuOpen ? <X size={24} /> : <Menu size={24} />}
</button>
</div>
</div>
{/* 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">
{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"
onClick={() => setIsMobileMenuOpen(false)}
/>
))}
</nav>
<div className="flex items-center justify-center sm:hidden mt-4 pt-4 border-t border-border/50">
<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"
>
<MessageCircle size={20} />
<span className="font-medium">Napisz na WhatsApp</span>
</Link>
</div>
</div>
)}
</header>
);
}