normalize mobile auth and profile ui to theme components

This commit is contained in:
dimitar committed 2026-03-29 20:07:33 +02:00
1 parent 7ada05da6a
commit ed14c57749
7 files changed
+557 -615

No files matched your search

+54 -86
View File
@@ -4,7 +4,6 @@ import { useRouter } from "expo-router";
import {
View,
Text,
TextInput,
TouchableOpacity,
StyleSheet,
ActivityIndicator,
@@ -13,6 +12,9 @@ import {
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";
@@ -25,6 +27,7 @@ export default function SignInScreen() {
const [password, setPassword] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const { colors, typography } = useTheme();
// Redirect if already signed in
useEffect(() => {
@@ -77,8 +80,15 @@ export default function SignInScreen() {
if (isSignedIn) {
return (
<View style={[styles.container, styles.centerContent]}>
<ActivityIndicator size="large" color="#2563eb" />
<Text style={styles.loadingText}>Redirecting...</Text>
<ActivityIndicator size="large" color={colors.primary} />
<Text
style={[
typography.body,
{ color: colors.textSecondary, marginTop: 12 },
]}
>
Redirecting...
</Text>
</View>
);
}
@@ -86,19 +96,33 @@ export default function SignInScreen() {
return (
<KeyboardAvoidingView
behavior={Platform.OS === "ios" ? "padding" : "height"}
style={styles.container}
style={[styles.container, { backgroundColor: colors.background }]}
>
<ScrollView
contentContainerStyle={styles.scrollContent}
keyboardShouldPersistTaps="handled"
>
<View style={styles.content}>
<Text style={styles.title}>Welcome Back</Text>
<Text style={styles.subtitle}>Sign in to continue to FitAI</Text>
<Text
style={[typography.h1, { color: colors.textPrimary }, styles.title]}
>
Welcome Back
</Text>
<Text
style={[
typography.body,
{ color: colors.textSecondary },
styles.subtitle,
]}
>
Sign in to continue to FitAI
</Text>
{error ? (
<View style={styles.errorContainer}>
<Text style={styles.errorText}>{error}</Text>
<Text style={[typography.caption, { color: colors.danger }]}>
{error}
</Text>
</View>
) : null}
@@ -112,13 +136,11 @@ export default function SignInScreen() {
<View style={styles.form}>
<View style={styles.inputContainer}>
<Text style={styles.label}>Email</Text>
<TextInput
style={styles.input}
<Input
label="Email"
autoCapitalize="none"
value={emailAddress}
placeholder="Enter your email"
placeholderTextColor="#999"
onChangeText={setEmailAddress}
keyboardType="email-address"
autoComplete="email"
@@ -127,12 +149,10 @@ export default function SignInScreen() {
</View>
<View style={styles.inputContainer}>
<Text style={styles.label}>Password</Text>
<TextInput
style={styles.input}
<Input
label="Password"
value={password}
placeholder="Enter your password"
placeholderTextColor="#999"
secureTextEntry={true}
onChangeText={setPassword}
autoComplete="password"
@@ -140,26 +160,29 @@ export default function SignInScreen() {
/>
</View>
<TouchableOpacity
style={[styles.button, loading && styles.buttonDisabled]}
<MinimalButton
title="Sign In"
onPress={onSignInPress}
loading={loading}
disabled={loading || !emailAddress || !password}
>
{loading ? (
<ActivityIndicator color="#fff" />
) : (
<Text style={styles.buttonText}>Sign In</Text>
)}
</TouchableOpacity>
fullWidth
size="lg"
/>
</View>
<View style={styles.footer}>
<Text style={styles.footerText}>Don't have an account? </Text>
<Text style={[typography.caption, { color: colors.textSecondary }]}>
Don't have an account?{" "}
</Text>
<TouchableOpacity
onPress={() => router.push("/(auth)/sign-up")}
disabled={loading}
>
<Text style={styles.linkText}>Sign Up</Text>
<Text
style={[typography.bodyEmphasis, { color: colors.primary }]}
>
Sign Up
</Text>
</TouchableOpacity>
</View>
</View>
@@ -171,17 +194,11 @@ export default function SignInScreen() {
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",
@@ -193,27 +210,18 @@ const styles = StyleSheet.create({
paddingVertical: 40,
},
title: {
fontSize: 32,
fontWeight: "bold",
color: "#1a1a1a",
marginBottom: 8,
},
subtitle: {
fontSize: 16,
color: "#666",
marginBottom: 32,
},
errorContainer: {
backgroundColor: "#fee",
backgroundColor: "rgba(255, 59, 59, 0.08)",
padding: 12,
borderRadius: 8,
borderRadius: 12,
marginBottom: 16,
borderLeftWidth: 4,
borderLeftColor: "#f44",
},
errorText: {
color: "#c00",
fontSize: 14,
borderLeftColor: "#FF3B3B",
},
form: {
marginBottom: 24,
@@ -221,51 +229,11 @@ const styles = StyleSheet.create({
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",
@@ -274,11 +242,11 @@ const styles = StyleSheet.create({
dividerLine: {
flex: 1,
height: 1,
backgroundColor: "#ddd",
backgroundColor: "#E5E5EA",
},
dividerText: {
marginHorizontal: 10,
color: "#666",
color: "#8E8E93",
fontSize: 14,
},
});