This repository has been archived on 2026-07-21. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
cloud-reader/mobile/src/screens/RegisterScreen.tsx
T
crisleo94 22ded87250 feat: implement mobile reader
- implement mobile epub reader
2026-06-20 13:33:44 -05:00

135 lines
3.8 KiB
TypeScript

import { useState, type ReactNode } from "react";
import {
Text,
TextInput,
TouchableOpacity,
Alert,
ActivityIndicator,
KeyboardAvoidingView,
Platform,
ScrollView,
} from "react-native";
import { useAuth } from "../context/AuthContext";
import { isStrongPassword } from "@cloud-reader/shared";
import { authStyles } from "./authStyles";
import { AuthFormError } from "./AuthFormError";
import { requireValidEmail } from "./authValidation";
export default function RegisterScreen({
navigation,
}: {
navigation: any;
}): ReactNode {
const { register } = useAuth();
const [username, setUsername] = useState("");
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [confirmPassword, setConfirmPassword] = useState("");
const [error, setError] = useState<string | null>(null);
const [submitting, setSubmitting] = useState(false);
const handleRegister = async () => {
setError(null);
if (!username.trim()) {
Alert.alert("Validation Error", "Please enter a username.");
return;
}
if (!requireValidEmail(email)) {
return;
}
if (!isStrongPassword(password)) {
Alert.alert(
"Validation Error",
"Password must be at least 8 characters and include uppercase, lowercase, and a number.",
);
return;
}
if (password !== confirmPassword) {
Alert.alert("Validation Error", "Passwords do not match.");
return;
}
setSubmitting(true);
try {
await register(email.trim(), username.trim(), password);
} catch {
setError("Could not create the account. Try a different email.");
} finally {
setSubmitting(false);
}
};
return (
<KeyboardAvoidingView
style={authStyles.container}
behavior={Platform.OS === "ios" ? "padding" : "height"}
>
<ScrollView contentContainerStyle={authStyles.innerScroll}>
<Text style={authStyles.titleCompact}>Create Account</Text>
<Text style={authStyles.subtitle}>Join Cloud Reader</Text>
{error ? <AuthFormError message={error} /> : null}
<TextInput
style={authStyles.input}
placeholder="Username"
placeholderTextColor="#666"
value={username}
onChangeText={setUsername}
autoCapitalize="none"
autoCorrect={false}
/>
<TextInput
style={authStyles.input}
placeholder="Email"
placeholderTextColor="#666"
value={email}
onChangeText={setEmail}
keyboardType="email-address"
autoCapitalize="none"
autoCorrect={false}
/>
<TextInput
style={authStyles.input}
placeholder="Password"
placeholderTextColor="#666"
value={password}
onChangeText={setPassword}
secureTextEntry
/>
<TextInput
style={authStyles.input}
placeholder="Confirm Password"
placeholderTextColor="#666"
value={confirmPassword}
onChangeText={setConfirmPassword}
secureTextEntry
/>
<TouchableOpacity
style={[authStyles.button, submitting && authStyles.buttonDisabled]}
onPress={handleRegister}
disabled={submitting}
>
{submitting ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={authStyles.buttonText}>Create Account</Text>
)}
</TouchableOpacity>
<TouchableOpacity onPress={() => navigation.goBack()}>
<Text style={authStyles.linkText}>
Already have an account?{" "}
<Text style={authStyles.linkBold}>Sign In</Text>
</Text>
</TouchableOpacity>
</ScrollView>
</KeyboardAvoidingView>
);
}