Files
fotospiel-app/resources/js/pages/marketing/Home.tsx
Codex Agent 79b209de9a Limit-Status im Upload-Flow anzeigen (Warnbanner + Sperrzustände).
Upload-Fehlercodes auswerten und freundliche Dialoge zeigen.
2025-11-01 19:50:17 +01:00

285 lines
12 KiB
TypeScript

import React from 'react';
import { Head, Link, useForm } from '@inertiajs/react';
import { useTranslation } from 'react-i18next';
import { useLocalizedRoutes } from '@/hooks/useLocalizedRoutes';
import MarketingLayout from '@/layouts/mainWebsite';
import { useAnalytics } from '@/hooks/useAnalytics';
import { useCtaExperiment } from '@/hooks/useCtaExperiment';
interface Package {
id: number;
name: string;
description: string;
price: number;
}
interface Props {
packages: Package[];
}
const Home: React.FC<Props> = ({ packages }) => {
const { t } = useTranslation('marketing');
const { localizedPath } = useLocalizedRoutes();
const { trackEvent } = useAnalytics();
const {
variant: heroCtaVariant,
trackClick: trackHeroCtaClick,
} = useCtaExperiment('home_hero_cta');
const { data, setData, post, processing, errors, reset } = useForm({
name: '',
email: '',
message: '',
});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
post(localizedPath('/kontakt'), {
onSuccess: () => {
trackEvent({
category: 'marketing_home',
action: 'contact_submit',
});
reset();
},
});
};
React.useEffect(() => {
if (Object.keys(errors).length > 0) {
window.scrollTo({ top: 0, behavior: 'smooth' });
}
}, [errors]);
return (
<MarketingLayout title={t('home.title')}>
<Head title={t('home.hero_title')} />
{/* Hero Section */}
<section id="hero" className="bg-aurora-enhanced text-gray-900 dark:text-gray-100 py-20 px-4">
<div className="container mx-auto flex flex-col md:flex-row items-center gap-8 max-w-6xl">
<div className="md:w-1/2 text-center md:text-left">
<h1 className="text-4xl md:text-6xl font-bold mb-4 font-display">{t('home.hero_title')}</h1>
<p className="text-xl md:text-2xl mb-8 font-sans-marketing">{t('home.hero_description')}</p>
<Link
href={localizedPath('/packages')}
onClick={() => {
trackHeroCtaClick();
trackEvent({
category: 'marketing_home',
action: 'hero_cta',
name: `packages:${heroCtaVariant}`,
});
}}
className={[
'inline-block rounded-full px-8 py-4 font-bold transition duration-300',
heroCtaVariant === 'gradient'
? 'bg-gradient-to-r from-rose-500 via-pink-500 to-amber-400 text-white shadow-lg shadow-rose-500/40 hover:from-rose-500/95 hover:via-pink-500/95 hover:to-amber-400/95'
: 'bg-white text-[#FFB6C1] hover:bg-gray-100 dark:bg-gray-800 dark:text-rose-200 dark:hover:bg-gray-700',
].join(' ')}
>
{heroCtaVariant === 'gradient' ? t('home.cta_explore_highlight') : t('home.cta_explore')}
</Link>
</div>
<div className="md:w-1/2">
<img
src="/joyous_wedding_guests_posing.jpg"
alt={t('home.hero_image_alt')}
className="w-full h-auto rounded-lg shadow-lg"
/>
</div>
</div>
</section>
{/* How it Works Section */}
<section className="py-20 px-4 bg-gray-50 dark:bg-gray-900">
<div className="container mx-auto max-w-6xl">
<h2 className="text-3xl md:text-4xl font-bold text-center mb-12 font-display">{t('home.how_title')}</h2>
<div className="grid md:grid-cols-3 gap-8">
<div className="text-center">
<div className="w-16 h-16 bg-[#FFB6C1] rounded-full flex items-center justify-center mx-auto mb-4">
<span className="text-2xl">1</span>
</div>
<h3 className="text-xl font-semibold mb-2">{t('home.step1_title')}</h3>
<p>{t('home.step1_desc')}</p>
</div>
<div className="text-center">
<div className="w-16 h-16 bg-[#FFB6C1] rounded-full flex items-center justify-center mx-auto mb-4">
<span className="text-2xl">2</span>
</div>
<h3 className="text-xl font-semibold mb-2">{t('home.step2_title')}</h3>
<p>{t('home.step2_desc')}</p>
</div>
<div className="text-center">
<div className="w-16 h-16 bg-[#FFB6C1] rounded-full flex items-center justify-center mx-auto mb-4">
<span className="text-2xl">3</span>
</div>
<h3 className="text-xl font-semibold mb-2">{t('home.step3_title')}</h3>
<p>{t('home.step3_desc')}</p>
</div>
</div>
</div>
</section>
{/* Features Section */}
<section className="py-20 px-4 dark:bg-gray-700">
<div className="container mx-auto max-w-6xl">
<h2 className="text-3xl md:text-4xl font-bold text-center mb-12 font-display">{t('home.features_title')}</h2>
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md">
<h3 className="text-xl font-semibold mb-2">{t('home.feature1_title')}</h3>
<p>{t('home.feature1_desc')}</p>
</div>
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md">
<h3 className="text-xl font-semibold mb-2">{t('home.feature2_title')}</h3>
<p>{t('home.feature2_desc')}</p>
</div>
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md">
<h3 className="text-xl font-semibold mb-2">{t('home.feature3_title')}</h3>
<p>{t('home.feature3_desc')}</p>
</div>
</div>
</div>
</section>
{/* Packages Teaser */}
<section className="py-20 px-4 bg-gray-50 dark:bg-gray-900">
<div className="container mx-auto max-w-6xl">
<h2 className="text-3xl md:text-4xl font-bold text-center mb-12 font-display">{t('home.packages_title')}</h2>
<div className="grid md:grid-cols-2 gap-8 mb-8">
{packages.slice(0, 2).map((pkg) => (
<div key={pkg.id} className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md text-center">
<h3 className="text-2xl font-bold mb-2">{pkg.name}</h3>
<p className="text-gray-600 dark:text-gray-300 mb-4">{pkg.description}</p>
<p className="text-3xl font-bold text-[#FFB6C1]">{pkg.price} {t('currency.euro')}</p>
<Link
href={`${localizedPath('/packages')}?package_id=${pkg.id}`}
onClick={() =>
trackEvent({
category: 'marketing_home',
action: 'package_teaser_cta',
name: pkg.name,
value: pkg.price,
})
}
className="mt-4 inline-block bg-[#FFB6C1] text-white px-6 py-2 rounded-full hover:bg-pink-600"
>
{t('home.view_details')}
</Link>
</div>
))}
</div>
<div className="text-center">
<Link
href={localizedPath('/packages')}
onClick={() =>
trackEvent({
category: 'marketing_home',
action: 'all_packages_cta',
})
}
className="bg-[#FFB6C1] text-white px-8 py-4 rounded-full font-bold hover:bg-pink-600 transition"
>
{t('home.all_packages')}
</Link>
</div>
</div>
</section>
{/* Contact Section */}
<section id="contact" className="py-20 px-4 dark:bg-gray-700">
<div className="container mx-auto max-w-4xl">
<h2 className="text-3xl md:text-4xl font-bold text-center mb-12 font-display">{t('home.contact_title')}</h2>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label htmlFor="name" className="block text-sm font-medium mb-2">
{t('home.name_label')} {t('common.required')}
</label>
<input
type="text"
id="name"
value={data.name}
onChange={(e) => setData('name', e.target.value)}
className="w-full p-3 border rounded-lg"
/>
{errors.name && <p className="text-red-500 text-sm">{errors.name}</p>}
</div>
<div>
<label htmlFor="email" className="block text-sm font-medium mb-2">
{t('home.email_label')} {t('common.required')}
</label>
<input
type="email"
id="email"
value={data.email}
onChange={(e) => setData('email', e.target.value)}
className="w-full p-3 border rounded-lg"
/>
{errors.email && <p className="text-red-500 text-sm">{errors.email}</p>}
</div>
<div>
<label htmlFor="message" className="block text-sm font-medium mb-2">
{t('home.message_label')} {t('common.required')}
</label>
<textarea
id="message"
rows={4}
value={data.message}
onChange={(e) => setData('message', e.target.value)}
className="w-full p-3 border rounded-lg"
/>
{errors.message && <p className="text-red-500 text-sm">{errors.message}</p>}
</div>
<button
type="submit"
disabled={processing}
className="bg-[#FFB6C1] text-white px-8 py-3 rounded-full font-bold hover:bg-pink-600 transition disabled:opacity-50"
>
{processing ? t('home.sending') : t('home.send')}
</button>
</form>
</div>
</section>
{/* Testimonials Section */}
<section className="py-20 px-4 bg-gray-50 dark:bg-gray-900">
<div className="container mx-auto max-w-6xl">
<h2 className="text-3xl md:text-4xl font-bold text-center mb-12 font-display">{t('home.testimonials_title')}</h2>
<div className="grid md:grid-cols-3 gap-8">
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md">
<p className="italic mb-4">"{t('home.testimonial1')}"</p>
<p className="font-semibold">{t('common.testimonials.anna.name')}</p>
</div>
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md">
<p className="italic mb-4">"{t('home.testimonial2')}"</p>
<p className="font-semibold">{t('common.testimonials.max.name')}</p>
</div>
<div className="bg-white dark:bg-gray-800 p-6 rounded-lg shadow-md">
<p className="italic mb-4">"{t('home.testimonial3')}"</p>
<p className="font-semibold">{t('common.testimonials.lisa.name')}</p>
</div>
</div>
</div>
</section>
{/* FAQ Section */}
<section className="py-20 px-4 dark:bg-gray-700">
<div className="container mx-auto max-w-4xl">
<h2 className="text-3xl md:text-4xl font-bold text-center mb-12 font-display">{t('home.faq_title')}</h2>
<div className="space-y-4">
<div className="bg-gray-50 dark:bg-gray-800 p-4 rounded-lg">
<h3 className="font-semibold">{t('home.faq1_q')}</h3>
<p>{t('home.faq1_a')}</p>
</div>
<div className="bg-gray-50 dark:bg-gray-800 p-4 rounded-lg">
<h3 className="font-semibold">{t('home.faq2_q')}</h3>
<p>{t('home.faq2_a')}</p>
</div>
</div>
</div>
</section>
</MarketingLayout>
);
};
export default Home;