bw-expo-app/components/auth/auth-button.tsx

79 lines
2.0 KiB
TypeScript

import { TouchableOpacity, StyleSheet, Alert, ActivityIndicator } from "react-native";
import { router } from "expo-router";
import { ThemedText } from "@/components/themed-text";
import { useAuth } from "@/hooks/use-auth";
import { authClient } from "@/lib/auth/client";
import { useState } from "react";
export function AuthButton() {
const { isAuthenticated, user, isLoading: sessionLoading } = useAuth();
const [isSigningOut, setIsSigningOut] = useState(false);
const handleSignOut = async () => {
setIsSigningOut(true);
try {
await authClient.signOut();
router.replace("/(auth)/login");
} catch (error: any) {
Alert.alert("登出失败", error?.message || "请稍后重试");
} finally {
setIsSigningOut(false);
}
};
const handleSignIn = () => {
router.push("/(auth)/login");
};
if (sessionLoading) {
return (
<TouchableOpacity style={styles.button} disabled>
<ActivityIndicator size="small" color="#007AFF" />
</TouchableOpacity>
);
}
if (isAuthenticated) {
return (
<TouchableOpacity
style={styles.button}
onPress={handleSignOut}
disabled={isSigningOut}
>
{isSigningOut ? (
<ActivityIndicator size="small" color="#FF3B30" />
) : (
<ThemedText style={styles.signOutText}>
{user?.username ? `登出 (${user.username})` : "登出"}
</ThemedText>
)}
</TouchableOpacity>
);
}
return (
<TouchableOpacity style={styles.button} onPress={handleSignIn}>
<ThemedText style={styles.signInText}></ThemedText>
</TouchableOpacity>
);
}
const styles = StyleSheet.create({
button: {
paddingHorizontal: 16,
paddingVertical: 8,
borderRadius: 8,
minWidth: 80,
alignItems: "center",
justifyContent: "center",
},
signInText: {
color: "#007AFF",
fontWeight: "600",
},
signOutText: {
color: "#FF3B30",
fontWeight: "600",
},
});