// src/screens/UserScreen.tsx
import { useState, useEffect } from "react";
import { View, Text, Image, ActivityIndicator, StyleSheet } from "react-native";
import { getUserQuery } from "@/queries/user.query";
type User = NonNullable<typeof getUserQuery.$infer.output.projected["user"]>;
export function UserScreen({ route }: { route: { params: { id: string } } }) {
const [user, setUser] = useState<User | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
useEffect(() => {
const fetchUser = async () => {
try {
const response = await fetch(process.env.EXPO_PUBLIC_GRAPHQL_URL!, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
query: getUserQuery.document,
variables: { id: route.params.id },
}),
});
const json = await response.json();
const data = getUserQuery.parse(json);
setUser(data.user);
} catch (err) {
setError(err instanceof Error ? err.message : "Unknown error");
} finally {
setLoading(false);
}
};
fetchUser();
}, [route.params.id]);
if (loading) {
return (
<View style={styles.center}>
<ActivityIndicator size="large" />
</View>
);
}
if (error) {
return (
<View style={styles.center}>
<Text style={styles.error}>{error}</Text>
</View>
);
}
if (!user) {
return (
<View style={styles.center}>
<Text>User not found</Text>
</View>
);
}
return (
<View style={styles.container}>
<Image source={{ uri: user.avatarUrl }} style={styles.avatar} />
<Text style={styles.name}>{user.name}</Text>
<Text style={styles.email}>{user.email}</Text>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, alignItems: "center", padding: 20 },
center: { flex: 1, justifyContent: "center", alignItems: "center" },
avatar: { width: 100, height: 100, borderRadius: 50, marginBottom: 16 },
name: { fontSize: 24, fontWeight: "bold", marginBottom: 8 },
email: { fontSize: 16, color: "#666" },
error: { color: "red", fontSize: 16 },
});