mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
Update
This commit is contained in:
1 parent
4d53d83769
commit
6ff5bc62f2
17 files changed
+2599
-1136
No files matched your search
+332
-262
@@ -2,7 +2,6 @@ import { useState } from "react";
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
TextInput,
|
||||
TouchableOpacity,
|
||||
StyleSheet,
|
||||
Alert,
|
||||
@@ -12,9 +11,16 @@ import {
|
||||
} from "react-native";
|
||||
import { Redirect } from "expo-router";
|
||||
import * as Linking from "expo-linking";
|
||||
import Animated, {
|
||||
FadeIn,
|
||||
FadeInDown,
|
||||
FadeInUp,
|
||||
} from "react-native-reanimated";
|
||||
import { Ionicons } from "@expo/vector-icons";
|
||||
import { supabase } from "../../src/lib/supabase";
|
||||
import { useAuthStore } from "../../src/store";
|
||||
|
||||
import { GradientBackground, GlassCard, GlassButton, GlassInput } from "../../src/components/ui";
|
||||
import { colors, spacing, radius, typography } from "../../src/theme";
|
||||
|
||||
type AuthMode = "magic-link" | "password";
|
||||
|
||||
@@ -25,22 +31,32 @@ export default function LoginScreen() {
|
||||
const [isMagicLinkSent, setIsMagicLinkSent] = useState(false);
|
||||
const [authMode, setAuthMode] = useState<AuthMode>("magic-link");
|
||||
const [isSignUp, setIsSignUp] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const { isAuthenticated } = useAuthStore();
|
||||
|
||||
// Use declarative Redirect instead of imperative router.replace()
|
||||
// This ensures navigation only happens after the Root Layout is mounted
|
||||
const showError = (message: string) => {
|
||||
setError(message);
|
||||
// Also show native alert on mobile
|
||||
if (Platform.OS !== 'web') {
|
||||
Alert.alert("Error", message);
|
||||
}
|
||||
};
|
||||
|
||||
const clearError = () => setError(null);
|
||||
|
||||
if (isAuthenticated) {
|
||||
return <Redirect href="/" />;
|
||||
}
|
||||
|
||||
const handleMagicLink = async () => {
|
||||
clearError();
|
||||
if (!email.trim()) {
|
||||
Alert.alert("Error", "Please enter your email");
|
||||
showError("Please enter your email");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
const { error } = await supabase.auth.signInWithOtp({
|
||||
const { error: authError } = await supabase.auth.signInWithOtp({
|
||||
email: email.trim(),
|
||||
options: {
|
||||
emailRedirectTo: Linking.createURL("/(auth)/login"),
|
||||
@@ -49,56 +65,66 @@ export default function LoginScreen() {
|
||||
|
||||
setIsLoading(false);
|
||||
|
||||
if (error) {
|
||||
Alert.alert("Error", error.message);
|
||||
if (authError) {
|
||||
showError(authError.message);
|
||||
} else {
|
||||
setIsMagicLinkSent(true);
|
||||
}
|
||||
};
|
||||
|
||||
const handlePasswordAuth = async () => {
|
||||
clearError();
|
||||
if (!email.trim()) {
|
||||
Alert.alert("Error", "Please enter your email");
|
||||
showError("Please enter your email");
|
||||
return;
|
||||
}
|
||||
if (!password) {
|
||||
Alert.alert("Error", "Please enter your password");
|
||||
showError("Please enter your password");
|
||||
return;
|
||||
}
|
||||
if (isSignUp && password.length < 6) {
|
||||
Alert.alert("Error", "Password must be at least 6 characters");
|
||||
showError("Password must be at least 6 characters");
|
||||
return;
|
||||
}
|
||||
|
||||
setIsLoading(true);
|
||||
|
||||
if (isSignUp) {
|
||||
const { error } = await supabase.auth.signUp({
|
||||
const { error: signUpError } = await supabase.auth.signUp({
|
||||
email: email.trim(),
|
||||
password,
|
||||
});
|
||||
|
||||
setIsLoading(false);
|
||||
|
||||
if (error) {
|
||||
Alert.alert("Error", error.message);
|
||||
if (signUpError) {
|
||||
showError(signUpError.message);
|
||||
} else {
|
||||
Alert.alert(
|
||||
"Check your email",
|
||||
"We sent you a confirmation link to verify your email address.",
|
||||
[{ text: "OK" }]
|
||||
);
|
||||
// Show success message
|
||||
if (Platform.OS === 'web') {
|
||||
setError(null);
|
||||
Alert.alert(
|
||||
"Check your email",
|
||||
"We sent you a confirmation link to verify your email address."
|
||||
);
|
||||
} else {
|
||||
Alert.alert(
|
||||
"Check your email",
|
||||
"We sent you a confirmation link to verify your email address.",
|
||||
[{ text: "OK" }]
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
const { error } = await supabase.auth.signInWithPassword({
|
||||
const { error: signInError } = await supabase.auth.signInWithPassword({
|
||||
email: email.trim(),
|
||||
password,
|
||||
});
|
||||
|
||||
setIsLoading(false);
|
||||
|
||||
if (error) {
|
||||
Alert.alert("Error", error.message);
|
||||
if (signInError) {
|
||||
showError(signInError.message);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -131,290 +157,334 @@ export default function LoginScreen() {
|
||||
|
||||
if (isMagicLinkSent) {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.content}>
|
||||
<Text style={styles.emoji}>✉️</Text>
|
||||
<Text style={styles.title}>Check your email</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
We sent a magic link to {email}
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
style={styles.secondaryButton}
|
||||
onPress={() => setIsMagicLinkSent(false)}
|
||||
<GradientBackground showAccent>
|
||||
<View style={styles.container}>
|
||||
<Animated.View
|
||||
entering={FadeInUp.duration(600).springify()}
|
||||
style={styles.content}
|
||||
>
|
||||
<Text style={styles.secondaryButtonText}>Try a different email</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={styles.iconContainer}>
|
||||
<Ionicons name="mail" size={48} color={colors.primary} />
|
||||
</View>
|
||||
<Text style={styles.title}>Check your email</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
We sent a magic link to{'\n'}
|
||||
<Text style={styles.emailHighlight}>{email}</Text>
|
||||
</Text>
|
||||
<GlassButton
|
||||
variant="ghost"
|
||||
onPress={() => setIsMagicLinkSent(false)}
|
||||
style={{ marginTop: spacing.lg }}
|
||||
>
|
||||
Try a different email
|
||||
</GlassButton>
|
||||
</Animated.View>
|
||||
</View>
|
||||
</View>
|
||||
</GradientBackground>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<KeyboardAvoidingView
|
||||
style={styles.container}
|
||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||
>
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
<GradientBackground showAccent>
|
||||
<KeyboardAvoidingView
|
||||
style={styles.container}
|
||||
behavior={Platform.OS === "ios" ? "padding" : "height"}
|
||||
>
|
||||
<View style={styles.content}>
|
||||
<Text style={styles.emoji}>💕</Text>
|
||||
<Text style={styles.title}>Sauci</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Explore intimacy together
|
||||
</Text>
|
||||
|
||||
{/* Auth Mode Toggle */}
|
||||
<View style={styles.modeToggleContainer}>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.modeToggle,
|
||||
authMode === "magic-link" && styles.modeToggleActive,
|
||||
]}
|
||||
onPress={() => setAuthMode("magic-link")}
|
||||
<ScrollView
|
||||
contentContainerStyle={styles.scrollContent}
|
||||
keyboardShouldPersistTaps="handled"
|
||||
showsVerticalScrollIndicator={false}
|
||||
>
|
||||
<View style={styles.content}>
|
||||
{/* Logo/Brand */}
|
||||
<Animated.View
|
||||
entering={FadeInDown.delay(100).duration(600).springify()}
|
||||
style={styles.brandContainer}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.modeToggleText,
|
||||
authMode === "magic-link" && styles.modeToggleTextActive,
|
||||
]}
|
||||
>
|
||||
Magic Link
|
||||
<View style={styles.logoContainer}>
|
||||
<Ionicons name="heart" size={40} color={colors.primary} />
|
||||
</View>
|
||||
<Text style={styles.title}>Sauci</Text>
|
||||
<Text style={styles.subtitle}>
|
||||
Explore intimacy together
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.modeToggle,
|
||||
authMode === "password" && styles.modeToggleActive,
|
||||
]}
|
||||
onPress={() => setAuthMode("password")}
|
||||
</Animated.View>
|
||||
|
||||
{/* Auth Card */}
|
||||
<Animated.View
|
||||
entering={FadeInDown.delay(200).duration(600).springify()}
|
||||
style={styles.formContainer}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.modeToggleText,
|
||||
authMode === "password" && styles.modeToggleTextActive,
|
||||
]}
|
||||
>
|
||||
Password
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<GlassCard variant="elevated">
|
||||
{/* Auth Mode Toggle */}
|
||||
<View style={styles.modeToggleContainer}>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.modeToggle,
|
||||
authMode === "magic-link" && styles.modeToggleActive,
|
||||
]}
|
||||
onPress={() => setAuthMode("magic-link")}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.modeToggleText,
|
||||
authMode === "magic-link" && styles.modeToggleTextActive,
|
||||
]}
|
||||
>
|
||||
Magic Link
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={[
|
||||
styles.modeToggle,
|
||||
authMode === "password" && styles.modeToggleActive,
|
||||
]}
|
||||
onPress={() => setAuthMode("password")}
|
||||
activeOpacity={0.7}
|
||||
>
|
||||
<Text
|
||||
style={[
|
||||
styles.modeToggleText,
|
||||
authMode === "password" && styles.modeToggleTextActive,
|
||||
]}
|
||||
>
|
||||
Password
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
|
||||
<View style={styles.form}>
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder="Enter your email"
|
||||
placeholderTextColor="#666"
|
||||
value={email}
|
||||
onChangeText={setEmail}
|
||||
keyboardType="email-address"
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
/>
|
||||
{/* Error Message */}
|
||||
{error && (
|
||||
<Animated.View
|
||||
entering={FadeIn.duration(200)}
|
||||
style={styles.errorContainer}
|
||||
>
|
||||
<Ionicons name="alert-circle" size={18} color={colors.error} />
|
||||
<Text style={styles.errorText}>{error}</Text>
|
||||
</Animated.View>
|
||||
)}
|
||||
|
||||
{authMode === "password" && (
|
||||
<TextInput
|
||||
style={styles.input}
|
||||
placeholder="Enter your password"
|
||||
placeholderTextColor="#666"
|
||||
value={password}
|
||||
onChangeText={setPassword}
|
||||
secureTextEntry
|
||||
autoCapitalize="none"
|
||||
/>
|
||||
)}
|
||||
{/* Form Fields */}
|
||||
<View style={styles.form}>
|
||||
<GlassInput
|
||||
placeholder="Enter your email"
|
||||
value={email}
|
||||
onChangeText={(text) => { clearError(); setEmail(text); }}
|
||||
keyboardType="email-address"
|
||||
autoCapitalize="none"
|
||||
autoCorrect={false}
|
||||
icon={<Ionicons name="mail-outline" size={20} color={colors.textTertiary} />}
|
||||
/>
|
||||
|
||||
{authMode === "magic-link" ? (
|
||||
<TouchableOpacity
|
||||
style={[styles.button, isLoading && styles.buttonDisabled]}
|
||||
onPress={handleMagicLink}
|
||||
disabled={isLoading}
|
||||
>
|
||||
<Text style={styles.buttonText}>
|
||||
{isLoading ? "Sending..." : "Continue with Magic Link"}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
) : (
|
||||
<>
|
||||
<TouchableOpacity
|
||||
style={[styles.button, isLoading && styles.buttonDisabled]}
|
||||
onPress={handlePasswordAuth}
|
||||
disabled={isLoading}
|
||||
{authMode === "password" && (
|
||||
<GlassInput
|
||||
placeholder="Enter your password"
|
||||
value={password}
|
||||
onChangeText={(text) => { clearError(); setPassword(text); }}
|
||||
secureTextEntry
|
||||
autoCapitalize="none"
|
||||
icon={<Ionicons name="lock-closed-outline" size={20} color={colors.textTertiary} />}
|
||||
/>
|
||||
)}
|
||||
|
||||
{authMode === "magic-link" ? (
|
||||
<GlassButton
|
||||
onPress={handleMagicLink}
|
||||
loading={isLoading}
|
||||
disabled={isLoading}
|
||||
fullWidth
|
||||
>
|
||||
Continue with Magic Link
|
||||
</GlassButton>
|
||||
) : (
|
||||
<>
|
||||
<GlassButton
|
||||
onPress={handlePasswordAuth}
|
||||
loading={isLoading}
|
||||
disabled={isLoading}
|
||||
fullWidth
|
||||
>
|
||||
{isSignUp ? "Create Account" : "Sign In"}
|
||||
</GlassButton>
|
||||
<TouchableOpacity
|
||||
style={styles.toggleSignUp}
|
||||
onPress={() => setIsSignUp(!isSignUp)}
|
||||
>
|
||||
<Text style={styles.toggleSignUpText}>
|
||||
{isSignUp
|
||||
? "Already have an account? Sign In"
|
||||
: "Don't have an account? Sign Up"}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
)}
|
||||
</View>
|
||||
</GlassCard>
|
||||
</Animated.View>
|
||||
|
||||
{/* Social Sign In */}
|
||||
<Animated.View
|
||||
entering={FadeInDown.delay(300).duration(600).springify()}
|
||||
style={styles.socialContainer}
|
||||
>
|
||||
<View style={styles.divider}>
|
||||
<View style={styles.dividerLine} />
|
||||
<Text style={styles.dividerText}>or continue with</Text>
|
||||
<View style={styles.dividerLine} />
|
||||
</View>
|
||||
|
||||
<View style={styles.socialButtons}>
|
||||
<GlassButton
|
||||
variant="secondary"
|
||||
onPress={handleGoogleSignIn}
|
||||
icon={<Ionicons name="logo-google" size={20} color={colors.text} />}
|
||||
style={styles.socialButton}
|
||||
>
|
||||
<Text style={styles.buttonText}>
|
||||
{isLoading
|
||||
? isSignUp
|
||||
? "Creating Account..."
|
||||
: "Signing In..."
|
||||
: isSignUp
|
||||
? "Create Account"
|
||||
: "Sign In"}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<TouchableOpacity
|
||||
style={styles.toggleSignUp}
|
||||
onPress={() => setIsSignUp(!isSignUp)}
|
||||
Google
|
||||
</GlassButton>
|
||||
|
||||
<GlassButton
|
||||
variant="secondary"
|
||||
onPress={handleAppleSignIn}
|
||||
icon={<Ionicons name="logo-apple" size={20} color={colors.text} />}
|
||||
style={styles.socialButton}
|
||||
>
|
||||
<Text style={styles.toggleSignUpText}>
|
||||
{isSignUp
|
||||
? "Already have an account? Sign In"
|
||||
: "Don't have an account? Sign Up"}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</>
|
||||
)}
|
||||
|
||||
<View style={styles.divider}>
|
||||
<View style={styles.dividerLine} />
|
||||
<Text style={styles.dividerText}>or</Text>
|
||||
<View style={styles.dividerLine} />
|
||||
</View>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.socialButton}
|
||||
onPress={handleGoogleSignIn}
|
||||
>
|
||||
<Text style={styles.socialButtonText}>Continue with Google</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<TouchableOpacity
|
||||
style={styles.socialButton}
|
||||
onPress={handleAppleSignIn}
|
||||
>
|
||||
<Text style={styles.socialButtonText}>Continue with Apple</Text>
|
||||
</TouchableOpacity>
|
||||
Apple
|
||||
</GlassButton>
|
||||
</View>
|
||||
</Animated.View>
|
||||
</View>
|
||||
</View>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
</GradientBackground>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
flex: 1,
|
||||
backgroundColor: "#1a1a2e",
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
paddingHorizontal: 24,
|
||||
paddingTop: 80,
|
||||
alignItems: "center",
|
||||
},
|
||||
emoji: {
|
||||
fontSize: 64,
|
||||
marginBottom: 16,
|
||||
},
|
||||
title: {
|
||||
fontSize: 32,
|
||||
fontWeight: "bold",
|
||||
color: "#fff",
|
||||
marginBottom: 8,
|
||||
},
|
||||
subtitle: {
|
||||
fontSize: 16,
|
||||
color: "#888",
|
||||
marginBottom: 48,
|
||||
textAlign: "center",
|
||||
},
|
||||
form: {
|
||||
width: "100%",
|
||||
},
|
||||
input: {
|
||||
backgroundColor: "#16213e",
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
fontSize: 16,
|
||||
color: "#fff",
|
||||
marginBottom: 16,
|
||||
borderWidth: 1,
|
||||
borderColor: "#0f3460",
|
||||
},
|
||||
button: {
|
||||
backgroundColor: "#e94560",
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
alignItems: "center",
|
||||
},
|
||||
buttonDisabled: {
|
||||
opacity: 0.7,
|
||||
},
|
||||
buttonText: {
|
||||
color: "#fff",
|
||||
fontSize: 16,
|
||||
fontWeight: "600",
|
||||
},
|
||||
divider: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginVertical: 24,
|
||||
},
|
||||
dividerLine: {
|
||||
flex: 1,
|
||||
height: 1,
|
||||
backgroundColor: "#333",
|
||||
},
|
||||
dividerText: {
|
||||
color: "#666",
|
||||
paddingHorizontal: 16,
|
||||
},
|
||||
socialButton: {
|
||||
backgroundColor: "#16213e",
|
||||
borderRadius: 12,
|
||||
padding: 16,
|
||||
alignItems: "center",
|
||||
marginBottom: 12,
|
||||
borderWidth: 1,
|
||||
borderColor: "#0f3460",
|
||||
},
|
||||
socialButtonText: {
|
||||
color: "#fff",
|
||||
fontSize: 16,
|
||||
fontWeight: "500",
|
||||
},
|
||||
secondaryButton: {
|
||||
marginTop: 24,
|
||||
},
|
||||
secondaryButtonText: {
|
||||
color: "#e94560",
|
||||
fontSize: 16,
|
||||
},
|
||||
scrollContent: {
|
||||
flexGrow: 1,
|
||||
},
|
||||
content: {
|
||||
flex: 1,
|
||||
paddingHorizontal: spacing.lg,
|
||||
paddingTop: 80,
|
||||
paddingBottom: spacing.xl,
|
||||
},
|
||||
brandContainer: {
|
||||
alignItems: "center",
|
||||
marginBottom: spacing.xl,
|
||||
},
|
||||
logoContainer: {
|
||||
width: 80,
|
||||
height: 80,
|
||||
borderRadius: 40,
|
||||
backgroundColor: colors.primaryLight,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: spacing.md,
|
||||
},
|
||||
title: {
|
||||
...typography.largeTitle,
|
||||
color: colors.text,
|
||||
marginBottom: spacing.xs,
|
||||
},
|
||||
subtitle: {
|
||||
...typography.body,
|
||||
color: colors.textSecondary,
|
||||
textAlign: "center",
|
||||
},
|
||||
emailHighlight: {
|
||||
color: colors.primary,
|
||||
fontWeight: "600",
|
||||
},
|
||||
iconContainer: {
|
||||
width: 100,
|
||||
height: 100,
|
||||
borderRadius: 50,
|
||||
backgroundColor: colors.primaryLight,
|
||||
justifyContent: "center",
|
||||
alignItems: "center",
|
||||
marginBottom: spacing.lg,
|
||||
},
|
||||
formContainer: {
|
||||
marginBottom: spacing.lg,
|
||||
},
|
||||
modeToggleContainer: {
|
||||
flexDirection: "row",
|
||||
backgroundColor: "#16213e",
|
||||
borderRadius: 12,
|
||||
backgroundColor: colors.glass.background,
|
||||
borderRadius: radius.md,
|
||||
padding: 4,
|
||||
marginBottom: 24,
|
||||
width: "100%",
|
||||
marginBottom: spacing.lg,
|
||||
},
|
||||
modeToggle: {
|
||||
flex: 1,
|
||||
paddingVertical: 12,
|
||||
borderRadius: 8,
|
||||
borderRadius: radius.sm,
|
||||
alignItems: "center",
|
||||
},
|
||||
modeToggleActive: {
|
||||
backgroundColor: "#e94560",
|
||||
backgroundColor: colors.primary,
|
||||
},
|
||||
modeToggleText: {
|
||||
color: "#666",
|
||||
fontSize: 14,
|
||||
fontWeight: "500",
|
||||
...typography.subhead,
|
||||
color: colors.textTertiary,
|
||||
fontWeight: "600",
|
||||
},
|
||||
modeToggleTextActive: {
|
||||
color: "#fff",
|
||||
color: colors.text,
|
||||
},
|
||||
errorContainer: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
backgroundColor: colors.errorLight,
|
||||
padding: spacing.md,
|
||||
borderRadius: radius.md,
|
||||
marginBottom: spacing.md,
|
||||
gap: spacing.sm,
|
||||
},
|
||||
errorText: {
|
||||
...typography.subhead,
|
||||
color: colors.error,
|
||||
flex: 1,
|
||||
},
|
||||
form: {
|
||||
gap: spacing.sm,
|
||||
},
|
||||
toggleSignUp: {
|
||||
marginTop: 16,
|
||||
marginTop: spacing.md,
|
||||
alignItems: "center",
|
||||
},
|
||||
toggleSignUpText: {
|
||||
color: "#e94560",
|
||||
fontSize: 14,
|
||||
...typography.subhead,
|
||||
color: colors.primary,
|
||||
},
|
||||
socialContainer: {
|
||||
marginTop: spacing.md,
|
||||
},
|
||||
divider: {
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
marginBottom: spacing.lg,
|
||||
},
|
||||
dividerLine: {
|
||||
flex: 1,
|
||||
height: 1,
|
||||
backgroundColor: colors.glass.border,
|
||||
},
|
||||
dividerText: {
|
||||
...typography.caption1,
|
||||
color: colors.textTertiary,
|
||||
paddingHorizontal: spacing.md,
|
||||
},
|
||||
socialButtons: {
|
||||
flexDirection: "row",
|
||||
gap: spacing.md,
|
||||
},
|
||||
socialButton: {
|
||||
flex: 1,
|
||||
},
|
||||
});
|
||||
|
||||
Reference in new issue
Block a user