Update expo application
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import { useState } from 'react';
|
||||
import { Alert, Text } from 'react-native';
|
||||
import { Stack } from 'expo-router';
|
||||
import { useAction, useMutation, useQuery } from 'convex/react';
|
||||
|
||||
import { api } from '@spoon/backend/convex/_generated/api.js';
|
||||
|
||||
import { AppScreen } from '~/components/ui/app-screen';
|
||||
import { Button } from '~/components/ui/button';
|
||||
import { Card } from '~/components/ui/card';
|
||||
import { Field } from '~/components/ui/field';
|
||||
import { titleize } from '~/utils/format';
|
||||
|
||||
const ProfileRoute = () => {
|
||||
const user = useQuery(api.auth.getUser, {});
|
||||
const provider = useQuery(api.auth.getUserProvider, {});
|
||||
const updateUser = useMutation(api.auth.updateUser);
|
||||
const updatePassword = useAction(api.auth.updateUserPassword);
|
||||
const [name, setName] = useState(user?.name ?? '');
|
||||
const [email, setEmail] = useState(user?.email ?? '');
|
||||
const [currentPassword, setCurrentPassword] = useState('');
|
||||
const [newPassword, setNewPassword] = useState('');
|
||||
const [savingProfile, setSavingProfile] = useState(false);
|
||||
const [savingPassword, setSavingPassword] = useState(false);
|
||||
|
||||
const saveProfile = async () => {
|
||||
setSavingProfile(true);
|
||||
try {
|
||||
await updateUser({ name, email });
|
||||
Alert.alert('Saved', 'Profile updated.');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
Alert.alert('Could not save profile.');
|
||||
} finally {
|
||||
setSavingProfile(false);
|
||||
}
|
||||
};
|
||||
|
||||
const savePassword = async () => {
|
||||
setSavingPassword(true);
|
||||
try {
|
||||
await updatePassword({ currentPassword, newPassword });
|
||||
setCurrentPassword('');
|
||||
setNewPassword('');
|
||||
Alert.alert('Saved', 'Password updated.');
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
Alert.alert('Could not update password.');
|
||||
} finally {
|
||||
setSavingPassword(false);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<AppScreen>
|
||||
<Stack.Screen options={{ title: 'Profile' }} />
|
||||
<Text className='text-foreground text-3xl font-bold'>Profile</Text>
|
||||
<Card className='gap-4'>
|
||||
<Text className='text-muted-foreground text-sm'>
|
||||
Email is currently managed by {titleize(provider ?? 'your provider')}.
|
||||
</Text>
|
||||
<Field label='Name' value={name} onChangeText={setName} />
|
||||
<Field
|
||||
keyboardType='email-address'
|
||||
label='Email'
|
||||
value={email}
|
||||
onChangeText={setEmail}
|
||||
/>
|
||||
<Button disabled={savingProfile} onPress={() => void saveProfile()}>
|
||||
{savingProfile ? 'Saving...' : 'Save profile'}
|
||||
</Button>
|
||||
</Card>
|
||||
{provider === 'password' ? (
|
||||
<Card className='gap-4'>
|
||||
<Text className='text-foreground font-semibold'>Password</Text>
|
||||
<Field
|
||||
label='Current password'
|
||||
secureTextEntry
|
||||
value={currentPassword}
|
||||
onChangeText={setCurrentPassword}
|
||||
/>
|
||||
<Field
|
||||
label='New password'
|
||||
secureTextEntry
|
||||
value={newPassword}
|
||||
onChangeText={setNewPassword}
|
||||
/>
|
||||
<Button
|
||||
disabled={savingPassword}
|
||||
variant='outline'
|
||||
onPress={() => void savePassword()}
|
||||
>
|
||||
{savingPassword ? 'Updating...' : 'Update password'}
|
||||
</Button>
|
||||
</Card>
|
||||
) : (
|
||||
<Card>
|
||||
<Text className='text-muted-foreground text-sm leading-5'>
|
||||
Password changes are hidden because this account is currently using{' '}
|
||||
{titleize(provider ?? 'an OAuth provider')}.
|
||||
</Text>
|
||||
</Card>
|
||||
)}
|
||||
</AppScreen>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProfileRoute;
|
||||
Reference in New Issue
Block a user