weitere perfektionierung der neuen mobile app
This commit is contained in:
@@ -5,22 +5,30 @@ import { LogOut, User, Settings, Shield, Globe, Moon } 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 { useTheme } from '@tamagui/core';
|
||||
import { MobileShell } from './components/MobileShell';
|
||||
import { MobileCard, CTAButton } from './components/Primitives';
|
||||
import { useAuth } from '../auth/context';
|
||||
import { fetchTenantProfile } from '../api';
|
||||
import { adminPath } from '../constants';
|
||||
import i18n from '../i18n';
|
||||
import { useAppearance } from '@/hooks/use-appearance';
|
||||
|
||||
export default function MobileProfilePage() {
|
||||
const { user, logout } = useAuth();
|
||||
const navigate = useNavigate();
|
||||
const { t } = useTranslation('management');
|
||||
const { appearance, updateAppearance } = useAppearance();
|
||||
const theme = useTheme();
|
||||
const textColor = String(theme.color?.val ?? '#111827');
|
||||
const mutedText = String(theme.gray?.val ?? '#4b5563');
|
||||
const borderColor = String(theme.borderColor?.val ?? '#e5e7eb');
|
||||
const avatarBg = String(theme.surface?.val ?? '#e0f2fe');
|
||||
const primary = String(theme.primary?.val ?? '#2563eb');
|
||||
|
||||
const [name, setName] = React.useState(user?.name ?? 'Guest');
|
||||
const [name, setName] = React.useState(user?.name ?? t('events.members.roles.guest', 'Guest'));
|
||||
const [email, setEmail] = React.useState(user?.email ?? '');
|
||||
const [role, setRole] = React.useState<string>(user?.role ?? '');
|
||||
const [theme, setTheme] = React.useState<'light' | 'dark'>('light');
|
||||
const [language, setLanguage] = React.useState<string>(i18n.language || 'de');
|
||||
|
||||
React.useEffect(() => {
|
||||
@@ -39,7 +47,7 @@ export default function MobileProfilePage() {
|
||||
return (
|
||||
<MobileShell
|
||||
activeTab="profile"
|
||||
title={t('profile.title', 'Profile')}
|
||||
title={t('mobileProfile.title', 'Profile')}
|
||||
onBack={() => navigate(-1)}
|
||||
>
|
||||
<MobileCard space="$3" alignItems="center">
|
||||
@@ -49,38 +57,38 @@ export default function MobileProfilePage() {
|
||||
borderRadius={20}
|
||||
alignItems="center"
|
||||
justifyContent="center"
|
||||
backgroundColor="#e0f2fe"
|
||||
backgroundColor={avatarBg}
|
||||
>
|
||||
<User size={28} color="#2563eb" />
|
||||
<User size={28} color={primary} />
|
||||
</XStack>
|
||||
<Text fontSize="$md" fontWeight="800" color="#111827">
|
||||
<Text fontSize="$md" fontWeight="800" color={textColor}>
|
||||
{name}
|
||||
</Text>
|
||||
<Text fontSize="$sm" color="#4b5563">
|
||||
<Text fontSize="$sm" color={mutedText}>
|
||||
{email}
|
||||
</Text>
|
||||
{role ? (
|
||||
<Text fontSize="$xs" color="#6b7280">
|
||||
<Text fontSize="$xs" color={mutedText}>
|
||||
{role}
|
||||
</Text>
|
||||
) : null}
|
||||
</MobileCard>
|
||||
|
||||
<MobileCard space="$3">
|
||||
<Text fontSize="$md" fontWeight="800" color="#111827">
|
||||
{t('profile.settings', 'Settings')}
|
||||
<Text fontSize="$md" fontWeight="800" color={textColor}>
|
||||
{t('mobileProfile.settings', 'Settings')}
|
||||
</Text>
|
||||
<Pressable onPress={() => navigate(adminPath('/mobile/settings'))}>
|
||||
<XStack alignItems="center" justifyContent="space-between" paddingVertical="$2" borderBottomWidth={1} borderColor="#e5e7eb">
|
||||
<Text fontSize="$sm" color="#111827">
|
||||
{t('profile.account', 'Account & Security')}
|
||||
<XStack alignItems="center" justifyContent="space-between" paddingVertical="$2" borderBottomWidth={1} borderColor={borderColor}>
|
||||
<Text fontSize="$sm" color={textColor}>
|
||||
{t('mobileProfile.account', 'Account & security')}
|
||||
</Text>
|
||||
<Settings size={18} color="#9ca3af" />
|
||||
</XStack>
|
||||
</Pressable>
|
||||
<Pressable onPress={() => navigate(adminPath('/mobile/billing#packages'))}>
|
||||
<XStack alignItems="center" justifyContent="space-between" paddingVertical="$2" borderBottomWidth={1} borderColor="#e5e7eb">
|
||||
<Text fontSize="$sm" color="#111827">
|
||||
<XStack alignItems="center" justifyContent="space-between" paddingVertical="$2" borderBottomWidth={1} borderColor={borderColor}>
|
||||
<Text fontSize="$sm" color={textColor}>
|
||||
{t('billing.sections.packages.title', 'Packages & Billing')}
|
||||
</Text>
|
||||
<Settings size={18} color="#9ca3af" />
|
||||
@@ -88,17 +96,17 @@ export default function MobileProfilePage() {
|
||||
</Pressable>
|
||||
<Pressable onPress={() => navigate(adminPath('/mobile/billing#invoices'))}>
|
||||
<XStack alignItems="center" justifyContent="space-between" paddingVertical="$2">
|
||||
<Text fontSize="$sm" color="#111827">
|
||||
<Text fontSize="$sm" color={textColor}>
|
||||
{t('billing.sections.invoices.title', 'Invoices & Payments')}
|
||||
</Text>
|
||||
<Settings size={18} color="#9ca3af" />
|
||||
</XStack>
|
||||
</Pressable>
|
||||
<XStack alignItems="center" justifyContent="space-between" paddingVertical="$2" borderBottomWidth={1} borderColor="#e5e7eb">
|
||||
<XStack alignItems="center" justifyContent="space-between" paddingVertical="$2" borderBottomWidth={1} borderColor={borderColor}>
|
||||
<XStack space="$2" alignItems="center">
|
||||
<Globe size={16} color="#6b7280" />
|
||||
<Text fontSize="$sm" color="#111827">
|
||||
{t('profile.language', 'Language')}
|
||||
<Text fontSize="$sm" color={textColor}>
|
||||
{t('mobileProfile.language', 'Language')}
|
||||
</Text>
|
||||
</XStack>
|
||||
<select
|
||||
@@ -109,31 +117,32 @@ export default function MobileProfilePage() {
|
||||
void i18n.changeLanguage(lng);
|
||||
}}
|
||||
style={{ border: '1px solid #e5e7eb', borderRadius: 10, padding: '6px 10px', background: 'white', fontSize: 13 }}
|
||||
>
|
||||
<option value="de">Deutsch</option>
|
||||
<option value="en">English</option>
|
||||
>
|
||||
<option value="de">{t('mobileProfile.languageDe', 'Deutsch')}</option>
|
||||
<option value="en">{t('mobileProfile.languageEn', 'English')}</option>
|
||||
</select>
|
||||
</XStack>
|
||||
<XStack alignItems="center" justifyContent="space-between" paddingVertical="$2">
|
||||
<XStack space="$2" alignItems="center">
|
||||
<Moon size={16} color="#6b7280" />
|
||||
<Text fontSize="$sm" color="#111827">
|
||||
{t('profile.theme', 'Theme')}
|
||||
<Text fontSize="$sm" color={textColor}>
|
||||
{t('mobileProfile.theme', 'Theme')}
|
||||
</Text>
|
||||
</XStack>
|
||||
<select
|
||||
value={theme}
|
||||
onChange={(e) => setTheme(e.target.value as 'light' | 'dark')}
|
||||
value={appearance}
|
||||
onChange={(e) => updateAppearance(e.target.value as 'light' | 'dark' | 'system')}
|
||||
style={{ border: '1px solid #e5e7eb', borderRadius: 10, padding: '6px 10px', background: 'white', fontSize: 13 }}
|
||||
>
|
||||
<option value="light">{t('profile.themeLight', 'Light')}</option>
|
||||
<option value="dark">{t('profile.themeDark', 'Dark')}</option>
|
||||
>
|
||||
<option value="light">{t('mobileProfile.themeLight', 'Light')}</option>
|
||||
<option value="dark">{t('mobileProfile.themeDark', 'Dark')}</option>
|
||||
<option value="system">{t('mobileProfile.themeSystem', 'System')}</option>
|
||||
</select>
|
||||
</XStack>
|
||||
</MobileCard>
|
||||
|
||||
<CTAButton
|
||||
label={t('profile.logout', 'Log out')}
|
||||
label={t('mobileProfile.logout', 'Log out')}
|
||||
onPress={() => {
|
||||
logout();
|
||||
navigate(adminPath('/logout'));
|
||||
|
||||
Reference in New Issue
Block a user