// ABOUTME: Registration screen for new user signup
// ABOUTME: Validates input and shows pending approval state after registration
import React, { useState } from 'react';
import {
View,
Text,
StyleSheet,
SafeAreaView,
KeyboardAvoidingView,
Platform,
ScrollView,
TouchableOpacity,
Alert,
} from 'react-native';
import { useAuth } from '../../contexts/AuthContext';
import { Button, Input } from '../../components/ui';
import { colors, spacing, fontSize, borderRadius } from '../../constants/theme';
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
type AuthStackParamList = {
Login: undefined;
Register: undefined;
PendingApproval: undefined;
};
interface RegisterScreenProps {
navigation: NativeStackNavigationProp<AuthStackParamList, 'Register'>;
}
export function RegisterScreen({ navigation }: RegisterScreenProps) {
const { register } = useAuth();
const [displayName, setDisplayName] = useState('');
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [errors, setErrors] = useState<{
displayName?: string;
email?: string;
password?: string;
confirmPassword?: string;
}>({});
const validateForm = () => {
const newErrors: typeof errors = {};
if (!displayName.trim()) {
newErrors.displayName = 'Display name is required';
}
if (!email.trim()) {
newErrors.email = 'Email is required';
} else if (!/\S+@\S+\.\S+/.test(email)) {
newErrors.email = 'Please enter a valid email';
}
if (!password) {
newErrors.password = 'Password is required';
} else if (password.length < 8) {
newErrors.password = 'Password must be at least 8 characters';
}
if (!confirmPassword) {
newErrors.confirmPassword = 'Please confirm your password';
} else if (password !== confirmPassword) {
newErrors.confirmPassword = 'Passwords do not match';
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
};
const handleRegister = async () => {
if (!validateForm()) return;
setIsLoading(true);
try {
await register(email.trim(), password, displayName.trim());
// Navigate to pending approval screen
navigation.replace('PendingApproval');
} catch (error) {
const message = error instanceof Error ? error.message : 'Registration failed';
Alert.alert('Registration Failed', message);
} finally {
setIsLoading(false);
}
};
return (
<SafeAreaView style={styles.container}>
<KeyboardAvoidingView
style={styles.keyboardView}
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
>
<ScrollView
contentContainerStyle={styles.scrollContent}
keyboardShouldPersistTaps="handled"
>
{/* Header */}
<View style={styles.header}>
<View style={styles.logoContainer}>
<Text style={styles.logoText}>P</Text>
</View>
<Text style={styles.title}>Create Account</Text>
<Text style={styles.subtitle}>
Join Pierre to unlock AI-powered fitness insights
</Text>
</View>
{/* Registration Form */}
<View style={styles.form}>
<Input
label="Display Name"
placeholder="How should we call you?"
value={displayName}
onChangeText={setDisplayName}
autoCapitalize="words"
error={errors.displayName}
/>
<Input
label="Email"
placeholder="you@example.com"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
error={errors.email}
/>
<Input
label="Password"
placeholder="Minimum 8 characters"
value={password}
onChangeText={setPassword}
secureTextEntry
showPasswordToggle
error={errors.password}
/>
<Input
label="Confirm Password"
placeholder="Re-enter your password"
value={confirmPassword}
onChangeText={setConfirmPassword}
secureTextEntry
showPasswordToggle
error={errors.confirmPassword}
/>
<Button
title="Create Account"
onPress={handleRegister}
loading={isLoading}
fullWidth
style={styles.registerButton}
/>
</View>
{/* Login Link */}
<View style={styles.footer}>
<Text style={styles.footerText}>Already have an account?</Text>
<TouchableOpacity onPress={() => navigation.navigate('Login')}>
<Text style={styles.linkText}>Sign in</Text>
</TouchableOpacity>
</View>
</ScrollView>
</KeyboardAvoidingView>
</SafeAreaView>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: colors.background.primary,
},
keyboardView: {
flex: 1,
},
scrollContent: {
flexGrow: 1,
justifyContent: 'center',
paddingHorizontal: spacing.lg,
paddingVertical: spacing.xl,
},
header: {
alignItems: 'center',
marginBottom: spacing.xl,
},
logoContainer: {
width: 64,
height: 64,
borderRadius: borderRadius.lg,
backgroundColor: colors.primary[600],
alignItems: 'center',
justifyContent: 'center',
marginBottom: spacing.md,
},
logoText: {
fontSize: 32,
fontWeight: '700',
color: colors.text.primary,
},
title: {
fontSize: fontSize.xxl,
fontWeight: '700',
color: colors.text.primary,
marginBottom: spacing.xs,
},
subtitle: {
fontSize: fontSize.md,
color: colors.text.secondary,
textAlign: 'center',
lineHeight: 22,
},
form: {
marginBottom: spacing.xl,
},
registerButton: {
marginTop: spacing.md,
},
footer: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
gap: spacing.xs,
},
footerText: {
color: colors.text.secondary,
fontSize: fontSize.sm,
},
linkText: {
color: colors.primary[500],
fontSize: fontSize.sm,
fontWeight: '600',
},
});