Initial Mobile
This commit is contained in:
110
mobile/app/tenant-select.tsx
Normal file
110
mobile/app/tenant-select.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import { useState } from 'react';
|
||||
import { Redirect, router } from 'expo-router';
|
||||
import { ActivityIndicator, Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
|
||||
|
||||
import { useAuth } from '@/src/providers/auth-provider';
|
||||
|
||||
export default function TenantSelectScreen() {
|
||||
const { token, tenants, activeTenantId, requiresTenantSelection, switchTenant } = useAuth();
|
||||
|
||||
const [switchingTenantId, setSwitchingTenantId] = useState<number | null>(null);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
if (!token) {
|
||||
return <Redirect href="/login" />;
|
||||
}
|
||||
|
||||
if (!requiresTenantSelection && activeTenantId) {
|
||||
return <Redirect href="/(tabs)" />;
|
||||
}
|
||||
|
||||
async function onSelectTenant(tenantId: number) {
|
||||
setSwitchingTenantId(tenantId);
|
||||
setError(null);
|
||||
|
||||
try {
|
||||
await switchTenant(tenantId);
|
||||
router.replace('/(tabs)');
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Tenant konnte nicht gewechselt werden.');
|
||||
} finally {
|
||||
setSwitchingTenantId(null);
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<ScrollView contentContainerStyle={styles.container}>
|
||||
<Text style={styles.title}>Tenant auswaehlen</Text>
|
||||
<Text style={styles.subtitle}>Bitte waehle den Tenant fuer deine Session.</Text>
|
||||
|
||||
{error ? <Text style={styles.error}>{error}</Text> : null}
|
||||
|
||||
{tenants.map((tenant) => {
|
||||
const tenantId = Number(tenant.id);
|
||||
const isBusy = switchingTenantId === tenantId;
|
||||
|
||||
return (
|
||||
<Pressable
|
||||
key={String(tenant.id)}
|
||||
style={[styles.tenantButton, isBusy ? styles.tenantButtonDisabled : null]}
|
||||
onPress={() => onSelectTenant(tenantId)}
|
||||
disabled={switchingTenantId !== null}>
|
||||
<View>
|
||||
<Text style={styles.tenantName}>{tenant.name}</Text>
|
||||
<Text style={styles.tenantMeta}>ID: {tenantId}</Text>
|
||||
</View>
|
||||
{isBusy ? <ActivityIndicator /> : <Text style={styles.tenantAction}>Auswaehlen</Text>}
|
||||
</Pressable>
|
||||
);
|
||||
})}
|
||||
</ScrollView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flexGrow: 1,
|
||||
padding: 16,
|
||||
gap: 10,
|
||||
backgroundColor: '#f9fafb',
|
||||
},
|
||||
title: {
|
||||
fontSize: 24,
|
||||
fontWeight: '700',
|
||||
color: '#111827',
|
||||
},
|
||||
subtitle: {
|
||||
color: '#6b7280',
|
||||
marginBottom: 8,
|
||||
},
|
||||
error: {
|
||||
color: '#dc2626',
|
||||
marginBottom: 8,
|
||||
},
|
||||
tenantButton: {
|
||||
borderRadius: 12,
|
||||
padding: 14,
|
||||
borderWidth: 1,
|
||||
borderColor: '#d1d5db',
|
||||
backgroundColor: '#ffffff',
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between',
|
||||
alignItems: 'center',
|
||||
},
|
||||
tenantButtonDisabled: {
|
||||
opacity: 0.6,
|
||||
},
|
||||
tenantName: {
|
||||
fontSize: 16,
|
||||
fontWeight: '600',
|
||||
color: '#111827',
|
||||
},
|
||||
tenantMeta: {
|
||||
color: '#6b7280',
|
||||
marginTop: 4,
|
||||
},
|
||||
tenantAction: {
|
||||
color: '#2563eb',
|
||||
fontWeight: '600',
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user