import React, { useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, KeyboardAvoidingView, Platform, ActivityIndicator, ScrollView, Image, } from 'react-native'; import { Ionicons } from '@expo/vector-icons'; import { router } from 'expo-router'; import { useApp } from '../../context/AppContext'; import { useColors } from '../../constants/Colors'; import { ThemeBackdrop } from '../../components/ThemeBackdrop'; import { AuthService } from '../../services/authService'; import AsyncStorage from '@react-native-async-storage/async-storage'; export default function SignupScreen() { const { isDarkMode, colorPalette, hydrateSession } = useApp(); const colors = useColors(isDarkMode, colorPalette); const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [passwordConfirm, setPasswordConfirm] = useState(''); const [showPassword, setShowPassword] = useState(false); const [showPasswordConfirm, setShowPasswordConfirm] = useState(false); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const validate = (): string | null => { if (!name.trim()) return 'Bitte gib deinen Namen ein.'; if (!email.trim() || !email.includes('@')) return 'Bitte gib eine gültige E-Mail ein.'; if (password.length < 6) return 'Das Passwort muss mindestens 6 Zeichen haben.'; if (password !== passwordConfirm) return 'Die Passwörter stimmen nicht überein.'; return null; }; const handleSignup = async () => { const validationError = validate(); if (validationError) { setError(validationError); return; } setLoading(true); setError(null); try { const session = await AuthService.signUp(email, name, password); await hydrateSession(session); // Flag setzen: Tour beim nächsten App-Öffnen anzeigen await AsyncStorage.setItem('greenlens_show_tour', 'true'); router.replace('/(tabs)'); } catch (e: any) { if (e.message === 'EMAIL_TAKEN') { setError('Diese E-Mail ist bereits registriert.'); } else if (e.message === 'BACKEND_URL_MISSING') { setError('Backend-URL fehlt. Bitte EXPO_PUBLIC_BACKEND_URL konfigurieren.'); } else if (e.message === 'NETWORK_ERROR') { setError('Server nicht erreichbar. Bitte versuche es erneut.'); } else if (e.message === 'SERVER_ERROR') { setError('Server-Fehler. Bitte versuche es später erneut.'); } else if (e.message === 'AUTH_ERROR') { setError('Registrierung fehlgeschlagen. Bitte versuche es erneut.'); } else { setError(`Fehler (${e.message}). Bitte versuche es erneut.`); } } finally { setLoading(false); } }; return ( {/* Header */} router.back()} > GreenLens Konto erstellen {/* Card */} {/* Name */} Name {/* Email */} E-Mail {/* Password */} Passwort setShowPassword((v) => !v)} style={styles.eyeBtn}> {/* Password Confirm */} Passwort bestätigen setShowPasswordConfirm((v) => !v)} style={styles.eyeBtn}> {/* Password strength hint */} {password.length > 0 && ( {[1, 2, 3, 4].map((level) => ( = level * 3 ? level <= 1 ? colors.danger : level === 2 ? colors.warning : colors.success : colors.border, }, ]} /> ))} {password.length < 4 ? 'Zu kurz' : password.length < 7 ? 'Schwach' : password.length < 10 ? 'Mittel' : 'Stark'} )} {/* Error */} {error && ( {error} )} {/* Signup Button */} {loading ? ( ) : ( Registrieren )} {/* Login link */} router.back()}> Bereits ein Konto?{' '} Anmelden ); } const styles = StyleSheet.create({ flex: { flex: 1 }, scroll: { flexGrow: 1, justifyContent: 'center', paddingHorizontal: 24, paddingVertical: 48, }, header: { alignItems: 'center', marginBottom: 32, }, backBtn: { position: 'absolute', left: 0, top: 0, width: 40, height: 40, borderRadius: 20, borderWidth: 1, justifyContent: 'center', alignItems: 'center', }, logoIcon: { width: 88, height: 88, borderRadius: 20, marginBottom: 16, }, appName: { fontSize: 30, fontWeight: '700', letterSpacing: -0.5, marginBottom: 6, }, subtitle: { fontSize: 15, fontWeight: '400', }, card: { borderRadius: 20, borderWidth: 1, padding: 24, gap: 14, shadowOffset: { width: 0, height: 4 }, shadowOpacity: 1, shadowRadius: 12, elevation: 4, }, fieldGroup: { gap: 6, }, label: { fontSize: 13, fontWeight: '500', marginLeft: 2, }, inputRow: { flexDirection: 'row', alignItems: 'center', borderWidth: 1, borderRadius: 12, paddingHorizontal: 14, height: 50, }, inputIcon: { marginRight: 10, }, input: { flex: 1, fontSize: 15, height: 50, }, eyeBtn: { padding: 4, marginLeft: 6, }, strengthRow: { flexDirection: 'row', alignItems: 'center', gap: 4, marginTop: -4, }, strengthBar: { flex: 1, height: 3, borderRadius: 2, }, strengthText: { fontSize: 11, marginLeft: 4, width: 40, }, errorBox: { flexDirection: 'row', alignItems: 'center', gap: 6, borderRadius: 10, paddingHorizontal: 12, paddingVertical: 10, }, errorText: { fontSize: 13, flex: 1, }, primaryBtn: { height: 52, borderRadius: 14, justifyContent: 'center', alignItems: 'center', marginTop: 4, }, primaryBtnText: { fontSize: 16, fontWeight: '600', }, loginLink: { alignItems: 'center', marginTop: 24, paddingVertical: 8, }, loginLinkText: { fontSize: 15, }, });