diff --git a/AGENTS.md b/AGENTS.md index 643577d..b00b5ca 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,3 +7,26 @@ This version has breaking changes — APIs, conventions, and file structure may This block is written and re-added by `next dev` — verify at `node_modules/next/dist/server/lib/generate-agent-files.js`. Removing it from a diff only re-creates the uncommitted change; committing it with your work keeps the tree clean. + +# POI Clean House - Project Rules & Guidelines + +## 1. ABSOLUTELY NO HARDCODED STRINGS IN TSX/COMPONENT FILES +- **Strict Rule:** Never hardcode text strings, button labels, contact details, headings, descriptions, footers, headers, badges, or placeholder texts in `.tsx` components or page files. +- **Dynamic Source:** All content MUST come dynamically from Payload CMS (collections, globals like `Company` and `Navigation`, block fields, seed script, or `@intecion/ipal-kit`). +- If a prop is optional, render it conditionally only when present (`{prop && {prop}}`), NEVER provide fallback hardcoded Polish or English text inside JSX. + +## 2. BRANDING & UI GUIDELINES (KÄRCHER STYLE) +- Colors: + - Primary Yellow: `#FFED00` (Hover: `#FAE100`) + - Dark Anthracite: `#1F1F1F` + - Deep Black: `#141414` + - Industrial Light Gray: `#F4F4F4` +- Architecture: + - Sharp, geometric corners (`rounded-none` / `0px radius`). No bubbly rounded-3xl or generic AI circles. + - Checkboxes: Square with 2px black border, yellow `#FFED00` checked background, and thick black checkmark (`stroke-[3]`). + - High contrast typography: Uppercase, bold/black weights with letter-spacing. + +## 3. UX & ACCESSIBILITY +- Modals & Overlays: + - Must lock background scrolling (`document.body.style.overflow = 'hidden'`) when open to prevent background page scroll leakage. + - Must support close on button, Escape key, or backdrop click. diff --git a/src/app/(frontend)/[locale]/[[...slug]]/page.tsx b/src/app/(frontend)/[locale]/[[...slug]]/page.tsx index 4997e28..a5bc1e5 100644 --- a/src/app/(frontend)/[locale]/[[...slug]]/page.tsx +++ b/src/app/(frontend)/[locale]/[[...slug]]/page.tsx @@ -18,54 +18,12 @@ interface PageProps { const pageMetadata = createPageMetadata({ config: i18nConfig, - baseUrl: process.env.NEXT_PUBLIC_SERVER_URL || 'http://localhost:3000', + baseUrl: process.env.NEXT_PUBLIC_SERVER_URL, }) export async function generateMetadata({ params }: PageProps): Promise { const { locale, slug } = await params - const payload = await getCachedPayload() - const baseMeta = await pageMetadata({ payload, locale, slug: slug ?? [] }) - - const baseUrl = process.env.NEXT_PUBLIC_SERVER_URL || 'http://localhost:3000' - const fallbackOgImage = `${baseUrl}/images/paving-hero.webp` - - const ogImages = - baseMeta.openGraph?.images && (baseMeta.openGraph.images as unknown[]).length > 0 - ? baseMeta.openGraph.images - : [ - { - url: fallbackOgImage, - width: 1920, - height: 1080, - alt: 'POI Clean House - Czyszczenie Kostki Brukowej', - }, - ] - - return { - ...baseMeta, - title: baseMeta.title || 'POI Clean House | Profesjonalne Czyszczenie Kostki Brukowej', - description: - baseMeta.description || - 'Specjalistyczne mycie gorącowodne do 100°C, odplamianie oleju, piaskowanie i impregnacja hydrofobowa kostki brukowej. Sprawdź bezpłatną wycenę!', - openGraph: { - ...baseMeta.openGraph, - title: (baseMeta.title as string) || 'POI Clean House | Profesjonalne Czyszczenie Kostki Brukowej', - description: - baseMeta.description || - 'Specjalistyczne mycie gorącowodne do 100°C, odplamianie oleju, piaskowanie i impregnacja hydrofobowa kostki brukowej. Sprawdź bezpłatną wycenę!', - images: ogImages, - type: 'website', - siteName: 'POI Clean House', - }, - twitter: { - card: 'summary_large_image', - title: (baseMeta.title as string) || 'POI Clean House | Profesjonalne Czyszczenie Kostki Brukowej', - description: - baseMeta.description || - 'Specjalistyczne mycie gorącowodne do 100°C, odplamianie oleju, piaskowanie i impregnacja hydrofobowa kostki brukowej.', - images: [fallbackOgImage], - }, - } + return pageMetadata({ payload: await getCachedPayload(), locale, slug: slug ?? [] }) } export default async function Page({ params, searchParams }: PageProps) { diff --git a/src/app/(frontend)/[locale]/layout.tsx b/src/app/(frontend)/[locale]/layout.tsx index 731a73b..47d821e 100644 --- a/src/app/(frontend)/[locale]/layout.tsx +++ b/src/app/(frontend)/[locale]/layout.tsx @@ -97,6 +97,11 @@ export default async function LocaleLayout({ children, params }: LayoutProps) { href: resolveNavItemHref(item), })) || [] + const contactHref = + navigation?.ctaButton?.url || + (navigation?.ctaButton?.page ? resolveNavItemHref(navigation.ctaButton) : undefined) + const contactLabel = navigation?.ctaButton?.label + return ( @@ -106,10 +111,11 @@ export default async function LocaleLayout({ children, params }: LayoutProps) { tagline={navigation?.tagline} items={headerItems} phone={company?.phone} + phoneLabel={(navigation as { phoneLabel?: string })?.phoneLabel} homeHref={homeHref} currentLocale={locale} - contactHref={`/${locale}/kontakt`} - contactLabel="KONTAKT" + contactHref={contactHref} + contactLabel={contactLabel} />
{children}