Mobile Dev
This commit is contained in:
@@ -1,187 +1,139 @@
|
||||
import { useState } from 'react';
|
||||
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
import { router } from 'expo-router';
|
||||
|
||||
import { useAuth, useTokenStorageInfo } from '@/src/providers/auth-provider';
|
||||
|
||||
const PRIMARY = '#69c350';
|
||||
|
||||
export default function AccountScreen() {
|
||||
const { token, user, tenants, activeTenantId, activeTenant, switchTenant, logout } = useAuth();
|
||||
const storageInfo = useTokenStorageInfo();
|
||||
|
||||
const [switchingTenantId, setSwitchingTenantId] = useState<number | null>(null);
|
||||
const [switchError, setSwitchError] = useState<string | null>(null);
|
||||
|
||||
const userId = String(user?.id || 'unbekannt');
|
||||
|
||||
async function onSwitchTenant(tenantId: number) {
|
||||
setSwitchingTenantId(tenantId);
|
||||
setSwitchError(null);
|
||||
|
||||
try {
|
||||
await switchTenant(tenantId);
|
||||
} catch (err) {
|
||||
setSwitchError(err instanceof Error ? err.message : 'Tenant konnte nicht gewechselt werden.');
|
||||
} finally {
|
||||
setSwitchingTenantId(null);
|
||||
}
|
||||
}
|
||||
const ITEMS = [
|
||||
{
|
||||
key: 'account',
|
||||
title: 'Konto',
|
||||
subtitle: 'Session, Tenant-Wechsel, Logout',
|
||||
href: '/more/account',
|
||||
},
|
||||
{
|
||||
key: 'settings',
|
||||
title: 'Einstellungen',
|
||||
subtitle: 'Server-Instanz verwalten',
|
||||
href: '/more/settings',
|
||||
},
|
||||
{
|
||||
key: 'wiki',
|
||||
title: 'Wiki',
|
||||
subtitle: 'Wissen und Dokumentation',
|
||||
href: '/more/wiki',
|
||||
},
|
||||
{
|
||||
key: 'customers',
|
||||
title: 'Kunden',
|
||||
subtitle: '',
|
||||
href: '/more/customers',
|
||||
},
|
||||
{
|
||||
key: 'plants',
|
||||
title: 'Objekte',
|
||||
subtitle: '',
|
||||
href: '/more/plants',
|
||||
},
|
||||
{
|
||||
key: 'inventory',
|
||||
title: 'Kundeninventar',
|
||||
subtitle: 'Inventar und Scanner',
|
||||
href: '/more/inventory',
|
||||
},
|
||||
{
|
||||
key: 'nimbot',
|
||||
title: 'Nimbot M2',
|
||||
subtitle: 'Drucker verbinden',
|
||||
href: '/more/nimbot',
|
||||
},
|
||||
];
|
||||
|
||||
export default function MoreScreen() {
|
||||
return (
|
||||
<ScrollView contentContainerStyle={styles.container}>
|
||||
<Text style={styles.title}>Konto</Text>
|
||||
<Text style={styles.subtitle}>Session-Infos und Tenant-Wechsel.</Text>
|
||||
<View style={styles.screen}>
|
||||
<ScrollView style={styles.list} contentContainerStyle={styles.listContent}>
|
||||
<View style={styles.section}>
|
||||
<Text style={styles.sectionTitle}>Funktionen</Text>
|
||||
<Text style={styles.sectionSubtitle}>Weitere Bereiche und Einstellungen.</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.label}>Token vorhanden</Text>
|
||||
<Text style={styles.value}>{token ? 'ja' : 'nein'}</Text>
|
||||
|
||||
<Text style={styles.label}>User ID</Text>
|
||||
<Text style={styles.value}>{userId}</Text>
|
||||
|
||||
<Text style={styles.label}>Aktiver Tenant</Text>
|
||||
<Text style={styles.value}>{activeTenant ? `${activeTenant.name} (#${activeTenantId})` : 'nicht gesetzt'}</Text>
|
||||
|
||||
<Text style={styles.label}>Storage Modus</Text>
|
||||
<Text style={styles.value}>{storageInfo.mode}</Text>
|
||||
</View>
|
||||
|
||||
<View style={styles.card}>
|
||||
<Text style={styles.sectionTitle}>Tenant wechseln</Text>
|
||||
|
||||
{switchError ? <Text style={styles.error}>{switchError}</Text> : null}
|
||||
|
||||
{tenants.map((tenant) => {
|
||||
const tenantId = Number(tenant.id);
|
||||
const isActive = tenantId === activeTenantId;
|
||||
const isSwitching = switchingTenantId === tenantId;
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
key={String(tenant.id)}
|
||||
style={[
|
||||
styles.tenantButton,
|
||||
isActive ? styles.tenantButtonActive : null,
|
||||
isSwitching ? styles.tenantButtonDisabled : null,
|
||||
]}
|
||||
onPress={() => onSwitchTenant(tenantId)}
|
||||
disabled={isActive || switchingTenantId !== null}>
|
||||
<View style={styles.tenantInfo}>
|
||||
<Text style={styles.tenantName} numberOfLines={2} ellipsizeMode="tail">
|
||||
{tenant.name}
|
||||
</Text>
|
||||
<Text style={styles.tenantMeta}>ID: {tenantId}</Text>
|
||||
</View>
|
||||
<View style={styles.tenantActionWrap}>
|
||||
<Text style={styles.tenantAction}>{isActive ? 'Aktiv' : isSwitching ? 'Wechsel...' : 'Wechseln'}</Text>
|
||||
</View>
|
||||
</Pressable>
|
||||
);
|
||||
})}
|
||||
</View>
|
||||
|
||||
<Pressable style={styles.logoutButton} onPress={logout}>
|
||||
<Text style={styles.logoutText}>Logout</Text>
|
||||
</Pressable>
|
||||
</ScrollView>
|
||||
{ITEMS.map((item, index) => (
|
||||
<Pressable key={item.key} style={styles.row} onPress={() => router.push(item.href as any)}>
|
||||
<View style={styles.rowMain}>
|
||||
<Text style={styles.rowTitle}>{item.title}</Text>
|
||||
<Text style={styles.rowSubtitle}>{item.subtitle}</Text>
|
||||
</View>
|
||||
<Text style={styles.rowArrow}>›</Text>
|
||||
{index < ITEMS.length - 1 ? <View style={styles.rowDivider} /> : null}
|
||||
</Pressable>
|
||||
))}
|
||||
</ScrollView>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexGrow: 1,
|
||||
backgroundColor: '#f9fafb',
|
||||
padding: 16,
|
||||
gap: 12,
|
||||
},
|
||||
title: {
|
||||
fontSize: 24,
|
||||
fontWeight: '700',
|
||||
color: '#111827',
|
||||
},
|
||||
subtitle: {
|
||||
color: '#6b7280',
|
||||
},
|
||||
card: {
|
||||
screen: {
|
||||
flex: 1,
|
||||
backgroundColor: '#ffffff',
|
||||
borderRadius: 12,
|
||||
padding: 14,
|
||||
borderWidth: 1,
|
||||
borderColor: '#e5e7eb',
|
||||
gap: 8,
|
||||
},
|
||||
list: {
|
||||
flex: 1,
|
||||
backgroundColor: '#ffffff',
|
||||
},
|
||||
listContent: {
|
||||
paddingBottom: 24,
|
||||
},
|
||||
section: {
|
||||
paddingHorizontal: 16,
|
||||
paddingTop: 14,
|
||||
paddingBottom: 10,
|
||||
borderBottomWidth: 1,
|
||||
borderBottomColor: '#e5e7eb',
|
||||
},
|
||||
sectionTitle: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: '#111827',
|
||||
marginBottom: 2,
|
||||
fontSize: 17,
|
||||
fontWeight: '700',
|
||||
},
|
||||
label: {
|
||||
fontSize: 12,
|
||||
color: '#6b7280',
|
||||
textTransform: 'uppercase',
|
||||
},
|
||||
value: {
|
||||
fontSize: 16,
|
||||
color: '#111827',
|
||||
marginBottom: 2,
|
||||
},
|
||||
error: {
|
||||
color: '#dc2626',
|
||||
marginBottom: 4,
|
||||
},
|
||||
tenantButton: {
|
||||
borderRadius: 10,
|
||||
padding: 12,
|
||||
borderWidth: 1,
|
||||
borderColor: '#d1d5db',
|
||||
backgroundColor: '#ffffff',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
tenantButtonActive: {
|
||||
borderColor: PRIMARY,
|
||||
backgroundColor: '#eff9ea',
|
||||
},
|
||||
tenantButtonDisabled: {
|
||||
opacity: 0.6,
|
||||
},
|
||||
tenantInfo: {
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
paddingRight: 10,
|
||||
},
|
||||
tenantName: {
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
color: '#111827',
|
||||
flexShrink: 1,
|
||||
},
|
||||
tenantMeta: {
|
||||
sectionSubtitle: {
|
||||
color: '#6b7280',
|
||||
fontSize: 13,
|
||||
marginTop: 3,
|
||||
},
|
||||
tenantActionWrap: {
|
||||
minWidth: 84,
|
||||
alignItems: 'flex-end',
|
||||
},
|
||||
tenantAction: {
|
||||
color: PRIMARY,
|
||||
fontWeight: '600',
|
||||
textAlign: 'right',
|
||||
},
|
||||
logoutButton: {
|
||||
marginTop: 4,
|
||||
backgroundColor: '#dc2626',
|
||||
minHeight: 44,
|
||||
borderRadius: 10,
|
||||
row: {
|
||||
paddingHorizontal: 16,
|
||||
paddingVertical: 14,
|
||||
backgroundColor: '#ffffff',
|
||||
position: 'relative',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
justifyContent: 'space-between',
|
||||
gap: 10,
|
||||
},
|
||||
logoutText: {
|
||||
color: '#ffffff',
|
||||
rowMain: {
|
||||
flex: 1,
|
||||
minWidth: 0,
|
||||
},
|
||||
rowTitle: {
|
||||
color: '#111827',
|
||||
fontSize: 15,
|
||||
fontWeight: '600',
|
||||
fontSize: 16,
|
||||
},
|
||||
rowSubtitle: {
|
||||
color: '#6b7280',
|
||||
fontSize: 13,
|
||||
marginTop: 2,
|
||||
},
|
||||
rowArrow: {
|
||||
color: '#9ca3af',
|
||||
fontSize: 24,
|
||||
lineHeight: 24,
|
||||
},
|
||||
rowDivider: {
|
||||
position: 'absolute',
|
||||
left: 16,
|
||||
right: 16,
|
||||
bottom: 0,
|
||||
height: 1,
|
||||
backgroundColor: '#e5e7eb',
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user