import React from 'react'; import { useNavigate } from 'react-router-dom'; import { useTranslation } from 'react-i18next'; import { Shield, Bell, LogOut, User } from 'lucide-react'; import { YStack, XStack } from '@tamagui/stacks'; import { SizableText as Text } from '@tamagui/text'; import { Pressable } from '@tamagui/react-native-web-lite'; import { Switch } from '@tamagui/switch'; import { MobileShell } from './components/MobileShell'; import { MobileCard, CTAButton, PillBadge } from './components/Primitives'; import { useAuth } from '../auth/context'; import { getNotificationPreferences, updateNotificationPreferences, NotificationPreferences, } from '../api'; import { getApiErrorMessage } from '../lib/apiError'; import { adminPath } from '../constants'; type PreferenceKey = keyof NotificationPreferences; const AVAILABLE_PREFS: PreferenceKey[] = [ 'photo_thresholds', 'photo_limits', 'guest_thresholds', 'guest_limits', 'gallery_warnings', 'gallery_expired', 'event_thresholds', 'event_limits', 'package_expiring', 'package_expired', ]; export default function MobileSettingsPage() { const { t } = useTranslation('management'); const navigate = useNavigate(); const { user, logout } = useAuth(); const [preferences, setPreferences] = React.useState({}); const [defaults, setDefaults] = React.useState({}); const [loading, setLoading] = React.useState(true); const [saving, setSaving] = React.useState(false); const [error, setError] = React.useState(null); React.useEffect(() => { (async () => { setLoading(true); try { const result = await getNotificationPreferences(); const defaultsMerged: NotificationPreferences = result.defaults ?? {}; const prefs = { ...defaultsMerged, ...(result.preferences ?? {}) }; AVAILABLE_PREFS.forEach((key) => { if (prefs[key] === undefined) { prefs[key] = defaultsMerged[key] ?? false; } }); setPreferences(prefs); setDefaults(defaultsMerged); setError(null); } catch (err) { setError(getApiErrorMessage(err, t('settings.notifications.errorLoad', 'Benachrichtigungen konnten nicht geladen werden.'))); } finally { setLoading(false); } })(); }, [t]); const togglePref = (key: PreferenceKey) => { setPreferences((prev) => ({ ...prev, [key]: !prev[key], })); }; const handleSave = async () => { setSaving(true); try { const payload: NotificationPreferences = {}; AVAILABLE_PREFS.forEach((key) => { payload[key] = Boolean(preferences[key]); }); await updateNotificationPreferences(payload); setError(null); } catch (err) { setError(getApiErrorMessage(err, t('settings.notifications.errorSave', 'Speichern fehlgeschlagen'))); } finally { setSaving(false); } }; const handleReset = () => { setPreferences(defaults); }; return ( navigate(-1)}> {error ? ( {error} ) : null} {t('mobileSettings.accountTitle', 'Account')} {user?.name ?? user?.email ?? t('settings.session.unknown', 'Benutzer')} {user?.tenant_id ? ( {t('mobileSettings.tenantBadge', 'Tenant #{{id}}', { id: user.tenant_id })} ) : null} navigate(adminPath('/mobile/profile'))} /> logout({ redirect: adminPath('/logout') })} /> {t('mobileSettings.notificationsTitle', 'Notifications')} {loading ? ( {t('mobileSettings.notificationsLoading', 'Loading settings ...')} ) : ( {AVAILABLE_PREFS.map((key) => ( {t(`settings.notifications.keys.${key}.label`, key)} {t(`settings.notifications.keys.${key}.description`, '')} togglePref(key)} aria-label={t(`settings.notifications.keys.${key}.label`, key)} > ))} )} handleSave()} /> handleReset()} /> {t('settings.appearance.title', 'Darstellung')} {t('settings.appearance.description', 'Schalte Dark-Mode oder passe Branding im Admin an.')} navigate(adminPath('/settings'))} /> ); }