- 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:
@@ -1,4 +1,4 @@
|
||||
import React, { useMemo, useRef, useEffect } from "react";
|
||||
import React, { useMemo, useRef, useEffect, useCallback } from "react";
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Steps } from "@/components/ui/Steps";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -9,6 +9,7 @@ import { PackageStep } from "./steps/PackageStep";
|
||||
import { AuthStep } from "./steps/AuthStep";
|
||||
import { PaymentStep } from "./steps/PaymentStep";
|
||||
import { ConfirmationStep } from "./steps/ConfirmationStep";
|
||||
import { useAnalytics } from '@/hooks/useAnalytics';
|
||||
|
||||
interface CheckoutWizardProps {
|
||||
initialPackage: CheckoutPackage;
|
||||
@@ -56,6 +57,7 @@ const WizardBody: React.FC<{ stripePublishableKey: string; paypalClientId: strin
|
||||
const { currentStep, nextStep, previousStep } = useCheckoutWizard();
|
||||
const progressRef = useRef<HTMLDivElement | null>(null);
|
||||
const hasMountedRef = useRef(false);
|
||||
const { trackEvent } = useAnalytics();
|
||||
|
||||
const stepConfig = useMemo(() =>
|
||||
baseStepConfig.map(step => ({
|
||||
@@ -75,6 +77,14 @@ const WizardBody: React.FC<{ stripePublishableKey: string; paypalClientId: strin
|
||||
return (currentIndex / (stepConfig.length - 1)) * 100;
|
||||
}, [currentIndex, stepConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
trackEvent({
|
||||
category: 'marketing_checkout',
|
||||
action: 'step_view',
|
||||
name: currentStep,
|
||||
});
|
||||
}, [currentStep, trackEvent]);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined' || !progressRef.current) {
|
||||
return;
|
||||
@@ -95,6 +105,34 @@ const WizardBody: React.FC<{ stripePublishableKey: string; paypalClientId: strin
|
||||
});
|
||||
}, [currentStep]);
|
||||
|
||||
const handleNext = useCallback(() => {
|
||||
const targetStep = stepConfig[currentIndex + 1]?.id ?? 'end';
|
||||
trackEvent({
|
||||
category: 'marketing_checkout',
|
||||
action: 'step_next',
|
||||
name: `${currentStep}->${targetStep}`,
|
||||
});
|
||||
nextStep();
|
||||
}, [currentIndex, currentStep, nextStep, stepConfig, trackEvent]);
|
||||
|
||||
const handlePrevious = useCallback(() => {
|
||||
const targetStep = stepConfig[currentIndex - 1]?.id ?? 'start';
|
||||
trackEvent({
|
||||
category: 'marketing_checkout',
|
||||
action: 'step_previous',
|
||||
name: `${currentStep}->${targetStep}`,
|
||||
});
|
||||
previousStep();
|
||||
}, [currentIndex, currentStep, previousStep, stepConfig, trackEvent]);
|
||||
|
||||
const handleViewProfile = useCallback(() => {
|
||||
window.location.href = '/settings/profile';
|
||||
}, []);
|
||||
|
||||
const handleGoToAdmin = useCallback(() => {
|
||||
window.location.href = '/event-admin';
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<div ref={progressRef} className="space-y-4">
|
||||
@@ -108,14 +146,16 @@ const WizardBody: React.FC<{ stripePublishableKey: string; paypalClientId: strin
|
||||
{currentStep === "payment" && (
|
||||
<PaymentStep stripePublishableKey={stripePublishableKey} paypalClientId={paypalClientId} />
|
||||
)}
|
||||
{currentStep === "confirmation" && <ConfirmationStep />}
|
||||
{currentStep === "confirmation" && (
|
||||
<ConfirmationStep onViewProfile={handleViewProfile} onGoToAdmin={handleGoToAdmin} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-between">
|
||||
<Button variant="ghost" onClick={previousStep} disabled={currentIndex <= 0}>
|
||||
<Button variant="ghost" onClick={handlePrevious} disabled={currentIndex <= 0}>
|
||||
{t('checkout.back')}
|
||||
</Button>
|
||||
<Button onClick={nextStep} disabled={currentIndex >= stepConfig.length - 1}>
|
||||
<Button onClick={handleNext} disabled={currentIndex >= stepConfig.length - 1}>
|
||||
{t('checkout.next')}
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user