import { useState, useEffect } from "react"; import { useSignIn, useAuth } from "@clerk/clerk-expo"; import { useRouter } from "expo-router"; import { View, Text, TouchableOpacity, StyleSheet, ActivityIndicator, KeyboardAvoidingView, Platform, ScrollView, } from "react-native"; import { OAuthButtons } from "../../components/auth/OAuthButtons"; import { Input } from "../../components/Input"; import { MinimalButton } from "../../components/MinimalButton"; import { useTheme } from "../../contexts/ThemeContext"; import { getErrorMessage, getClerkErrorCode } from "../../utils/error-helpers"; import log from "../../utils/logger"; export default function SignInScreen() { const { signIn, setActive, isLoaded } = useSignIn(); const { isSignedIn } = useAuth(); const router = useRouter(); const [emailAddress, setEmailAddress] = useState(""); const [password, setPassword] = useState(""); const [loading, setLoading] = useState(false); const [error, setError] = useState(""); const { colors, typography } = useTheme(); // Redirect if already signed in useEffect(() => { if (isSignedIn) { router.replace("/(tabs)"); } }, [isSignedIn]); const onSignInPress = async () => { if (!isLoaded) return; setLoading(true); setError(""); try { const signInAttempt = await signIn.create({ identifier: emailAddress, password, }); if (signInAttempt.status === "complete") { await setActive({ session: signInAttempt.createdSessionId }); router.replace("/(tabs)"); } else { log.warn("Sign-in incomplete", { status: signInAttempt.status }); setError("Sign-in incomplete. Please try again."); } } catch (err: unknown) { log.error("Sign-in failed", err); // Handle specific error codes if (getClerkErrorCode(err) === "session_exists") { // User is already signed in, just redirect router.replace("/(tabs)"); return; } setError( getErrorMessage( err, "Failed to sign in. Please check your credentials.", ), ); } finally { setLoading(false); } }; // Don't render the form if already signed in if (isSignedIn) { return ( Redirecting... ); } return ( Welcome Back Sign in to continue to FitAI {error ? ( {error} ) : null} OR Don't have an account?{" "} router.push("/(auth)/sign-up")} disabled={loading} > Sign Up ); } const styles = StyleSheet.create({ container: { flex: 1, }, centerContent: { justifyContent: "center", alignItems: "center", }, scrollContent: { flexGrow: 1, justifyContent: "center", }, content: { flex: 1, justifyContent: "center", paddingHorizontal: 24, paddingVertical: 40, }, title: { marginBottom: 8, }, subtitle: { marginBottom: 32, }, errorContainer: { backgroundColor: "rgba(255, 59, 59, 0.08)", padding: 12, borderRadius: 12, marginBottom: 16, borderLeftWidth: 4, borderLeftColor: "#FF3B3B", }, form: { marginBottom: 24, }, inputContainer: { marginBottom: 20, }, footer: { flexDirection: "row", justifyContent: "center", alignItems: "center", }, dividerContainer: { flexDirection: "row", alignItems: "center", marginBottom: 24, }, dividerLine: { flex: 1, height: 1, backgroundColor: "#E5E5EA", }, dividerText: { marginHorizontal: 10, color: "#8E8E93", fontSize: 14, }, });