Initial commit: Expo app with Better Auth integration
- Complete Expo React Native app setup with TypeScript - Better Auth authentication system integration - Secure storage implementation for session tokens - Authentication flow with login/logout functionality - API client configuration for backend communication - Responsive UI components with themed styling - Expo Router navigation setup - Development configuration and scripts 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
78
components/auth/auth-button.tsx
Normal file
78
components/auth/auth-button.tsx
Normal file
@@ -0,0 +1,78 @@
|
||||
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",
|
||||
},
|
||||
});
|
||||
Reference in New Issue
Block a user