import React, { useState } from 'react'; import { router } from 'expo-router'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, Alert, ActivityIndicator, KeyboardAvoidingView, Platform, ScrollView, } from 'react-native'; import { SafeAreaView } from 'react-native-safe-area-context'; import { MaterialIcons } from '@expo/vector-icons'; import * as Device from 'expo-device'; import { useHouseholdStore } from '../src/hooks/useHousehold'; import { createHousehold, joinHousehold, getHousehold, registerMember } from '../src/services/household'; import { getFcmToken } from '../src/services/notifications'; import { COLORS } from '../src/constants'; export default function OnboardingScreen() { const setHousehold = useHouseholdStore((s) => s.setHousehold); const [householdName, setHouseholdName] = useState(''); const [deviceName, setDeviceName] = useState(Device.deviceName ?? ''); const [inviteLink, setInviteLink] = useState(''); const [tab, setTab] = useState<'create' | 'join'>('create'); const [loading, setLoading] = useState(false); const handleCreate = async () => { if (!householdName.trim()) { Alert.alert('Pflichtfeld', 'Bitte gib einen Haushaltsnamen ein.'); return; } setLoading(true); try { const household = await createHousehold(householdName.trim()); setHousehold(household); router.replace('/'); const fcmToken = await getFcmToken().catch(() => null); await registerMember(household.id, fcmToken, deviceName).catch((e) => console.warn('registerMember failed (non-critical):', e) ); } catch (e: any) { Alert.alert('Fehler', 'Haushalt konnte nicht erstellt werden. Bitte Internetverbindung prüfen.'); } finally { setLoading(false); } }; const handleJoin = async () => { const raw = inviteLink.trim(); const qIndex = raw.indexOf('?'); if (!raw || qIndex === -1) { Alert.alert('Ungültiger Link', 'Füge den vollständigen Einladungslink ein.'); return; } const params = new URLSearchParams(raw.slice(qIndex + 1)); const householdId = params.get('householdId') ?? ''; const token = params.get('token') ?? ''; if (!householdId || !token) { Alert.alert('Ungültiger Link', 'Der Link enthält keine gültigen Zugangsdaten.'); return; } setLoading(true); try { const success = await joinHousehold(householdId, token); if (!success) { Alert.alert('Abgelaufener Link', 'Dieser Einladungslink ist ungültig oder wurde erneuert. Bitte einen neuen Link anfordern.'); return; } const household = await getHousehold(householdId); if (!household) { Alert.alert('Fehler', 'Haushalt nicht gefunden. Bitte erneut versuchen.'); return; } const fcmToken = await getFcmToken().catch(() => null); await registerMember(householdId, fcmToken, deviceName); setHousehold(household); router.replace('/'); } catch { Alert.alert('Verbindungsfehler', 'Bitte Internetverbindung prüfen und erneut versuchen.'); } finally { setLoading(false); } }; return ( HouseOrg Gemeinsam organisiert setTab('create')} > Neu erstellen setTab('join')} > Beitreten {tab === 'create' ? ( <> Haushaltsname Mein Gerätename {loading ? ( ) : ( <> Haushalt erstellen )} ) : ( <> Einladungslink Mein Gerätename {loading ? ( ) : ( <> Beitreten )} )} ); } const styles = StyleSheet.create({ safeArea: { flex: 1, backgroundColor: COLORS.primary }, keyboardView: { flex: 1 }, scroll: { flexGrow: 1 }, hero: { alignItems: 'center', paddingTop: 56, paddingBottom: 52, paddingHorizontal: 24, backgroundColor: COLORS.primary, }, heroIcon: { width: 84, height: 84, borderRadius: 26, backgroundColor: 'rgba(255,255,255,0.18)', justifyContent: 'center', alignItems: 'center', marginBottom: 20, }, title: { fontSize: 36, fontWeight: '700', color: COLORS.white, letterSpacing: -0.5, }, subtitle: { fontSize: 17, color: 'rgba(255,255,255,0.72)', marginTop: 6, }, card: { flex: 1, backgroundColor: COLORS.surface, borderTopLeftRadius: 28, borderTopRightRadius: 28, padding: 24, paddingTop: 28, }, tabs: { flexDirection: 'row', backgroundColor: COLORS.white, borderRadius: 14, padding: 4, marginBottom: 26, shadowColor: '#000', shadowOpacity: 0.05, shadowRadius: 4, elevation: 1, }, tab: { flex: 1, paddingVertical: 10, borderRadius: 10, alignItems: 'center', }, tabActive: { backgroundColor: COLORS.primary }, tabText: { fontSize: 14, color: COLORS.textSecondary, fontWeight: '500' }, tabTextActive: { color: COLORS.white, fontWeight: '600' }, form: { gap: 12 }, label: { fontSize: 12, fontWeight: '600', color: COLORS.text, textTransform: 'uppercase', letterSpacing: 0.5, }, input: { borderWidth: 1.5, borderColor: COLORS.border, borderRadius: 12, padding: 14, fontSize: 16, backgroundColor: COLORS.white, color: COLORS.text, }, inputMultiline: { height: 100, textAlignVertical: 'top' }, btn: { backgroundColor: COLORS.primary, borderRadius: 14, paddingVertical: 16, alignItems: 'center', flexDirection: 'row', justifyContent: 'center', gap: 8, marginTop: 4, shadowColor: COLORS.primary, shadowOpacity: 0.28, shadowRadius: 10, shadowOffset: { width: 0, height: 4 }, elevation: 4, }, btnDisabled: { opacity: 0.6, shadowOpacity: 0 }, btnText: { color: COLORS.white, fontSize: 16, fontWeight: '600' }, });