wavelength_app/components/home/UserInfo.tsx

116 lines
3.7 KiB
TypeScript

import React, { useEffect, useState } from 'react';
import { StyleSheet, Alert, Image, TouchableOpacity } from 'react-native';
import { ThemedText, ThemedView } from '@/components/theme/Theme';
import { getUser, updateUser } from '@/components/services/SecureStore';
import { manipulateAsync, SaveFormat } from 'expo-image-manipulator';
import * as ImagePicker from 'expo-image-picker';
import { updateProfilePicture } from '@/constants/APIs';
import type { User } from '@/constants/Types';
type UserInfoProps = {
onPfpUpdate: (url: string) => void;
};
const UserInfo: React.FC<UserInfoProps> = ({ onPfpUpdate }) => {
const [user, setUser] = useState<User | null>(null);
useEffect(() => {
const fetchUserData = async () => {
try {
const user: User = await getUser() as User;
setUser(user);
if (user.pfpUrl)
onPfpUpdate(user.pfpUrl);
} catch (error) {
console.error('Error fetching user data:', error);
Alert.alert('Error', 'Failed to fetch user data.');
}
};
fetchUserData();
}, [onPfpUpdate]);
const handleUpdateProfilePicture = async () => {
const permissionResult = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (permissionResult.granted === false) {
Alert.alert(
'Permission Required',
'You need to grant permission to access your photo library.'
);
return;
}
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: true,
aspect: [4, 3],
quality: 1,
});
if (!result.canceled && result.assets[0].uri) {
try {
const manipulateResult = await manipulateAsync(
result.assets[0].uri,
[{resize: {width: 300, height: 300}}],
{compress: 0.7, format: SaveFormat.JPEG}
);
const user = await getUser() as User;
const updatedUser = await updateProfilePicture(user.id, manipulateResult.uri);
if (!updatedUser || !updatedUser.pfpUrl) throw new Error('Failed to update user profile picture.');
setUser(prevData => prevData ? {...prevData, pfpUrl: updatedUser.pfpUrl} as User : updatedUser as User);
await updateUser({pfpUrl: updatedUser.pfpUrl});
onPfpUpdate(updatedUser.pfpUrl);
} catch (error) {
console.error('Error updating profile picture:', error);
Alert.alert('Error', 'Failed to update profile picture.');
}
} else {
Alert.alert('Error', 'Failed to select an image.');
}
};
return (
<ThemedView style={styles.container}>
{user ? (
<ThemedView style={styles.profileContainer}>
<TouchableOpacity onPress={handleUpdateProfilePicture}>
<Image
source={user.pfpUrl ? {
uri: `${process.env.EXPO_PUBLIC_API_URL}${user.pfpUrl}`} :
require('@/assets/images/default-profile.png')}
style={styles.profilePicture}
/>
</TouchableOpacity>
<ThemedText style={styles.name}>{user.fullName}</ThemedText>
<ThemedText style={styles.email}>{user.email}</ThemedText>
</ThemedView>
) : (
<ThemedText>Loading user data...</ThemedText>
)}
</ThemedView>
);
};
export default UserInfo;
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
marginTop: 40,
},
profileContainer: {
alignItems: 'center',
marginTop: 20,
},
profilePicture: {
width: 100,
height: 100,
borderRadius: 50,
marginBottom: 10,
},
name: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 5,
},
email: {
fontSize: 16,
},
});