This commit is contained in:
dios.one
2026-04-21 18:00:30 +07:00
parent 2173a765c9
commit 23dc306f12
67 changed files with 10302 additions and 67 deletions
+152
View File
@@ -0,0 +1,152 @@
import React, { useState } from 'react';
import { View, Text, StyleSheet, TouchableOpacity, KeyboardAvoidingView, Platform } from 'react-native';
import { showAlert } from '../components/NovaAlert';
import ScreenWrapper from '../components/ScreenWrapper';
import Input from '../components/Input';
import Button from '../components/Button';
import useAuthStore from '../store/useAuthStore';
import { colors, fonts, spacing } from '../utils/theme';
export default function RegisterScreen({ navigation }) {
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const [confirmPassword, setConfirmPassword] = useState('');
const [loading, setLoading] = useState(false);
const register = useAuthStore((s) => s.register);
const setSession = useAuthStore((s) => s.setSession);
const goToOnboarding = () => {
navigation.reset({ index: 0, routes: [{ name: 'Onboarding' }] });
};
const handleRegister = async () => {
if (!email.trim() || !password.trim()) {
showAlert('Error', 'Please fill in all fields');
return;
}
if (password !== confirmPassword) {
showAlert('Error', 'Passwords do not match');
return;
}
if (password.length < 6) {
showAlert('Error', 'Password must be at least 6 characters');
return;
}
setLoading(true);
try {
const data = await register(email.trim(), password);
// If registration returned a session (offline mode or auto-confirm), log in directly
if (data?.session) {
setSession(data.session);
goToOnboarding();
} else {
showAlert(
'Account Created',
'Check your email to confirm your account, then sign in.',
[{ text: 'OK', onPress: () => navigation.navigate('Login') }]
);
}
} catch (error) {
showAlert('Registration Failed', error.message);
} finally {
setLoading(false);
}
};
return (
<ScreenWrapper>
<KeyboardAvoidingView
behavior={Platform.OS === 'ios' ? 'padding' : 'height'}
style={styles.container}
>
<View style={styles.header}>
<Text style={styles.title}>Begin Your Journey</Text>
<Text style={styles.subtitle}>Create your Nova40 identity</Text>
</View>
<View style={styles.form}>
<Input
label="Email"
value={email}
onChangeText={setEmail}
placeholder="your@email.com"
keyboardType="email-address"
/>
<Input
label="Password"
value={password}
onChangeText={setPassword}
placeholder="At least 6 characters"
secureTextEntry
/>
<Input
label="Confirm Password"
value={confirmPassword}
onChangeText={setConfirmPassword}
placeholder="Repeat your password"
secureTextEntry
/>
<Button
title="Create Account"
onPress={handleRegister}
loading={loading}
style={styles.button}
/>
</View>
<View style={styles.footer}>
<Text style={styles.footerText}>Already have an account? </Text>
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text style={styles.footerLink}>Sign In</Text>
</TouchableOpacity>
</View>
</KeyboardAvoidingView>
</ScreenWrapper>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
paddingHorizontal: spacing.lg,
},
header: {
marginBottom: spacing.xxl,
},
title: {
color: colors.text,
fontSize: fonts.sizes.xxl,
fontWeight: fonts.weights.bold,
marginBottom: spacing.xs,
},
subtitle: {
color: colors.textSecondary,
fontSize: fonts.sizes.md,
},
form: {
marginBottom: spacing.xl,
},
button: {
marginTop: spacing.md,
},
footer: {
flexDirection: 'row',
justifyContent: 'center',
},
footerText: {
color: colors.textSecondary,
fontSize: fonts.sizes.sm,
},
footerLink: {
color: colors.primary,
fontSize: fonts.sizes.sm,
fontWeight: fonts.weights.semibold,
},
});