import React, { useState } from 'react'; import { View, Text, TextInput, TouchableOpacity, StyleSheet, ScrollView, KeyboardAvoidingView, Platform, ActivityIndicator, } from 'react-native'; import { useRouter } from 'expo-router'; import { useAuthStore } from '../lib/auth-store'; export default function SignupScreen() { const router = useRouter(); const { signup, isLoading, error, clearError } = useAuthStore(); const [name, setName] = useState(''); const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const [confirmPassword, setConfirmPassword] = useState(''); const [showPassword, setShowPassword] = useState(false); const [validationErrors, setValidationErrors] = useState<{ name?: string; email?: string; password?: string; confirmPassword?: string; }>({}); // Validate email format const validateEmail = (email: string): boolean => { const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; return emailRegex.test(email); }; // Calculate password strength const getPasswordStrength = (password: string): { level: number; text: string; color: string } => { if (!password) { return { level: 0, text: '', color: '#E0E0E0' }; } let strength = 0; if (password.length >= 8) strength++; if (/[a-z]/.test(password) && /[A-Z]/.test(password)) strength++; if (/\d/.test(password)) strength++; if (/[^a-zA-Z0-9]/.test(password)) strength++; const levels = [ { level: 1, text: 'Weak', color: '#FF3B30' }, { level: 2, text: 'Fair', color: '#FF9500' }, { level: 3, text: 'Good', color: '#FFCC00' }, { level: 4, text: 'Strong', color: '#34C759' }, ]; return levels[Math.min(strength, 4) - 1] || { level: 0, text: 'Too short', color: '#FF3B30' }; }; // Validate form const validateForm = (): boolean => { const errors: { name?: string; email?: string; password?: string; confirmPassword?: string; } = {}; if (!name.trim()) { errors.name = 'Name is required'; } else if (name.trim().length < 2) { errors.name = 'Name must be at least 2 characters'; } if (!email.trim()) { errors.email = 'Email is required'; } else if (!validateEmail(email)) { errors.email = 'Please enter a valid email'; } if (!password) { errors.password = 'Password is required'; } else if (password.length < 8) { errors.password = 'Password must be at least 8 characters'; } if (!confirmPassword) { errors.confirmPassword = 'Please confirm your password'; } else if (password !== confirmPassword) { errors.confirmPassword = 'Passwords do not match'; } setValidationErrors(errors); return Object.keys(errors).length === 0; }; // Handle signup const handleSignup = async () => { clearError(); if (!validateForm()) { return; } try { await signup({ name: name.trim(), email: email.trim().toLowerCase(), password, }); router.replace('/(tabs)'); } catch { // Error is handled by the store } }; // Navigate to login const handleLogin = () => { clearError(); router.push('/(auth)/login'); }; const passwordStrength = getPasswordStrength(password); return ( {/* Header */} Create Account Join our community today {/* Form */} {/* Name Input */} Name { setName(text); if (validationErrors.name) { setValidationErrors((prev) => ({ ...prev, name: undefined })); } }} autoCapitalize="words" autoCorrect={false} autoComplete="name" editable={!isLoading} /> {validationErrors.name && ( {validationErrors.name} )} {/* Email Input */} Email { setEmail(text); if (validationErrors.email) { setValidationErrors((prev) => ({ ...prev, email: undefined })); } }} keyboardType="email-address" autoCapitalize="none" autoCorrect={false} autoComplete="email" editable={!isLoading} /> {validationErrors.email && ( {validationErrors.email} )} {/* Password Input */} Password { setPassword(text); if (validationErrors.password) { setValidationErrors((prev) => ({ ...prev, password: undefined })); } }} secureTextEntry={!showPassword} autoCapitalize="none" autoCorrect={false} autoComplete="password-new" editable={!isLoading} /> setShowPassword(!showPassword)} disabled={isLoading} > {showPassword ? 'Hide' : 'Show'} {validationErrors.password && ( {validationErrors.password} )} {/* Password Strength Indicator */} {password.length > 0 && ( {[1, 2, 3, 4].map((level) => ( ))} {passwordStrength.text} )} {/* Confirm Password Input */} Confirm Password { setConfirmPassword(text); if (validationErrors.confirmPassword) { setValidationErrors((prev) => ({ ...prev, confirmPassword: undefined, })); } }} secureTextEntry={!showPassword} autoCapitalize="none" autoCorrect={false} autoComplete="password-new" editable={!isLoading} /> {validationErrors.confirmPassword && ( {validationErrors.confirmPassword} )} {/* API Error */} {error && ( {error} )} {/* Create Account Button */} {isLoading ? ( ) : ( Create Account )} {/* Terms */} By creating an account, you agree to our{' '} Terms of Service and{' '} Privacy Policy {/* Sign In Link */} Already have an account? Sign In ); } const styles = StyleSheet.create({ container: { flex: 1, backgroundColor: '#FFFFFF', }, scrollContent: { flexGrow: 1, paddingHorizontal: 24, paddingTop: 60, paddingBottom: 40, }, header: { marginBottom: 32, }, title: { fontSize: 32, fontWeight: 'bold', color: '#333333', marginBottom: 8, }, subtitle: { fontSize: 16, color: '#666666', }, form: { flex: 1, }, inputContainer: { marginBottom: 20, }, label: { fontSize: 14, fontWeight: '600', color: '#333333', marginBottom: 8, }, input: { height: 50, borderWidth: 1, borderColor: '#E0E0E0', borderRadius: 8, paddingHorizontal: 16, fontSize: 16, color: '#333333', backgroundColor: '#FAFAFA', }, inputError: { borderColor: '#FF3B30', }, passwordContainer: { position: 'relative', }, passwordInput: { paddingRight: 60, }, showPasswordButton: { position: 'absolute', right: 16, top: 0, bottom: 0, justifyContent: 'center', }, showPasswordText: { fontSize: 14, color: '#007AFF', fontWeight: '600', }, errorText: { fontSize: 12, color: '#FF3B30', marginTop: 4, }, strengthContainer: { flexDirection: 'row', alignItems: 'center', marginTop: 8, }, strengthBars: { flexDirection: 'row', flex: 1, gap: 4, }, strengthBar: { flex: 1, height: 4, borderRadius: 2, }, strengthText: { fontSize: 12, fontWeight: '600', marginLeft: 8, minWidth: 50, }, apiError: { backgroundColor: '#FFF0F0', borderRadius: 8, padding: 12, marginBottom: 16, borderWidth: 1, borderColor: '#FF3B30', }, apiErrorText: { fontSize: 14, color: '#FF3B30', textAlign: 'center', }, button: { height: 50, backgroundColor: '#007AFF', borderRadius: 8, justifyContent: 'center', alignItems: 'center', marginBottom: 16, }, buttonDisabled: { backgroundColor: '#B0B0B0', }, buttonText: { fontSize: 16, fontWeight: '600', color: '#FFFFFF', }, termsText: { fontSize: 12, color: '#666666', textAlign: 'center', marginBottom: 24, lineHeight: 18, }, termsLink: { color: '#007AFF', fontWeight: '600', }, loginContainer: { flexDirection: 'row', justifyContent: 'center', alignItems: 'center', }, loginText: { fontSize: 14, color: '#666666', }, loginLink: { fontSize: 14, color: '#007AFF', fontWeight: '600', }, });