import { useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { api } from '../../api/client.js';
import usePageMeta from '../../hooks/usePageMeta.js';
import ExternalEmbed from '../../components/ExternalEmbed.jsx';
import { useSiteSettings } from '../../context/SiteSettingsContext.jsx';
import { useLanguage } from '../../context/LanguageContext.jsx';
import { useCookieConsent } from '../../context/CookieConsentContext.jsx';
import { User, Mail, Phone, Car, Package, Send, MapPin, ExternalLink } from 'lucide-react';
import grungeBg from '../../assets/contact/grunge.png';
import splatterBg from '../../assets/contact/splatter.png';
import carPhoto from '../../assets/contact/car-light.png';
const digitsOnly = (value) => (value || '').replace(/[^\d+]/g, '');
const waHref = (whatsapp) => `https://wa.me/${digitsOnly(whatsapp).replace(/^0/, '49').replace('+', '')}`;
const SHOP_ADDRESS_ENCODED = encodeURIComponent('Boxbrunner Str. 20a, 63916 Amorbach');
const DIRECTIONS_URL = `https://www.google.com/maps/dir/?api=1&destination=${SHOP_ADDRESS_ENCODED}`;
const michroma = { fontFamily: "'Michroma', sans-serif" };
function WhatsAppIcon({ className }) {
return (
);
}
// Die 4 Feature-Icons aus dem Referenzdesign - kein 1:1-Lucide-Pendant fuer alle,
// daher als rohe Pfade uebernommen statt einem angenaeherten Lucide-Icon.
function FeatureIcon({ path, className }) {
return (
);
}
const FEATURE_ICON_PATHS = {
premium: 'M4 12v3M8 8v11M12 4v16M16 8v11M20 12v3',
germany: 'M12 12m-3 0a3 3 0 1 0 6 0a3 3 0 1 0 -6 0 M12 2v2M12 20v2M2 12h2M20 12h2M5 5l1.5 1.5M17.5 17.5 19 19M19 5l-1.5 1.5M6.5 17.5 5 19',
individual: 'M6 3h12l4 6-10 12L2 9z M11 3 8 9l4 12 4-12-3-6M2 9h20',
experts: 'M20 6 9 17l-5-5',
};
// Michroma hat kein Euro-Zeichen-Glyph (rendert als Tofu/"O"-Ersatzform) - das
// Waehrungssymbol bekommt darum immer die System-Schrift, nur Ziffern/Komma bleiben
// in Michroma. Robust gegen beide Symbolpositionen (de-DE: "999,00 €", en-US: "€999.00").
function PriceMichroma({ formatted, color }) {
const [pre, post] = formatted.split('€');
return (
{pre}
€
{post}
);
}
function Field({ icon: Icon, label, name, type = 'text', required, value, onChange, placeholder }) {
return (
);
}
export default function ContactPage() {
const [params] = useSearchParams();
const { phone, whatsapp, contact_email: contactEmail } = useSiteSettings();
const { t, language } = useLanguage();
const { consent } = useCookieConsent();
const formatPrice = (value) =>
new Intl.NumberFormat(language === 'de' ? 'de-DE' : 'en-US', { style: 'currency', currency: 'EUR' }).format(value);
const [form, setForm] = useState({ name: '', email: '', phone: '', vin: '', message: '' });
const [status, setStatus] = useState('idle');
const [error, setError] = useState('');
const [upgrades, setUpgrades] = useState([]);
const [selectedUpgradeIds, setSelectedUpgradeIds] = useState([]);
const packageId = params.get('packageId');
const packageTotal = params.get('total') ? Number(params.get('total')) : null;
useEffect(() => {
if (!packageId) {
setUpgrades([]);
return;
}
api.get(`/packages/${packageId}/upgrades`).then(setUpgrades).catch(() => setUpgrades([]));
}, [packageId]);
const toggleUpgrade = (id) => {
setSelectedUpgradeIds((ids) => (ids.includes(id) ? ids.filter((x) => x !== id) : [...ids, id]));
};
const upgradesTotal = upgrades
.filter((u) => selectedUpgradeIds.includes(u.id))
.reduce((sum, u) => sum + Number(u.price), 0);
usePageMeta({
title: t('contactPage.metaTitle'),
description: t('contactPage.metaDescription'),
path: '/kontakt',
});
const context = {
brand: params.get('brand') || '',
model: params.get('model') || '',
package: params.get('package') || '',
};
const hasPackage = Boolean(context.brand && context.model && context.package);
const handleChange = (e) => setForm((f) => ({ ...f, [e.target.name]: e.target.value }));
const handleSubmit = async (e) => {
e.preventDefault();
setStatus('sending');
setError('');
try {
await api.post('/contact', {
...form,
brand_name: context.brand || null,
model_name: context.model || null,
package_name: context.package || null,
product_name: params.get('product') || null,
package_id: packageId || null,
package_product_id: params.get('productId') || null,
upgrade_ids: selectedUpgradeIds,
});
setStatus('sent');
setForm({ name: '', email: '', phone: '', vin: '', message: '' });
} catch (e) {
setError(e.message);
setStatus('idle');
}
};
const features = [
{ key: 'premium', title: t('contactPage.featurePremiumTitle'), sub: t('contactPage.featurePremiumSub') },
{ key: 'germany', title: t('contactPage.featureGermanyTitle'), sub: t('contactPage.featureGermanySub') },
{ key: 'individual', title: t('contactPage.featureIndividualTitle'), sub: t('contactPage.featureIndividualSub') },
{ key: 'experts', title: t('contactPage.featureExpertsTitle'), sub: t('contactPage.featureExpertsSub') },
];
return (
{/* Dark Mode: Grunge-Textur + Splatter + Bogen (Assets aus dem Handoff) */}
{/* Light Mode: Auto-Foto unten links verankert + gruener Lichtstreifen rechts (ab 981px, s. README).
Maske uebernimmt die weiche Ausblendung nach oben (kein harter oberer Rand bei
voller Hoehe), der Scrim obendrauf das weiche Verlaufen nach rechts in die Seite. */}
{/* Light Mode: dezente Topo-Wellenlinien oben links (README "Hintergruende"). */}
{/* Hero */}
{t('contactPage.heroEyebrow')}
{t('contactPage.heroTitlePre')} {t('contactPage.heroTitleAccent')} {t('contactPage.heroTitlePost')}
{t('contactPage.heroSubtitle')}
{/* Hauptraster */}
{/* Formular-Karte */}
{hasPackage && (
{t('contactPage.packageBoxTitle')}
{t('contactPage.contextBrand')}
{context.brand}
{t('contactPage.contextModel')}
{context.model}
{t('contactPage.contextPackage')}
{context.package}
{t('contactPage.packagePrice')}
{packageTotal != null ? : '—'}
)}
{upgrades.length > 0 && (
{t('contactPage.optionalUpgrades')}
{upgrades.map((u) => (
toggleUpgrade(u.id)}
className="mt-0.5 h-4 w-4 rounded"
style={{ accentColor: 'var(--kf-accent)' }}
/>
{u.name}
{u.description && (
{u.description}
)}
+{formatPrice(u.price)}
))}
{selectedUpgradeIds.length > 0 && packageTotal != null && (
{t('contactPage.totalWithUpgrades')}
)}
)}
{t('contactPage.formTitle')}
{status === 'sent' && (
{t('contactPage.sentTitle')}
{t('contactPage.sentText')}
)}
{/* Rechte Spalte */}
{t('contactPage.cardTitle')}
{t('contactPage.address')}
Boxbrunner Straße 20a 63916 Amorbach
{whatsapp && (
)}
{t('contactPage.hours')}
{t('contactPage.hoursWeekDays')}
{t('contactPage.hoursWeekTime')}
{t('contactPage.hoursSatDay')}
{t('contactPage.hoursSatTime')}
{/* Feature-Leiste */}
{features.map((f) => (
))}
);
}