- Added public gallery API with token-expiry enforcement, branding payload, cursor pagination, and per-photo download stream (app/Http/Controllers/Api/EventPublicController.php:1, routes/api.php:16). 410 is returned when the package gallery duration has lapsed.
- Served the guest PWA at /g/{token} and introduced a mobile-friendly gallery page with lazy-loaded thumbnails, themed colors, lightbox, and download links plus new gallery data client (resources/js/guest/pages/PublicGalleryPage.tsx:1, resources/js/guest/services/galleryApi.ts:1, resources/js/guest/router.tsx:1). Added i18n strings for the public gallery experience (resources/js/guest/i18n/messages.ts:1).
- Ensured checkout step changes snap back to the progress bar on mobile via smooth scroll anchoring (resources/ js/pages/marketing/checkout/CheckoutWizard.tsx:1).
- Enabled tenant admins to export all approved event photos through a new download action that streams a ZIP archive, with translations and routing in place (app/Http/Controllers/Tenant/EventPhotoArchiveController.php:1, app/Filament/Resources/EventResource.php:1, routes/web.php:1, resources/lang/de/admin.php:1, resources/lang/en/admin.php:1).
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import React, { useMemo } from "react";
|
||||
import React, { useMemo, useRef, useEffect } from "react";
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Steps } from "@/components/ui/Steps";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -54,6 +54,8 @@ const baseStepConfig: { id: CheckoutStepId; titleKey: string; descriptionKey: st
|
||||
const WizardBody: React.FC<{ stripePublishableKey: string; paypalClientId: string; privacyHtml: string }> = ({ stripePublishableKey, paypalClientId, privacyHtml }) => {
|
||||
const { t } = useTranslation('marketing');
|
||||
const { currentStep, nextStep, previousStep } = useCheckoutWizard();
|
||||
const progressRef = useRef<HTMLDivElement | null>(null);
|
||||
const hasMountedRef = useRef(false);
|
||||
|
||||
const stepConfig = useMemo(() =>
|
||||
baseStepConfig.map(step => ({
|
||||
@@ -73,9 +75,29 @@ const WizardBody: React.FC<{ stripePublishableKey: string; paypalClientId: strin
|
||||
return (currentIndex / (stepConfig.length - 1)) * 100;
|
||||
}, [currentIndex, stepConfig]);
|
||||
|
||||
useEffect(() => {
|
||||
if (typeof window === 'undefined' || !progressRef.current) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!hasMountedRef.current) {
|
||||
hasMountedRef.current = true;
|
||||
return;
|
||||
}
|
||||
|
||||
const element = progressRef.current;
|
||||
const rect = element.getBoundingClientRect();
|
||||
const scrollTop = window.scrollY + rect.top - 16; // slightly above the progress bar
|
||||
|
||||
window.scrollTo({
|
||||
top: Math.max(scrollTop, 0),
|
||||
behavior: 'smooth',
|
||||
});
|
||||
}, [currentStep]);
|
||||
|
||||
return (
|
||||
<div className="space-y-8">
|
||||
<div className="space-y-4">
|
||||
<div ref={progressRef} className="space-y-4">
|
||||
<Progress value={progress} />
|
||||
<Steps steps={stepConfig} currentStep={currentIndex >= 0 ? currentIndex : 0} />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user