import { useState, useEffect } from "react";
import { useSignIn, useAuth } from "@clerk/clerk-expo";
import { useRouter } from "expo-router";
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
ActivityIndicator,
KeyboardAvoidingView,
Platform,
ScrollView,
} from "react-native";
import { OAuthButtons } from "../../components/auth/OAuthButtons";
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("");
// 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 {
console.error(
"Sign-in incomplete:",
JSON.stringify(signInAttempt, null, 2),
);
setError("Sign-in incomplete. Please try again.");
}
} catch (err: any) {
console.error("Sign-in error:", JSON.stringify(err, null, 2));
// Handle specific error codes
if (err.errors?.[0]?.code === "session_exists") {
// User is already signed in, just redirect
router.replace("/(tabs)");
return;
}
setError(
err.errors?.[0]?.message ||
"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
Email
Password
{loading ? (
) : (
Sign In
)}
Don't have an account?
router.push("/(auth)/sign-up")}
disabled={loading}
>
Sign Up
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: "#f5f5f5",
},
centerContent: {
justifyContent: "center",
alignItems: "center",
},
loadingText: {
marginTop: 12,
fontSize: 16,
color: "#666",
},
scrollContent: {
flexGrow: 1,
justifyContent: "center",
},
content: {
flex: 1,
justifyContent: "center",
paddingHorizontal: 24,
paddingVertical: 40,
},
title: {
fontSize: 32,
fontWeight: "bold",
color: "#1a1a1a",
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: "#666",
marginBottom: 32,
},
errorContainer: {
backgroundColor: "#fee",
padding: 12,
borderRadius: 8,
marginBottom: 16,
borderLeftWidth: 4,
borderLeftColor: "#f44",
},
errorText: {
color: "#c00",
fontSize: 14,
},
form: {
marginBottom: 24,
},
inputContainer: {
marginBottom: 20,
},
label: {
fontSize: 14,
fontWeight: "600",
color: "#333",
marginBottom: 8,
},
input: {
backgroundColor: "#fff",
borderWidth: 1,
borderColor: "#ddd",
borderRadius: 8,
paddingHorizontal: 16,
paddingVertical: 12,
fontSize: 16,
color: "#1a1a1a",
},
button: {
backgroundColor: "#2563eb",
paddingVertical: 16,
borderRadius: 8,
alignItems: "center",
marginTop: 8,
},
buttonDisabled: {
backgroundColor: "#93c5fd",
},
buttonText: {
color: "#fff",
fontSize: 16,
fontWeight: "600",
},
footer: {
flexDirection: "row",
justifyContent: "center",
alignItems: "center",
},
footerText: {
fontSize: 14,
color: "#666",
},
linkText: {
fontSize: 14,
color: "#2563eb",
fontWeight: "600",
},
dividerContainer: {
flexDirection: "row",
alignItems: "center",
marginBottom: 24,
},
dividerLine: {
flex: 1,
height: 1,
backgroundColor: "#ddd",
},
dividerText: {
marginHorizontal: 10,
color: "#666",
fontSize: 14,
},
});