Added opaque join-token support across backend and frontend: new migration/model/service/endpoints, guest controllers now resolve tokens, and the demo seeder seeds a token. Tenant event details list/manage tokens with copy/revoke actions, and the guest PWA uses tokens end-to-end (routing, storage, uploads, achievements, etc.). Docs TODO updated to reflect completed steps.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import React from "react";
|
||||
import React from "react";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Sparkles, Users, Camera, CalendarDays, ChevronRight } from "lucide-react";
|
||||
|
||||
import {
|
||||
TenantWelcomeLayout,
|
||||
WelcomeHero,
|
||||
@@ -13,6 +15,7 @@ import { ADMIN_WELCOME_PACKAGES_PATH, ADMIN_EVENTS_PATH } from "../../constants"
|
||||
export default function WelcomeLandingPage() {
|
||||
const navigate = useNavigate();
|
||||
const { markStep } = useOnboardingProgress();
|
||||
const { t } = useTranslation("onboarding");
|
||||
|
||||
React.useEffect(() => {
|
||||
markStep({ welcomeSeen: true, lastStep: "landing" });
|
||||
@@ -20,38 +23,36 @@ export default function WelcomeLandingPage() {
|
||||
|
||||
return (
|
||||
<TenantWelcomeLayout
|
||||
eyebrow="Fotospiel Tenant Admin"
|
||||
title="Willkommen im Event-Erlebnisstudio"
|
||||
subtitle="Starte mit einer inspirierten Einführung, sichere dir dein Event-Paket und kreiere die perfekte Gästegalerie – alles optimiert für mobile Hosts."
|
||||
eyebrow={t("layout.eyebrow")}
|
||||
title={t("layout.title")}
|
||||
subtitle={t("layout.subtitle")}
|
||||
footer={
|
||||
<>
|
||||
<span className="text-brand-navy/80">Schon vertraut mit Fotospiel?</span>
|
||||
<span className="text-brand-navy/80">{t("layout.alreadyFamiliar")}</span>
|
||||
<button
|
||||
type="button"
|
||||
className="inline-flex items-center gap-1 text-sm font-semibold text-brand-rose hover:text-[var(--brand-rose-strong)]"
|
||||
onClick={() => navigate(ADMIN_EVENTS_PATH)}
|
||||
>
|
||||
Direkt zum Dashboard
|
||||
{t("layout.jumpToDashboard")}
|
||||
<ChevronRight className="size-4" />
|
||||
</button>
|
||||
</>
|
||||
}
|
||||
>
|
||||
<WelcomeHero
|
||||
eyebrow="Dein Event, deine Bühne"
|
||||
title="Gestalte das nächste Fotospiel Erlebnis"
|
||||
scriptTitle="Einmalig für Gäste, mühelos für dich."
|
||||
description="Mit nur wenigen Schritten führst du deine Gäste durch ein magisches Fotoabenteuer – inklusive Storytelling, Aufgaben und moderierter Galerie."
|
||||
eyebrow={t("hero.eyebrow")}
|
||||
title={t("hero.title")}
|
||||
scriptTitle={t("hero.scriptTitle")}
|
||||
description={t("hero.description")}
|
||||
actions={[
|
||||
{
|
||||
label: "Pakete entdecken",
|
||||
buttonLabel: "Pakete entdecken",
|
||||
label: t("hero.primary.label"),
|
||||
onClick: () => navigate(ADMIN_WELCOME_PACKAGES_PATH),
|
||||
icon: Sparkles,
|
||||
},
|
||||
{
|
||||
label: "Events anzeigen",
|
||||
buttonLabel: "Bestehende Events anzeigen",
|
||||
label: t("hero.secondary.label"),
|
||||
onClick: () => navigate(ADMIN_EVENTS_PATH),
|
||||
icon: CalendarDays,
|
||||
variant: "outline",
|
||||
@@ -64,24 +65,21 @@ export default function WelcomeLandingPage() {
|
||||
{
|
||||
id: "gallery",
|
||||
icon: Camera,
|
||||
title: "Premium Gästegalerie",
|
||||
description:
|
||||
"Kuratiere Fotos in Echtzeit, markiere Highlights und teile QR-Codes mit einem Tap.",
|
||||
badge: "Neu",
|
||||
title: t("highlights.gallery.title"),
|
||||
description: t("highlights.gallery.description"),
|
||||
badge: t("highlights.gallery.badge"),
|
||||
},
|
||||
{
|
||||
id: "team",
|
||||
icon: Users,
|
||||
title: "Flexibles Team-Onboarding",
|
||||
description:
|
||||
"Lade Co-Hosts ein, weise Rollen zu und behalte den Überblick über Moderation und Aufgaben.",
|
||||
title: t("highlights.team.title"),
|
||||
description: t("highlights.team.description"),
|
||||
},
|
||||
{
|
||||
id: "sparkles",
|
||||
id: "story",
|
||||
icon: Sparkles,
|
||||
title: "Storytelling in Etappen",
|
||||
description:
|
||||
"Geführte Aufgaben und Emotionskarten machen jedes Event zu einer erinnerungswürdigen Reise.",
|
||||
title: t("highlights.story.title"),
|
||||
description: t("highlights.story.description"),
|
||||
},
|
||||
]}
|
||||
/>
|
||||
@@ -90,21 +88,19 @@ export default function WelcomeLandingPage() {
|
||||
actions={[
|
||||
{
|
||||
id: "choose-package",
|
||||
label: "Dein Eventpaket auswählen",
|
||||
description:
|
||||
"Reserviere Credits oder Abos, um sofort Events zu aktivieren. Flexible Optionen für jede Eventgröße.",
|
||||
label: t("ctaList.choosePackage.label"),
|
||||
description: t("ctaList.choosePackage.description"),
|
||||
onClick: () => navigate(ADMIN_WELCOME_PACKAGES_PATH),
|
||||
icon: Sparkles,
|
||||
buttonLabel: "Weiter zu Paketen",
|
||||
buttonLabel: t("ctaList.choosePackage.button"),
|
||||
},
|
||||
{
|
||||
id: "create-event",
|
||||
label: "Event vorbereiten",
|
||||
description:
|
||||
"Sammle Eventdetails, plane Aufgaben und sorge für einen reibungslosen Ablauf noch vor dem Tag des Events.",
|
||||
label: t("ctaList.createEvent.label"),
|
||||
description: t("ctaList.createEvent.description"),
|
||||
onClick: () => navigate(ADMIN_EVENTS_PATH),
|
||||
icon: CalendarDays,
|
||||
buttonLabel: "Zum Event-Manager",
|
||||
buttonLabel: t("ctaList.createEvent.button"),
|
||||
variant: "secondary",
|
||||
},
|
||||
]}
|
||||
|
||||
Reference in New Issue
Block a user