refactor: eliminate all hardcoded strings in TSX components, enforce project rules in AGENTS.md, lock body scroll in cookie modal

This commit is contained in:
2026-08-26 03:09:15 +02:00
parent 8c6f3d2633
commit 434237e916
17 changed files with 475 additions and 245 deletions
+53 -41
View File
@@ -17,8 +17,9 @@ interface HeaderProps {
phone?: string | null
homeHref?: string
currentLocale?: string
contactHref?: string
contactLabel?: string
contactHref?: string | null
contactLabel?: string | null
phoneLabel?: string | null
}
export function Header({
@@ -28,8 +29,9 @@ export function Header({
phone,
homeHref = '/',
currentLocale = 'pl',
contactHref = '/kontakt',
contactLabel = 'KONTAKT',
contactHref,
contactLabel,
phoneLabel,
}: HeaderProps) {
const pathname = usePathname() || ''
const [langDropdownOpen, setLangDropdownOpen] = useState(false)
@@ -61,8 +63,8 @@ export function Header({
)
const languages = [
{ code: 'pl', label: 'PL - Polski' },
{ code: 'en', label: 'UK - English' },
{ code: 'pl', label: 'PL' },
{ code: 'en', label: 'UK' },
]
const activeLang = languages.find((l) => l.code === currentLocale) || languages[0]
@@ -70,29 +72,35 @@ export function Header({
return (
<header className="sticky top-0 z-50 w-full bg-white border-b-2 border-[#1f1f1f] shadow-xs">
{/* Top Black Utility Bar */}
<div className="bg-[#1f1f1f] text-white text-xs py-2 hidden md:block">
<div className="container mx-auto px-4 sm:px-6 lg:px-12 max-w-7xl flex items-center justify-between">
<div className="flex items-center gap-2">
<span className="inline-block w-2.5 h-2.5 bg-[#FFED00]" />
<span className="font-bold uppercase tracking-wider text-[11px] text-[#e0e0e0]">
{tagline || 'Profesjonalne Mycie i Renowacja Nawierzchni Brukowych'}
</span>
{(tagline || phone) && (
<div className="bg-[#1f1f1f] text-white text-xs py-2 hidden md:block">
<div className="container mx-auto px-4 sm:px-6 lg:px-12 max-w-7xl flex items-center justify-between">
{tagline && (
<div className="flex items-center gap-2">
<span className="inline-block w-2.5 h-2.5 bg-[#FFED00]" />
<span className="font-bold uppercase tracking-wider text-[11px] text-[#e0e0e0]">
{tagline}
</span>
</div>
)}
{phone && (
<div className="flex items-center gap-2 ml-auto">
{phoneLabel && (
<span className="font-bold uppercase tracking-wider text-[11px] text-[#e0e0e0]">
{phoneLabel}
</span>
)}
<a
href={`tel:${phone.replace(/\s+/g, '')}`}
className="font-black uppercase tracking-wider text-[11px] text-[#FFED00] hover:underline font-mono"
>
{phone}
</a>
</div>
)}
</div>
{phone && (
<div className="flex items-center gap-2">
<span className="font-bold uppercase tracking-wider text-[11px] text-[#e0e0e0]">
Infolinia / Bezpłatna wycena:
</span>
<a
href={`tel:${phone.replace(/\s+/g, '')}`}
className="font-black uppercase tracking-wider text-[11px] text-[#FFED00] hover:underline font-mono"
>
{phone}
</a>
</div>
)}
</div>
</div>
)}
{/* Main Navigation Bar */}
<div className="container mx-auto flex h-20 items-center justify-between px-4 sm:px-6 lg:px-12 max-w-7xl">
@@ -106,13 +114,15 @@ export function Header({
{companyName}
</span>
)}
<span className="text-[10px] uppercase tracking-widest text-[#666666] font-bold block mt-1">
Czyszczenie Kostki Brukowej
</span>
{tagline && (
<span className="text-[10px] uppercase tracking-widest text-[#666666] font-bold block mt-1">
{tagline}
</span>
)}
</div>
</a>
{/* Navigation Items (Without duplicated Kontakt) */}
{/* Navigation Items */}
{filteredNavItems && filteredNavItems.length > 0 && (
<nav className="hidden lg:flex items-center gap-8 text-xs font-black uppercase tracking-wider text-[#1f1f1f]">
{filteredNavItems.map((item, idx) => (
@@ -128,7 +138,7 @@ export function Header({
)}
<div className="flex items-center gap-4">
{/* Wysuwany przełącznik języków (Dropdown Language Switcher) */}
{/* Wysuwany przełącznik języków */}
<div className="relative" ref={dropdownRef}>
<button
type="button"
@@ -141,7 +151,7 @@ export function Header({
</button>
{langDropdownOpen && (
<div className="absolute right-0 mt-1 w-36 bg-white border-2 border-[#1f1f1f] shadow-xl z-50 py-1">
<div className="absolute right-0 mt-1 w-28 bg-white border-2 border-[#1f1f1f] shadow-xl z-50 py-1">
{languages.map((lang) => (
<a
key={lang.code}
@@ -161,14 +171,16 @@ export function Header({
)}
</div>
{/* Right CTA Button: KONTAKT */}
<a
href={contactHref}
className="inline-flex items-center gap-2 bg-[#FFED00] hover:bg-[#fae100] text-[#1f1f1f] border-2 border-[#1f1f1f] px-6 py-3 text-xs font-black uppercase tracking-widest transition-colors shadow-xs"
>
<span>{contactLabel}</span>
<ArrowRight className="h-4 w-4" />
</a>
{/* Right CTA Button */}
{contactHref && contactLabel && (
<a
href={contactHref}
className="inline-flex items-center gap-2 bg-[#FFED00] hover:bg-[#fae100] text-[#1f1f1f] border-2 border-[#1f1f1f] px-6 py-3 text-xs font-black uppercase tracking-widest transition-colors shadow-xs"
>
<span>{contactLabel}</span>
<ArrowRight className="h-4 w-4" />
</a>
)}
</div>
</div>
</header>