Skip to content

Commit 745dce4

Browse files
Merge pull request #116 from rootstrap/feat/auth-provider-proposal
Feat/auth provider proposal
2 parents 564f6df + 0bd0d8d commit 745dce4

File tree

12 files changed

+503
-31
lines changed

12 files changed

+503
-31
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,10 @@
6969
"@lukemorales/query-key-factory": "^1.3.4",
7070
"@shopify/flash-list": "1.6.4",
7171
"@tanstack/react-query": "^5.52.1",
72+
"@testing-library/react-hooks": "^8.0.1",
7273
"app-icon-badge": "^0.0.15",
7374
"axios": "^1.7.5",
75+
"dayjs": "^1.11.13",
7476
"expo": "~51.0.39",
7577
"expo-constants": "~16.0.2",
7678
"expo-dev-client": "~4.0.29",

pnpm-lock.yaml

Lines changed: 43 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/api/auth/use-user.tsx

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import { createQuery } from 'react-query-kit';
2+
3+
import { client } from '../common';
4+
5+
export type User = {
6+
id: number;
7+
name: string;
8+
email: string;
9+
picture: string | null;
10+
birthday: Date | null;
11+
};
12+
13+
const getUser = async () => {
14+
const { data } = await client({
15+
url: '/v1/users',
16+
method: 'GET',
17+
});
18+
return data;
19+
};
20+
21+
export const useUser = createQuery<User>({
22+
queryKey: ['getUser'],
23+
fetcher: getUser,
24+
});

src/api/types.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,9 @@ export type PaginateQuery<T> = {
44
next: string | null;
55
previous: string | null;
66
};
7+
8+
export type ApiResponse<T> =
9+
| {
10+
errors: string[];
11+
}
12+
| T;

src/app/(app)/_layout.tsx

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import { Link, Redirect, SplashScreen, Tabs } from 'expo-router';
22
import { useCallback, useEffect } from 'react';
33

4-
import { useAuth, useIsFirstTime } from '@/core';
4+
import { useAuth } from '@/components/providers/auth';
5+
import { useIsFirstTime } from '@/core';
56
import { Pressable, Text } from '@/ui';
67
import {
78
Feed as FeedIcon,
@@ -10,24 +11,22 @@ import {
1011
} from '@/ui/icons';
1112

1213
export default function TabLayout() {
13-
const status = useAuth.use.status();
14+
const { isAuthenticated, ready } = useAuth();
1415
const [isFirstTime] = useIsFirstTime();
1516
const hideSplash = useCallback(async () => {
1617
await SplashScreen.hideAsync();
1718
}, []);
19+
1820
useEffect(() => {
19-
const TIMEOUT = 1000;
20-
if (status !== 'idle') {
21-
setTimeout(() => {
22-
hideSplash();
23-
}, TIMEOUT);
21+
if (!ready) {
22+
hideSplash();
2423
}
25-
}, [hideSplash, status]);
24+
}, [hideSplash, ready]);
2625

2726
if (isFirstTime) {
2827
return <Redirect href="/onboarding" />;
2928
}
30-
if (status === 'signOut') {
29+
if (!isAuthenticated && ready) {
3130
return <Redirect href="/sign-in" />;
3231
}
3332
return (
@@ -45,7 +44,6 @@ export default function TabLayout() {
4544
name="style"
4645
options={{
4746
title: 'Style',
48-
headerShown: false,
4947
tabBarIcon: ({ color }) => <StyleIcon color={color} />,
5048
tabBarTestID: 'style-tab',
5149
}}
@@ -54,7 +52,6 @@ export default function TabLayout() {
5452
name="settings"
5553
options={{
5654
title: 'Settings',
57-
headerShown: false,
5855
tabBarIcon: ({ color }) => <SettingsIcon color={color} />,
5956
tabBarTestID: 'settings-tab',
6057
}}

src/app/(app)/settings.tsx

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,41 @@
1-
import { Env } from '@env';
1+
/* eslint-disable max-lines-per-function */
22
import { Link } from 'expo-router';
33
import { useColorScheme } from 'nativewind';
44
import React from 'react';
55

6+
import { useUser } from '@/api/auth/use-user';
7+
import { useAuth } from '@/components/providers/auth';
68
import { Item } from '@/components/settings/item';
79
import { ItemsContainer } from '@/components/settings/items-container';
810
import { LanguageItem } from '@/components/settings/language-item';
911
import { ThemeItem } from '@/components/settings/theme-item';
10-
import { translate, useAuth } from '@/core';
12+
import { translate } from '@/core';
13+
import { Env } from '@/core/env';
1114
import { colors, FocusAwareStatusBar, ScrollView, Text, View } from '@/ui';
1215
import { Website } from '@/ui/icons';
1316

1417
export default function Settings() {
15-
const signOut = useAuth.use.signOut();
18+
const { data: userData } = useUser();
19+
const { logout } = useAuth();
1620
const { colorScheme } = useColorScheme();
1721
const iconColor =
1822
colorScheme === 'dark' ? colors.neutral[400] : colors.neutral[500];
1923

2024
return (
2125
<>
2226
<FocusAwareStatusBar />
23-
2427
<ScrollView>
25-
<View className="flex-1 px-4 pt-16 ">
28+
<View className="flex-1 gap-2 p-4">
2629
<Text className="text-xl font-bold">
2730
{translate('settings.title')}
2831
</Text>
32+
<ItemsContainer title="settings.account.title">
33+
<Item text={'settings.account.name'} value={userData?.name ?? ''} />
34+
<Item
35+
text={'settings.account.email'}
36+
value={userData?.email ?? ''}
37+
/>
38+
</ItemsContainer>
2939
<ItemsContainer title="settings.generale">
3040
<LanguageItem />
3141
<ThemeItem />
@@ -67,7 +77,7 @@ export default function Settings() {
6777

6878
<View className="my-8">
6979
<ItemsContainer>
70-
<Item text="settings.logout" onPress={signOut} />
80+
<Item text="settings.logout" onPress={logout} />
7181
</ItemsContainer>
7282
</View>
7383
</View>

src/app/_layout.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { KeyboardProvider } from 'react-native-keyboard-controller';
1212

1313
import { APIProvider } from '@/api';
1414
import interceptors from '@/api/common/interceptors';
15+
import { AuthProvider } from '@/components/providers/auth';
1516
import { hydrateAuth, loadSelectedTheme } from '@/core';
1617
import { useThemeConfig } from '@/core/use-theme-config';
1718

@@ -61,10 +62,12 @@ function Providers({ children }: { children: React.ReactNode }) {
6162
<KeyboardProvider>
6263
<ThemeProvider value={theme}>
6364
<APIProvider>
64-
<BottomSheetModalProvider>
65-
{children}
66-
<FlashMessage position="top" />
67-
</BottomSheetModalProvider>
65+
<AuthProvider>
66+
<BottomSheetModalProvider>
67+
{children}
68+
<FlashMessage position="top" />
69+
</BottomSheetModalProvider>
70+
</AuthProvider>
6871
</APIProvider>
6972
</ThemeProvider>
7073
</KeyboardProvider>

0 commit comments

Comments
 (0)