Skip to content

Commit 7b5a494

Browse files
author
Guillermo Machado
committed
feat: add delete account feature
1 parent 745dce4 commit 7b5a494

File tree

5 files changed

+102
-28
lines changed

5 files changed

+102
-28
lines changed

src/api/auth/use-user.tsx

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { createQuery } from 'react-query-kit';
1+
import { createMutation, createQuery } from 'react-query-kit';
22

33
import { client } from '../common';
44

@@ -10,6 +10,10 @@ export type User = {
1010
birthday: Date | null;
1111
};
1212

13+
export type DeleteUserVariables = {
14+
email: string;
15+
};
16+
1317
const getUser = async () => {
1418
const { data } = await client({
1519
url: '/v1/users',
@@ -18,7 +22,18 @@ const getUser = async () => {
1822
return data;
1923
};
2024

25+
const deleteUser = async (variables: DeleteUserVariables) => {
26+
const { data } = await client.delete('/v1/users', {
27+
data: variables,
28+
});
29+
return data;
30+
};
31+
2132
export const useUser = createQuery<User>({
2233
queryKey: ['getUser'],
2334
fetcher: getUser,
2435
});
36+
37+
export const useDeleteUser = createMutation<{}, DeleteUserVariables>({
38+
mutationFn: deleteUser,
39+
});

src/app/(app)/settings.tsx

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
import { Link } from 'expo-router';
33
import { useColorScheme } from 'nativewind';
44
import React from 'react';
5+
import { showMessage } from 'react-native-flash-message';
56

6-
import { useUser } from '@/api/auth/use-user';
7+
import { useDeleteUser, useUser } from '@/api/auth/use-user';
78
import { useAuth } from '@/components/providers/auth';
9+
import { DeleteAccountItem } from '@/components/settings/delete-account-item';
810
import { Item } from '@/components/settings/item';
911
import { ItemsContainer } from '@/components/settings/items-container';
1012
import { LanguageItem } from '@/components/settings/language-item';
@@ -15,12 +17,25 @@ import { colors, FocusAwareStatusBar, ScrollView, Text, View } from '@/ui';
1517
import { Website } from '@/ui/icons';
1618

1719
export default function Settings() {
18-
const { data: userData } = useUser();
1920
const { logout } = useAuth();
21+
const { data: userData } = useUser();
22+
const { mutateAsync: deleteUserAsync } = useDeleteUser({
23+
onSuccess: () => {
24+
logout();
25+
},
26+
onError: (error) => showMessage({ message: error.message, type: 'danger' }),
27+
});
2028
const { colorScheme } = useColorScheme();
2129
const iconColor =
2230
colorScheme === 'dark' ? colors.neutral[400] : colors.neutral[500];
2331

32+
const handleDeleteUser = async () => {
33+
if (!userData?.email) {
34+
return;
35+
}
36+
await deleteUserAsync({ email: userData?.email });
37+
};
38+
2439
return (
2540
<>
2641
<FocusAwareStatusBar />
@@ -77,6 +92,7 @@ export default function Settings() {
7792

7893
<View className="my-8">
7994
<ItemsContainer>
95+
<DeleteAccountItem onDelete={handleDeleteUser} />
8096
<Item text="settings.logout" onPress={logout} />
8197
</ItemsContainer>
8298
</View>
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React from 'react';
2+
import { Alert } from 'react-native';
3+
4+
import { translate } from '@/core';
5+
6+
import { Item } from './item';
7+
8+
export type DeleteAccountItemProps = {
9+
onDelete: () => void;
10+
};
11+
12+
export const DeleteAccountItem = (props: DeleteAccountItemProps) => {
13+
const handleDeleteAccount = () => {
14+
props.onDelete();
15+
};
16+
17+
const confirmDelete = () => {
18+
Alert.alert(
19+
translate('settings.deleteAccount.confirmTitle'),
20+
translate('settings.deleteAccount.confirmMessage'),
21+
[
22+
{ text: translate('settings.deleteAccount.cancel'), style: 'cancel' },
23+
{
24+
text: translate('settings.deleteAccount.delete'),
25+
style: 'destructive',
26+
onPress: handleDeleteAccount,
27+
},
28+
],
29+
);
30+
};
31+
32+
return <Item text={'settings.deleteAccount.title'} onPress={confirmDelete} />;
33+
};

src/components/settings/item.tsx

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React from 'react';
1+
import React, { forwardRef } from 'react';
22

33
import type { TxKeyPath } from '@/core';
44
import { Pressable, Text, View } from '@/ui';
@@ -11,26 +11,29 @@ type ItemProps = {
1111
icon?: React.ReactNode;
1212
};
1313

14-
export const Item = ({ text, value, icon, onPress }: ItemProps) => {
15-
const isPressable = onPress !== undefined;
16-
return (
17-
<Pressable
18-
onPress={onPress}
19-
pointerEvents={isPressable ? 'auto' : 'none'}
20-
className="flex-1 flex-row items-center justify-between px-4 py-2"
21-
>
22-
<View className="flex-row items-center">
23-
{icon && <View className="pr-2">{icon}</View>}
24-
<Text tx={text} />
25-
</View>
26-
<View className="flex-row items-center">
27-
<Text className="text-neutral-600 dark:text-white">{value}</Text>
28-
{isPressable && (
29-
<View className="pl-2">
30-
<ArrowRight />
31-
</View>
32-
)}
33-
</View>
34-
</Pressable>
35-
);
36-
};
14+
export const Item = forwardRef<View, ItemProps>(
15+
({ text, value, icon, onPress }: ItemProps, ref) => {
16+
const isPressable = onPress !== undefined;
17+
return (
18+
<Pressable
19+
ref={ref}
20+
onPress={onPress}
21+
pointerEvents={isPressable ? 'auto' : 'none'}
22+
className="flex-1 flex-row items-center justify-between px-4 py-2"
23+
>
24+
<View className="flex-row items-center">
25+
{icon && <View className="pr-2">{icon}</View>}
26+
<Text tx={text} />
27+
</View>
28+
<View className="flex-row items-center">
29+
<Text className="text-neutral-600 dark:text-white">{value}</Text>
30+
{isPressable && (
31+
<View className="pl-2">
32+
<ArrowRight />
33+
</View>
34+
)}
35+
</View>
36+
</Pressable>
37+
);
38+
},
39+
);

src/translations/en.json

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,13 @@
7272
},
7373
"app_name": "App Name",
7474
"arabic": "Arabic",
75+
"deleteAccount": {
76+
"cancel": "Cancel",
77+
"confirmMessage": "Are you sure you want to delete your account? This action cannot be undone.",
78+
"confirmTitle": "Confirm Delete",
79+
"delete": "Delete",
80+
"title": "Delete account"
81+
},
7582
"english": "English",
7683
"generale": "General",
7784
"github": "Github",
@@ -83,7 +90,7 @@
8390
"rate": "Rate",
8491
"share": "Share",
8592
"support": "Support",
86-
"support_us": "Support Us",
93+
"supportUs": "Support Us",
8794
"terms": "Terms of Service",
8895
"theme": {
8996
"dark": "Dark",

0 commit comments

Comments
 (0)