Fix notification event names and allow welcome onboarding
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-02-04 11:22:38 +01:00
parent 049c4f82b9
commit 9ddb135c03
5 changed files with 53 additions and 3 deletions

View File

@@ -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<number, string>();
(events ?? []).forEach((event) => {
lookup.set(event.id, typeof event.name === 'string' ? event.name : (event.name as Record<string, string>)?.en ?? '');
lookup.set(event.id, resolveEventName(event.name, t));
});
return (response.data ?? [])
@@ -756,7 +766,7 @@ export default function MobileNotificationsPage() {
<XStack alignItems="center" justifyContent="space-between" paddingVertical="$2">
<YStack>
<Text fontSize="$sm" fontWeight="700" color={text}>
{ev.name}
{resolveEventName(ev.name, t)}
</Text>
<Text fontSize="$xs" color={muted}>
{ev.slug}

View File

@@ -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(<MobileNotificationsPage />);
expect(await screen.findByText('All caught up')).toBeInTheDocument();
expect(await screen.findByText('Demo Event')).toBeInTheDocument();
});
});

View File

@@ -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();
});
});

View File

@@ -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;
}

View File

@@ -98,6 +98,7 @@ function RequireAuth() {
remainingEvents,
pathname: location.pathname,
isBillingPath,
isWelcomePath,
isOnboardingDismissed,
isOnboardingCompleted,
isSuperAdmin,