- Tenant-Admin-PWA: Neues /event-admin/welcome Onboarding mit WelcomeHero, Packages-, Order-Summary- und Event-Setup-Pages, Zustandsspeicher, Routing-Guard und Dashboard-CTA für Erstnutzer; Filament-/admin-Login via Custom-View behoben.

- Brand/Theming: Marketing-Farb- und Typographievariablen in `resources/css/app.css` eingeführt, AdminLayout, Dashboardkarten und Onboarding-Komponenten entsprechend angepasst; Dokumentation (`docs/todo/tenant-admin-onboarding-fusion.md`, `docs/changes/...`) aktualisiert.
- Checkout & Payments: Checkout-, PayPal-Controller und Tests für integrierte Stripe/PayPal-Flows sowie Paket-Billing-Abläufe überarbeitet; neue PayPal SDK-Factory und Admin-API-Helper (`resources/js/admin/api.ts`) schaffen Grundlage für Billing/Members/Tasks-Seiten.
- DX & Tests: Neue Playwright/E2E-Struktur (docs/testing/e2e.md, `tests/e2e/tenant-onboarding-flow.test.ts`, Utilities), E2E-Tenant-Seeder und zusätzliche Übersetzungen/Factories zur Unterstützung der neuen Flows.
- Marketing-Kommunikation: Automatische Kontakt-Bestätigungsmail (`ContactConfirmation` + Blade-Template) implementiert; Guest-PWA unter `/event` erreichbar.
- Nebensitzung: Blogsystem gefixt und umfassenden BlogPostSeeder für Beispielinhalte angelegt.
This commit is contained in:
Codex Agent
2025-10-10 21:31:55 +02:00
parent 52197f216d
commit d04e234ca0
84 changed files with 8397 additions and 1005 deletions

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { useNavigate, useSearchParams } from 'react-router-dom';
import { useNavigate, useParams, useSearchParams } from 'react-router-dom';
import { ArrowLeft, Loader2, Save, Sparkles, Package as PackageIcon } from 'lucide-react';
import { useQuery } from '@tanstack/react-query';
@@ -15,7 +15,7 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Di
import { AdminLayout } from '../components/AdminLayout';
import { createEvent, getEvent, updateEvent, getPackages } from '../api';
import { isAuthError } from '../auth/tokens';
import { adminPath } from '../constants';
import { ADMIN_EVENT_VIEW_PATH, ADMIN_EVENTS_PATH } from '../constants';
interface EventFormState {
name: string;
@@ -26,8 +26,9 @@ interface EventFormState {
}
export default function EventFormPage() {
const params = useParams<{ slug?: string }>();
const [searchParams] = useSearchParams();
const slugParam = searchParams.get('slug');
const slugParam = params.slug ?? searchParams.get('slug') ?? undefined;
const isEdit = Boolean(slugParam);
const navigate = useNavigate();
@@ -63,12 +64,13 @@ export default function EventFormPage() {
const event = await getEvent(slugParam);
if (cancelled) return;
const name = normalizeName(event.name);
setForm({
setForm((prev) => ({
...prev,
name,
slug: event.slug,
date: event.event_date ? event.event_date.slice(0, 10) : '',
isPublished: event.status === 'published',
});
}));
setOriginalSlug(event.slug);
setAutoSlug(false);
} catch (err) {
@@ -117,12 +119,14 @@ export default function EventFormPage() {
setSaving(true);
setError(null);
const status: 'draft' | 'published' | 'archived' = form.isPublished ? 'published' : 'draft';
const payload = {
name: trimmedName,
slug: trimmedSlug,
package_id: form.package_id,
date: form.date || undefined,
status: form.isPublished ? 'published' : 'draft',
status,
};
try {
@@ -130,10 +134,10 @@ export default function EventFormPage() {
const targetSlug = originalSlug ?? slugParam!;
const updated = await updateEvent(targetSlug, payload);
setOriginalSlug(updated.slug);
navigate(adminPath(`/events/view?slug=${encodeURIComponent(updated.slug)}`));
navigate(ADMIN_EVENT_VIEW_PATH(updated.slug));
} else {
const { event: created } = await createEvent(payload);
navigate(adminPath(`/events/view?slug=${encodeURIComponent(created.slug)}`));
navigate(ADMIN_EVENT_VIEW_PATH(created.slug));
}
} catch (err) {
if (!isAuthError(err)) {
@@ -147,7 +151,7 @@ export default function EventFormPage() {
const actions = (
<Button
variant="outline"
onClick={() => navigate(adminPath('/events'))}
onClick={() => navigate(ADMIN_EVENTS_PATH)}
className="border-pink-200 text-pink-600 hover:bg-pink-50"
>
<ArrowLeft className="h-4 w-4" /> Zurueck zur Liste