Files
klz-cables.com/app/[locale]/contact/page.tsx
Marc Mintel a0cfa8ef62
All checks were successful
Build & Deploy KLZ Cables / deploy (push) Successful in 5m8s
mailing
2026-01-25 13:36:25 +01:00

210 lines
9.8 KiB
TypeScript

import { useTranslations } from 'next-intl';
import { getTranslations } from 'next-intl/server';
import { Metadata } from 'next';
import JsonLd from '@/components/JsonLd';
import { getBreadcrumbSchema, SITE_URL, LOGO_URL } from '@/lib/schema';
import { Section, Container, Heading } from '@/components/ui';
import ContactForm from '@/components/ContactForm';
interface ContactPageProps {
params: {
locale: string;
};
}
export async function generateMetadata({ params: { locale } }: ContactPageProps): Promise<Metadata> {
const t = await getTranslations({ locale, namespace: 'Contact' });
return {
title: t('title'),
description: t('subtitle'),
alternates: {
canonical: `/${locale}/contact`,
languages: {
'de': '/de/contact',
'en': '/en/contact',
'x-default': '/en/contact',
},
},
openGraph: {
title: `${t('title')} | KLZ Cables`,
description: t('subtitle'),
url: `https://klz-cables.com/${locale}/contact`,
},
twitter: {
card: 'summary_large_image',
title: `${t('title')} | KLZ Cables`,
description: t('subtitle'),
},
};
}
export default function ContactPage() {
const t = useTranslations('Contact');
const locale = t('locale') || 'en'; // Fallback if needed, but usually passed via params
return (
<div className="flex flex-col min-h-screen bg-neutral-light">
<JsonLd
id="breadcrumb-contact"
data={{
'@context': 'https://schema.org',
'@type': 'BreadcrumbList',
itemListElement: [
{
'@type': 'ListItem',
position: 1,
name: t('title'),
item: `https://klz-cables.com/${locale}/contact`,
},
],
}}
/>
<JsonLd
id="local-business-contact"
data={{
'@context': 'https://schema.org',
'@type': 'LocalBusiness',
name: 'KLZ Cables',
image: 'https://klz-cables.com/logo.png',
'@id': 'https://klz-cables.com',
url: 'https://klz-cables.com',
telephone: '+49 881 92537298',
address: {
'@type': 'PostalAddress',
streetAddress: 'Trifthofstraße 57',
addressLocality: 'Weilheim i. OB',
postalCode: '82362',
addressCountry: 'DE',
},
geo: {
'@type': 'GeoCoordinates',
latitude: 47.8407,
longitude: 11.1421,
},
openingHoursSpecification: [
{
'@type': 'OpeningHoursSpecification',
dayOfWeek: [
'Monday',
'Tuesday',
'Wednesday',
'Thursday',
'Friday'
],
opens: '08:00',
closes: '17:00'
}
],
sameAs: [
'https://www.linkedin.com/company/klz-cables'
]
}}
/>
{/* Hero Section */}
<section className="bg-primary-dark text-white py-20 md:py-32 relative overflow-hidden">
<div className="absolute inset-0 opacity-20">
<div className="absolute top-0 left-0 w-full h-full bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-accent via-transparent to-transparent" />
</div>
<Container className="relative z-10">
<div className="max-w-4xl animate-slide-up">
<Heading level={1} subtitle={t('heroSubtitle')} className="text-white mb-4 md:mb-6">
<span className="text-white">{t('title')}</span>
</Heading>
<p className="text-lg md:text-xl text-white/70 leading-relaxed max-w-2xl">
{t('subtitle')}
</p>
</div>
</Container>
</section>
<Section className="bg-neutral-light -mt-8 md:-mt-20 relative z-20 py-12 md:py-28">
<Container>
<div className="grid grid-cols-1 lg:grid-cols-12 gap-8 md:gap-16">
{/* Contact Info */}
<div className="lg:col-span-5 space-y-6 md:space-y-12">
<div className="animate-fade-in">
<Heading level={3} subtitle={t('info.subtitle')} className="mb-6 md:mb-8">
{t('info.howToReachUs')}
</Heading>
<div className="space-y-4 md:space-y-8">
<div className="flex items-start gap-4 md:gap-6 group">
<div className="w-10 h-10 md:w-14 md:h-14 rounded-xl md:rounded-2xl bg-saturated/10 flex items-center justify-center text-saturated group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm flex-shrink-0">
<svg className="w-5 h-5 md:w-7 md:h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M15 11a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
</div>
<div>
<h4 className="text-base md:text-xl font-bold text-primary mb-1 md:mb-2">{t('info.office')}</h4>
<p className="text-sm md:text-lg text-text-secondary leading-relaxed whitespace-pre-line">
{t('info.address')}
</p>
</div>
</div>
<div className="flex items-start gap-4 md:gap-6 group">
<div className="w-10 h-10 md:w-14 md:h-14 rounded-xl md:rounded-2xl bg-saturated/10 flex items-center justify-center text-saturated group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm flex-shrink-0">
<svg className="w-5 h-5 md:w-7 md:h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 5a2 2 0 012-2h3.28a1 1 0 01.948.684l1.498 4.493a1 1 0 01-.502 1.21l-2.257 1.13a11.042 11.042 0 005.516 5.516l1.13-2.257a1 1 0 011.21-.502l4.493 1.498a1 1 0 01.684.949V19a2 2 0 01-2 2h-1C9.716 21 3 14.284 3 6V5z" />
</svg>
</div>
<div>
<h4 className="text-base md:text-xl font-bold text-primary mb-1 md:mb-2">{t('info.phone')}</h4>
<a href="tel:+4988192537298" className="text-sm md:text-lg text-text-secondary hover:text-primary transition-colors font-medium touch-target">+49 881 92537298</a>
</div>
</div>
<div className="flex items-start gap-4 md:gap-6 group">
<div className="w-10 h-10 md:w-14 md:h-14 rounded-xl md:rounded-2xl bg-saturated/10 flex items-center justify-center text-saturated group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm flex-shrink-0">
<svg className="w-5 h-5 md:w-7 md:h-7" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
</div>
<div>
<h4 className="text-base md:text-xl font-bold text-primary mb-1 md:mb-2">{t('info.email')}</h4>
<a href="mailto:info@klz-vertriebs-gmbh.com" className="text-sm md:text-lg text-text-secondary hover:text-primary transition-colors font-medium touch-target">info@klz-vertriebs-gmbh.com</a>
</div>
</div>
</div>
</div>
<div className="p-6 md:p-10 bg-white rounded-2xl md:rounded-3xl border border-neutral-medium shadow-sm animate-fade-in">
<Heading level={4} className="mb-4 md:mb-6">{t('hours.title')}</Heading>
<ul className="space-y-2 md:space-y-4">
<li className="flex justify-between items-center pb-2 md:pb-4 border-b border-neutral-medium text-sm md:text-base">
<span className="font-bold text-primary">{t('hours.weekdays')}</span>
<span className="text-text-secondary">{t('hours.weekdaysTime')}</span>
</li>
<li className="flex justify-between items-center text-sm md:text-base">
<span className="font-bold text-primary">{t('hours.weekend')}</span>
<span className="text-accent-dark font-bold">{t('hours.closed')}</span>
</li>
</ul>
</div>
</div>
{/* Contact Form */}
<div className="lg:col-span-7">
<ContactForm />
</div>
</div>
</Container>
</Section>
{/* Map Placeholder */}
<section className="h-[300px] md:h-[500px] bg-neutral-medium relative overflow-hidden grayscale hover:grayscale-0 transition-all duration-1000">
<div className="absolute inset-0 flex items-center justify-center">
<div className="text-center">
<div className="w-20 h-20 bg-primary rounded-full flex items-center justify-center text-white mb-4 mx-auto shadow-2xl animate-bounce">
<svg className="w-10 h-10" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M17.657 16.657L13.414 20.9a1.998 1.998 0 01-2.827 0l-4.244-4.243a8 8 0 1111.314 0z" />
</svg>
</div>
<p className="font-bold text-primary text-xl">{t('map.comingSoon')}</p>
</div>
</div>
</section>
</div>
);
}