From 9ddb135c039ba4d4b9d102947d74572e55fa67fe Mon Sep 17 00:00:00 2001 From: Codex Agent Date: Wed, 4 Feb 2026 11:22:38 +0100 Subject: [PATCH] Fix notification event names and allow welcome onboarding --- .../js/admin/mobile/NotificationsPage.tsx | 14 +++++++++-- .../__tests__/NotificationsPage.test.tsx | 10 +++++++- .../admin/mobile/lib/onboardingGuard.test.ts | 25 +++++++++++++++++++ .../js/admin/mobile/lib/onboardingGuard.ts | 6 +++++ resources/js/admin/router.tsx | 1 + 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/resources/js/admin/mobile/NotificationsPage.tsx b/resources/js/admin/mobile/NotificationsPage.tsx index 4f94d102..bba14be4 100644 --- a/resources/js/admin/mobile/NotificationsPage.tsx +++ b/resources/js/admin/mobile/NotificationsPage.tsx @@ -43,6 +43,16 @@ type NotificationSwipeRowProps = { children: React.ReactNode; }; +function resolveEventName(name: TenantEvent['name'], t: (key: string, fallback?: string) => string): string { + if (typeof name === 'string') { + return name; + } + if (name && typeof name === 'object') { + return name.de ?? name.en ?? Object.values(name)[0] ?? t('events.placeholders.untitled', 'Unbenanntes Event'); + } + return t('events.placeholders.untitled', 'Unbenanntes Event'); +} + function NotificationSwipeRow({ item, onOpen, onMarkRead, children }: NotificationSwipeRowProps) { const { t } = useTranslation('management'); const { successBg, successText, infoBg, infoText } = useAdminTheme(); @@ -296,7 +306,7 @@ async function loadNotifications( }); const lookup = new Map(); (events ?? []).forEach((event) => { - lookup.set(event.id, typeof event.name === 'string' ? event.name : (event.name as Record)?.en ?? ''); + lookup.set(event.id, resolveEventName(event.name, t)); }); return (response.data ?? []) @@ -756,7 +766,7 @@ export default function MobileNotificationsPage() { - {ev.name} + {resolveEventName(ev.name, t)} {ev.slug} diff --git a/resources/js/admin/mobile/__tests__/NotificationsPage.test.tsx b/resources/js/admin/mobile/__tests__/NotificationsPage.test.tsx index 6a875f34..0d3597dd 100644 --- a/resources/js/admin/mobile/__tests__/NotificationsPage.test.tsx +++ b/resources/js/admin/mobile/__tests__/NotificationsPage.test.tsx @@ -27,7 +27,14 @@ vi.mock('react-i18next', () => ({ vi.mock('../../api', () => ({ listNotificationLogs: vi.fn().mockResolvedValue([]), markNotificationLogs: vi.fn(), - getEvents: vi.fn().mockResolvedValue([]), + getEvents: vi.fn().mockResolvedValue([ + { + id: 1, + slug: 'demo-event', + name: { de: 'Demo Event' }, + status: 'active', + }, + ]), })); vi.mock('../../auth/tokens', () => ({ @@ -131,5 +138,6 @@ describe('MobileNotificationsPage', () => { render(); expect(await screen.findByText('All caught up')).toBeInTheDocument(); + expect(await screen.findByText('Demo Event')).toBeInTheDocument(); }); }); diff --git a/resources/js/admin/mobile/lib/onboardingGuard.test.ts b/resources/js/admin/mobile/lib/onboardingGuard.test.ts index 3fb29e1f..12d58ce3 100644 --- a/resources/js/admin/mobile/lib/onboardingGuard.test.ts +++ b/resources/js/admin/mobile/lib/onboardingGuard.test.ts @@ -12,6 +12,7 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: null, pathname: '/event-admin/mobile/dashboard', isBillingPath: false, + isWelcomePath: false, isOnboardingDismissed: false, isOnboardingCompleted: false, isSuperAdmin: false, @@ -26,6 +27,7 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: null, pathname: ADMIN_BILLING_PATH, isBillingPath: true, + isWelcomePath: false, isOnboardingDismissed: false, isOnboardingCompleted: false, isSuperAdmin: false, @@ -40,6 +42,7 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: 1, pathname: '/event-admin/mobile/events/new', isBillingPath: false, + isWelcomePath: false, isOnboardingDismissed: false, isOnboardingCompleted: false, isSuperAdmin: false, @@ -54,6 +57,7 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: null, pathname: '/event-admin/mobile/dashboard', isBillingPath: false, + isWelcomePath: false, isOnboardingDismissed: false, isOnboardingCompleted: false, isSuperAdmin: false, @@ -68,6 +72,7 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: 0, pathname: '/event-admin/mobile/dashboard', isBillingPath: false, + isWelcomePath: false, isOnboardingDismissed: false, isOnboardingCompleted: false, isSuperAdmin: false, @@ -82,6 +87,7 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: 2, pathname: '/event-admin/mobile/dashboard', isBillingPath: false, + isWelcomePath: false, isOnboardingDismissed: false, isOnboardingCompleted: false, isSuperAdmin: false, @@ -96,6 +102,7 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: null, pathname: '/event-admin/mobile/dashboard', isBillingPath: false, + isWelcomePath: false, isOnboardingDismissed: false, isOnboardingCompleted: false, isSuperAdmin: false, @@ -110,6 +117,7 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: null, pathname: '/event-admin/mobile/dashboard', isBillingPath: false, + isWelcomePath: false, isOnboardingDismissed: true, isOnboardingCompleted: false, isSuperAdmin: false, @@ -124,6 +132,7 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: null, pathname: '/event-admin/mobile/dashboard', isBillingPath: false, + isWelcomePath: false, isOnboardingCompleted: true, isSuperAdmin: false, }); @@ -137,10 +146,26 @@ describe('resolveOnboardingRedirect', () => { remainingEvents: null, pathname: '/event-admin/mobile/dashboard', isBillingPath: false, + isWelcomePath: false, isOnboardingDismissed: false, isOnboardingCompleted: false, isSuperAdmin: true, }); expect(result).toBeNull(); }); + + it('returns null for welcome paths', () => { + const result = resolveOnboardingRedirect({ + hasEvents: false, + hasActivePackage: false, + remainingEvents: null, + pathname: '/event-admin/mobile/welcome', + isBillingPath: false, + isWelcomePath: true, + isOnboardingDismissed: false, + isOnboardingCompleted: false, + isSuperAdmin: false, + }); + expect(result).toBeNull(); + }); }); diff --git a/resources/js/admin/mobile/lib/onboardingGuard.ts b/resources/js/admin/mobile/lib/onboardingGuard.ts index 080c3e43..0268ef3e 100644 --- a/resources/js/admin/mobile/lib/onboardingGuard.ts +++ b/resources/js/admin/mobile/lib/onboardingGuard.ts @@ -9,6 +9,7 @@ type OnboardingRedirectInput = { remainingEvents?: number | null; pathname: string; isBillingPath: boolean; + isWelcomePath?: boolean; isOnboardingDismissed?: boolean; isOnboardingCompleted?: boolean; isSuperAdmin?: boolean; @@ -20,6 +21,7 @@ export function resolveOnboardingRedirect({ remainingEvents, pathname, isBillingPath, + isWelcomePath, isOnboardingDismissed, isOnboardingCompleted, isSuperAdmin, @@ -28,6 +30,10 @@ export function resolveOnboardingRedirect({ return null; } + if (isWelcomePath) { + return null; + } + if (isOnboardingDismissed || isOnboardingCompleted) { return null; } diff --git a/resources/js/admin/router.tsx b/resources/js/admin/router.tsx index 13df1a38..d548013d 100644 --- a/resources/js/admin/router.tsx +++ b/resources/js/admin/router.tsx @@ -98,6 +98,7 @@ function RequireAuth() { remainingEvents, pathname: location.pathname, isBillingPath, + isWelcomePath, isOnboardingDismissed, isOnboardingCompleted, isSuperAdmin,