- 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:
@@ -272,17 +272,17 @@ function SummaryCards({ data }: { data: AchievementsPayload }) {
|
||||
);
|
||||
}
|
||||
|
||||
function PersonalActions({ slug }: { slug: string }) {
|
||||
function PersonalActions({ token }: { token: string }) {
|
||||
return (
|
||||
<div className="flex flex-wrap gap-3">
|
||||
<Button asChild>
|
||||
<Link to={`/e/${encodeURIComponent(slug)}/upload`} className="flex items-center gap-2">
|
||||
<Link to={`/e/${encodeURIComponent(token)}/upload`} className="flex items-center gap-2">
|
||||
<Camera className="h-4 w-4" />
|
||||
Neues Foto hochladen
|
||||
</Link>
|
||||
</Button>
|
||||
<Button variant="outline" asChild>
|
||||
<Link to={`/e/${encodeURIComponent(slug)}/tasks`} className="flex items-center gap-2">
|
||||
<Link to={`/e/${encodeURIComponent(token)}/tasks`} className="flex items-center gap-2">
|
||||
<Sparkles className="h-4 w-4" />
|
||||
Aufgabe ziehen
|
||||
</Link>
|
||||
@@ -292,7 +292,7 @@ function PersonalActions({ slug }: { slug: string }) {
|
||||
}
|
||||
|
||||
export default function AchievementsPage() {
|
||||
const { token: slug } = useParams<{ token: string }>();
|
||||
const { token } = useParams<{ token: string }>();
|
||||
const identity = useGuestIdentity();
|
||||
const [data, setData] = useState<AchievementsPayload | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
@@ -302,12 +302,12 @@ export default function AchievementsPage() {
|
||||
const personalName = identity.hydrated && identity.name ? identity.name : undefined;
|
||||
|
||||
useEffect(() => {
|
||||
if (!slug) return;
|
||||
if (!token) return;
|
||||
const controller = new AbortController();
|
||||
setLoading(true);
|
||||
setError(null);
|
||||
|
||||
fetchAchievements(slug, personalName, controller.signal)
|
||||
fetchAchievements(token, personalName, controller.signal)
|
||||
.then((payload) => {
|
||||
setData(payload);
|
||||
if (!payload.personal) {
|
||||
@@ -322,11 +322,11 @@ export default function AchievementsPage() {
|
||||
.finally(() => setLoading(false));
|
||||
|
||||
return () => controller.abort();
|
||||
}, [slug, personalName]);
|
||||
}, [token, personalName]);
|
||||
|
||||
const hasPersonal = Boolean(data?.personal);
|
||||
|
||||
if (!slug) {
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -407,7 +407,7 @@ export default function AchievementsPage() {
|
||||
{data.personal.photos} Fotos | {data.personal.tasks} Aufgaben | {data.personal.likes} Likes
|
||||
</CardDescription>
|
||||
</div>
|
||||
<PersonalActions slug={slug} />
|
||||
<PersonalActions token={token} />
|
||||
</CardHeader>
|
||||
</Card>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user