- Wired the checkout wizard for Google “comfort login”: added Socialite controller + dependency, new Google env

hooks in config/services.php/.env.example, and updated wizard steps/controllers to store session payloads,
attach packages, and surface localized success/error states.
- Retooled payment handling for both Stripe and PayPal, adding richer status management in CheckoutController/
PayPalController, fallback flows in the wizard’s PaymentStep.tsx, and fresh feature tests for intent
creation, webhooks, and the wizard CTA.
- Introduced a consent-aware Matomo analytics stack: new consent context, cookie-banner UI, useAnalytics/
useCtaExperiment hooks, and MatomoTracker component, then instrumented marketing pages (Home, Packages,
Checkout) with localized copy and experiment tracking.
- Polished package presentation across marketing UIs by centralizing formatting in PresentsPackages, surfacing
localized description tables/placeholders, tuning badges/layouts, and syncing guest/marketing translations.
- Expanded docs & reference material (docs/prp/*, TODOs, public gallery overview) and added a Playwright smoke
test for the hero CTA while reconciling outstanding checklist items.
This commit is contained in:
Codex Agent
2025-10-19 11:41:03 +02:00
parent ae9b9160ac
commit a949c8d3af
113 changed files with 5169 additions and 712 deletions

View File

@@ -3,6 +3,8 @@ 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;
@@ -18,6 +20,11 @@ interface Props {
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: '',
@@ -27,7 +34,13 @@ const Home: React.FC<Props> = ({ packages }) => {
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
post(localizedPath('/kontakt'), {
onSuccess: () => reset(),
onSuccess: () => {
trackEvent({
category: 'marketing_home',
action: 'contact_submit',
});
reset();
},
});
};
@@ -49,9 +62,22 @@ const Home: React.FC<Props> = ({ packages }) => {
<p className="text-xl md:text-2xl mb-8 font-sans-marketing">{t('home.hero_description')}</p>
<Link
href={localizedPath('/packages')}
className="bg-white dark:bg-gray-800 text-[#FFB6C1] px-8 py-4 rounded-full font-bold hover:bg-gray-100 dark:hover:bg-gray-700 transition duration-300 inline-block"
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(' ')}
>
{t('home.cta_explore')}
{heroCtaVariant === 'gradient' ? t('home.cta_explore_highlight') : t('home.cta_explore')}
</Link>
</div>
<div className="md:w-1/2">
@@ -125,14 +151,34 @@ const Home: React.FC<Props> = ({ packages }) => {
<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('/register')}?package_id=${pkg.id}`} className="mt-4 inline-block bg-[#FFB6C1] text-white px-6 py-2 rounded-full hover:bg-pink-600">
<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')} className="bg-[#FFB6C1] text-white px-8 py-4 rounded-full font-bold hover:bg-pink-600 transition">
<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>
@@ -235,4 +281,4 @@ const Home: React.FC<Props> = ({ packages }) => {
);
};
export default Home;
export default Home;