From 07fe049b8a22ae89cb077b53fe445de9e781073e Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Fri, 21 Nov 2025 07:45:21 +0100 Subject: [PATCH] =?UTF-8?q?umfangreiche=20Behebung=20von=20TS-Fehlern.=20"?= =?UTF-8?q?npm=20run=20types"=20l=C3=A4uft=20nun=20ohne=20Fehler=20durch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- resources/js/admin/api.ts | 16 +++++++++++--- resources/js/admin/auth/context.tsx | 1 - resources/js/admin/components/UserMenu.tsx | 4 ++-- resources/js/admin/context/EventContext.tsx | 2 +- resources/js/admin/dev-tools.ts | 7 +++++-- resources/js/admin/main.tsx | 1 - resources/js/admin/pages/AuthCallbackPage.tsx | 2 +- resources/js/admin/pages/DashboardPage.tsx | 17 +++++++-------- resources/js/admin/pages/EventDetailPage.tsx | 8 +++---- resources/js/admin/pages/EventFormPage.tsx | 2 +- resources/js/admin/pages/EventMembersPage.tsx | 2 +- .../js/admin/pages/EventPhotoboothPage.tsx | 2 +- resources/js/admin/pages/EventPhotosPage.tsx | 6 +++--- resources/js/admin/pages/LoginPage.tsx | 6 ++++-- resources/js/admin/pages/LoginStartPage.tsx | 2 +- .../invite-layout/DesignerCanvas.tsx | 4 ++-- resources/js/guest/components/Header.tsx | 4 ++-- resources/js/guest/demo/fixtures.ts | 2 +- .../js/guest/hooks/usePushSubscription.ts | 2 +- resources/js/guest/i18n/messages.ts | 8 ++----- resources/js/guest/pages/HomePage.tsx | 21 ++++++++++--------- .../js/guest/pages/PublicGalleryPage.tsx | 2 +- resources/js/guest/pages/TaskPickerPage.tsx | 2 +- resources/js/guest/pages/UploadPage.tsx | 2 +- resources/js/guest/services/helpApi.ts | 12 ++++++----- 25 files changed, 74 insertions(+), 63 deletions(-) diff --git a/resources/js/admin/api.ts b/resources/js/admin/api.ts index 971cb86..b26c1c7 100644 --- a/resources/js/admin/api.ts +++ b/resources/js/admin/api.ts @@ -1021,14 +1021,16 @@ function normalizeGuestNotification(raw: JsonValue): GuestNotificationSummary | } const record = raw as Record; + const status = typeof record.status === 'string' ? record.status : null; + const audience = typeof record.audience_scope === 'string' ? record.audience_scope : null; return { id: Number(record.id ?? 0), type: typeof record.type === 'string' ? record.type : 'broadcast', title: typeof record.title === 'string' ? record.title : '', body: typeof record.body === 'string' ? record.body : null, - status: (record.status as GuestNotificationSummary['status']) ?? 'active', - audience_scope: (record.audience_scope as GuestNotificationSummary['audience_scope']) ?? 'all', + status: status === 'draft' || status === 'archived' || status === 'active' ? status : 'active', + audience_scope: audience === 'guest' || audience === 'all' ? audience : 'all', target_identifier: typeof record.target_identifier === 'string' ? record.target_identifier : null, payload: (record.payload as Record) ?? null, priority: Number(record.priority ?? 0), @@ -1384,7 +1386,7 @@ export async function sendGuestNotification( body: JSON.stringify(payload), }); const data = await jsonOrThrow<{ data?: JsonValue }>(response, 'Failed to send guest notification'); - return normalizeGuestNotification(data.data ?? {}) ?? normalizeGuestNotification({ + const fallback = normalizeGuestNotification({ id: 0, type: payload.type ?? 'broadcast', title: payload.title, @@ -1397,6 +1399,14 @@ export async function sendGuestNotification( created_at: new Date().toISOString(), expires_at: null, }); + + const normalized = normalizeGuestNotification(data.data ?? {}) ?? fallback; + + if (!normalized) { + throw new Error('Failed to normalize guest notification'); + } + + return normalized; } export async function getEventPhotoboothStatus(slug: string): Promise { diff --git a/resources/js/admin/auth/context.tsx b/resources/js/admin/auth/context.tsx index c9ac324..4076b71 100644 --- a/resources/js/admin/auth/context.tsx +++ b/resources/js/admin/auth/context.tsx @@ -124,7 +124,6 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }; }, staleTime: 1000 * 60 * 5, - cacheTime: 1000 * 60 * 30, retry: 1, }); diff --git a/resources/js/admin/components/UserMenu.tsx b/resources/js/admin/components/UserMenu.tsx index a53078a..11c1940 100644 --- a/resources/js/admin/components/UserMenu.tsx +++ b/resources/js/admin/components/UserMenu.tsx @@ -115,7 +115,7 @@ export function UserMenu() { {t('app.languageSwitch')} - + {SUPPORTED_LANGUAGES.map(({ code, labelKey }) => ( : appearance === 'light' ? : } {t('app.theme', { defaultValue: 'Darstellung' })} - + {(['light', 'dark', 'system'] as const).map((mode) => ( changeAppearance(mode)}> {mode === 'light' ? : mode === 'dark' ? : } diff --git a/resources/js/admin/context/EventContext.tsx b/resources/js/admin/context/EventContext.tsx index 62dbd22..72c5253 100644 --- a/resources/js/admin/context/EventContext.tsx +++ b/resources/js/admin/context/EventContext.tsx @@ -40,8 +40,8 @@ export function EventProvider({ children }: { children: React.ReactNode }) { } }, staleTime: 60 * 1000, - cacheTime: 5 * 60 * 1000, enabled: authReady, + initialData: [], }); const events = authReady ? fetchedEvents : []; diff --git a/resources/js/admin/dev-tools.ts b/resources/js/admin/dev-tools.ts index b794cc6..164e5ff 100644 --- a/resources/js/admin/dev-tools.ts +++ b/resources/js/admin/dev-tools.ts @@ -57,8 +57,11 @@ if (import.meta.env.DEV || import.meta.env.VITE_ENABLE_TENANT_SWITCHER === 'true } } - const api = { loginAs, clients: Object.keys(CREDENTIALS) }; - console.info('[DevAuth] Demo tenant helpers ready', api.clients); + const api = { + loginAs, + clients: Object.fromEntries(Object.entries(CREDENTIALS).map(([key, value]) => [key, value.login])), + }; + console.info('[DevAuth] Demo tenant helpers ready', Object.keys(api.clients)); (window as typeof window & { fotospielDemoAuth?: typeof api }).fotospielDemoAuth = api; (globalThis as typeof globalThis & { fotospielDemoAuth?: typeof api }).fotospielDemoAuth = api; diff --git a/resources/js/admin/main.tsx b/resources/js/admin/main.tsx index d83152b..140d42e 100644 --- a/resources/js/admin/main.tsx +++ b/resources/js/admin/main.tsx @@ -21,7 +21,6 @@ const queryClient = new QueryClient({ defaultOptions: { queries: { staleTime: 1000 * 60, // 1 minute - cacheTime: 1000 * 60 * 5, refetchOnWindowFocus: false, refetchOnReconnect: false, retry: 1, diff --git a/resources/js/admin/pages/AuthCallbackPage.tsx b/resources/js/admin/pages/AuthCallbackPage.tsx index 4c68a8a..48ffa25 100644 --- a/resources/js/admin/pages/AuthCallbackPage.tsx +++ b/resources/js/admin/pages/AuthCallbackPage.tsx @@ -4,7 +4,7 @@ import { useAuth } from '../auth/context'; import { ADMIN_DEFAULT_AFTER_LOGIN_PATH } from '../constants'; import { decodeReturnTo, resolveReturnTarget } from '../lib/returnTo'; -export default function AuthCallbackPage(): JSX.Element { +export default function AuthCallbackPage(): React.ReactElement { const { status } = useAuth(); const navigate = useNavigate(); const [redirected, setRedirected] = React.useState(false); diff --git a/resources/js/admin/pages/DashboardPage.tsx b/resources/js/admin/pages/DashboardPage.tsx index 8bc740e..708f182 100644 --- a/resources/js/admin/pages/DashboardPage.tsx +++ b/resources/js/admin/pages/DashboardPage.tsx @@ -463,20 +463,18 @@ export default function DashboardPage() { : translate('overview.title', 'Kurzer Überblick'); const heroDescription = singleEvent - ? translate('overview.eventHero.description', 'Alles richtet sich nach {{event}}. Nächster Termin: {{date}}.', { - event: singleEventName ?? '', - date: singleEventDateLabel ?? translate('overview.eventHero.noDate', 'Noch kein Datum festgelegt'), - }) + ? translate('overview.eventHero.description', { defaultValue: 'Alles richtet sich nach {{event}}. Nächster Termin: {{date}}.', event: singleEventName ?? '', date: singleEventDateLabel ?? translate('overview.eventHero.noDate', 'Noch kein Datum festgelegt') }) : translate('overview.description', 'Wichtigste Kennzahlen deines Tenants auf einen Blick.'); const heroSupportingCopy = onboardingCompletion === 100 ? onboardingCompletedCopy : onboardingCardDescription; const heroSupporting = singleEvent ? [ - translate('overview.eventHero.supporting.status', 'Status: {{status}}', { + translate('overview.eventHero.supporting.status', { + defaultValue: 'Status: {{status}}', status: formatEventStatus(singleEvent.status ?? null, tc), }), singleEventDateLabel - ? translate('overview.eventHero.supporting.date', 'Eventdatum: {{date}}', { date: singleEventDateLabel }) + ? translate('overview.eventHero.supporting.date', singleEventDateLabel ?? 'Noch kein Datum festgelegt.') : translate('overview.eventHero.noDate', 'Noch kein Datum festgelegt.'), ].filter(Boolean) : [heroSupportingCopy]; @@ -636,9 +634,10 @@ export default function DashboardPage() { const adminTitle = singleEventName ?? greetingTitle; const adminSubtitle = singleEvent - ? translate('overview.eventHero.subtitle', 'Alle Funktionen konzentrieren sich auf dieses Event.', { - date: singleEventDateLabel ?? translate('overview.eventHero.noDate', 'Noch kein Datum festgelegt'), - }) + ? translate('overview.eventHero.subtitle', { + defaultValue: 'Alle Funktionen konzentrieren sich auf dieses Event.', + date: singleEventDateLabel ?? translate('overview.eventHero.noDate', 'Noch kein Datum festgelegt'), + }) : subtitle; const heroTitle = adminTitle; diff --git a/resources/js/admin/pages/EventDetailPage.tsx b/resources/js/admin/pages/EventDetailPage.tsx index af3963f..68cb335 100644 --- a/resources/js/admin/pages/EventDetailPage.tsx +++ b/resources/js/admin/pages/EventDetailPage.tsx @@ -704,7 +704,7 @@ function PendingPhotosCard({ return (
{photo.caption @@ -779,7 +779,7 @@ function RecentUploadsCard({ slug, photos }: { slug: string; photos: TenantPhoto return (
{photo.caption @@ -811,7 +811,7 @@ function FeedbackCard({ slug }: { slug: string }) { const [message, setMessage] = React.useState(''); const [busy, setBusy] = React.useState(false); const [submitted, setSubmitted] = React.useState(false); - const [error, setError] = React.useState(null); + const [error, setError] = React.useState(undefined); const copy = { positive: t('events.feedback.positive', 'Super Lauf!'), @@ -862,7 +862,7 @@ function FeedbackCard({ slug }: { slug: string }) { onClick={async () => { if (busy || submitted) return; setBusy(true); - setError(null); + setError(undefined); try { await submitTenantFeedback({ diff --git a/resources/js/admin/pages/EventFormPage.tsx b/resources/js/admin/pages/EventFormPage.tsx index 48f5a40..1be2b95 100644 --- a/resources/js/admin/pages/EventFormPage.tsx +++ b/resources/js/admin/pages/EventFormPage.tsx @@ -99,7 +99,7 @@ export default function EventFormPage() { const { data: packageOverview, isLoading: overviewLoading } = useQuery({ queryKey: ['tenant', 'packages', 'overview'], - queryFn: getTenantPackagesOverview, + queryFn: () => getTenantPackagesOverview(), }); const activePackage = packageOverview?.activePackage ?? null; diff --git a/resources/js/admin/pages/EventMembersPage.tsx b/resources/js/admin/pages/EventMembersPage.tsx index 318dffc..49dffb4 100644 --- a/resources/js/admin/pages/EventMembersPage.tsx +++ b/resources/js/admin/pages/EventMembersPage.tsx @@ -305,7 +305,7 @@ export default function EventMembersPage() {