- 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

@@ -2,7 +2,7 @@ import { useEffect, useRef, useState } from 'react';
type Photo = { id: number; file_path?: string; thumbnail_path?: string; created_at?: string };
export function usePollGalleryDelta(slug: string) {
export function usePollGalleryDelta(token: string) {
const [photos, setPhotos] = useState<Photo[]>([]);
const [loading, setLoading] = useState(true);
const [newCount, setNewCount] = useState(0);
@@ -13,14 +13,14 @@ export function usePollGalleryDelta(slug: string) {
);
async function fetchDelta() {
if (!slug) {
if (!token) {
setLoading(false);
return;
}
try {
const qs = latestAt.current ? `?since=${encodeURIComponent(latestAt.current)}` : '';
const res = await fetch(`/api/v1/events/${encodeURIComponent(slug)}/photos${qs}`, {
const res = await fetch(`/api/v1/events/${encodeURIComponent(token)}/photos${qs}`, {
headers: { 'Cache-Control': 'no-store' },
});
@@ -90,7 +90,7 @@ export function usePollGalleryDelta(slug: string) {
}, []);
useEffect(() => {
if (!slug) {
if (!token) {
setPhotos([]);
setLoading(false);
return;
@@ -107,7 +107,7 @@ export function usePollGalleryDelta(slug: string) {
return () => {
if (timer.current) window.clearInterval(timer.current);
};
}, [slug, visible]);
}, [token, visible]);
function acknowledgeNew() { setNewCount(0); }
return { loading, photos, newCount, acknowledgeNew };