diff --git a/.env.example b/.env.example index 4bbccf73..cc50bfdb 100644 --- a/.env.example +++ b/.env.example @@ -2,6 +2,7 @@ NODE_ENV= API_HOST= REACT_NATIVE_APP_VERSION_NR= REACT_NATIVE_APP_AUTH0_DOMAIN= +REACT_NATIVE_APP_AUTH0_AUDIENCE= REACT_NATIVE_APP_AUTH0_SCHEME= REACT_NATIVE_APP_AUTH0_CLIENT_ID= REACT_NATIVE_APP_ENCRYPTION_KEY= diff --git a/package.json b/package.json index ff5bb22a..daf80978 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,7 @@ "@tanstack/query-sync-storage-persister": "^4.14.5", "@tanstack/react-query": "^4.14.1", "@tanstack/react-query-persist-client": "^4.14.5", - "axios": "^1.1.3", + "axios": "1.2.0-alpha.1", "color": "^4.2.3", "date-fns": "^2.29.3", "i18next": "^22.0.4", diff --git a/src/App.tsx b/src/App.tsx index c9471759..2303214c 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -7,7 +7,7 @@ import { ThemeProvider } from 'styled-components/native'; import { AuthenticationProvider } from './_context'; import { StorageKey } from './_models'; -// import { QueryClientProvider } from './_providers'; +import { QueryClientProvider } from './_providers'; import RootStackNavigator from './_routing'; import { theme } from './_styles/theme'; import { storage } from './storage'; @@ -24,15 +24,14 @@ const App = () => { return ( - {/* @TODO: Uncomment when react-query is used in the source code */} - {/* */} - - - - - - - {/* */} + + + + + + + + ); diff --git a/src/_hooks/usePubliqApi.ts b/src/_hooks/usePubliqApi.ts new file mode 100644 index 00000000..46d6bbc0 --- /dev/null +++ b/src/_hooks/usePubliqApi.ts @@ -0,0 +1,38 @@ +import { useCallback } from 'react'; +import { Config } from 'react-native-config'; +import { QueryObserverOptions, useQuery } from '@tanstack/react-query'; + +import { useAuthentication } from '../_context'; +import { HttpClient, TApiError } from '../_http'; +import { Headers, Params } from '../_http/HttpClient'; + +type TGetOptions = { + enabled?: boolean; + headers?: Headers; + onError?: QueryObserverOptions['onError']; + onSuccess?: QueryObserverOptions['onSuccess']; + params?: Params; +}; + +export function usePubliqApi() { + const { accessToken } = useAuthentication(); + + const defaultHeaders: Headers = { + Authorization: `Bearer ${accessToken}`, + }; + + const get = useCallback( + (queryKey: unknown[], path: string, { headers = {}, params = {}, ...options }: TGetOptions = {}) => { + return useQuery({ + enabled: !!accessToken && (options.enabled === undefined || options.enabled), + onError: options.onError, + onSuccess: options.onSuccess, + queryFn: async () => HttpClient.get(`${Config.API_HOST}${path}`, params, { ...defaultHeaders, ...headers }), + queryKey, + }); + }, + [Config.API_HOST, accessToken], + ); + + return { get }; +} diff --git a/src/_http/HttpClient.ts b/src/_http/HttpClient.ts index af89b0ad..a0658033 100644 --- a/src/_http/HttpClient.ts +++ b/src/_http/HttpClient.ts @@ -4,8 +4,8 @@ import axios, { AxiosError, AxiosResponse, ResponseType } from 'axios'; import { TApiError, TValidationError } from './HttpError'; import { HttpStatus } from './HttpStatus'; -type Params = Record; -type Headers = Record; +export type Params = Record; +export type Headers = Record; class HttpClient { static getUrl(route: string): string { diff --git a/src/_routing/_components/RootStackNavigator.tsx b/src/_routing/_components/RootStackNavigator.tsx index efcef872..ed932d0c 100644 --- a/src/_routing/_components/RootStackNavigator.tsx +++ b/src/_routing/_components/RootStackNavigator.tsx @@ -4,12 +4,12 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack'; import { useAuthentication } from '../../_context'; import { StorageKey } from '../../_models'; -import Home from '../../login/Login'; +import Login from '../../login/Login'; import Onboarding from '../../onboarding/Onboarding'; import { storage } from '../../storage'; import { MainNavigator } from './MainNavigator'; -export type TRootRoutes = 'MainNavigator' | 'Onboarding' | 'Home'; +export type TRootRoutes = 'MainNavigator' | 'Onboarding' | 'Login'; export type TRootParams = Record; const RootStack = createNativeStackNavigator(); @@ -35,7 +35,7 @@ export const RootStackNavigator = () => { name="Onboarding" /> )} - {!isAuthenticated && } + {!isAuthenticated && } {isAuthenticated && } ); diff --git a/src/env.d.ts b/src/env.d.ts index 37457fcc..79e03d29 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -7,6 +7,7 @@ declare module 'react-native-config' { | 'NODE_ENV' | 'REACT_NATIVE_APP_AUTH0_CLIENT_ID' | 'REACT_NATIVE_APP_AUTH0_DOMAIN' + | 'REACT_NATIVE_APP_AUTH0_AUDIENCE' | 'REACT_NATIVE_APP_ENCRYPTION_KEY' | 'REACT_NATIVE_APP_VERSION_NR'; diff --git a/src/login/Login.tsx b/src/login/Login.tsx index 4b3520de..d170cd9c 100644 --- a/src/login/Login.tsx +++ b/src/login/Login.tsx @@ -1,5 +1,6 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; +import { Config } from 'react-native-config'; import { BrandLogo, DiagonalSplitView } from '../_components'; import { useAuthentication } from '../_context'; @@ -11,7 +12,7 @@ const Login = () => { const handleLogin = async () => { try { - await authorize({ scope: 'openid profile email offline_access' }); + await authorize({ audience: Config.REACT_NATIVE_APP_AUTH0_AUDIENCE, scope: 'openid profile email offline_access' }); } catch (e) { // @TODO: general error handling? console.error(e); diff --git a/src/onboarding/Onboarding.tsx b/src/onboarding/Onboarding.tsx index 11e4d482..f90a84dd 100644 --- a/src/onboarding/Onboarding.tsx +++ b/src/onboarding/Onboarding.tsx @@ -12,7 +12,7 @@ const Onboarding = () => { const onPress = () => { storage.set(StorageKey.IsPolicyApproved, true); - navigation.navigate('Home'); + navigation.navigate('Login'); }; return ( diff --git a/src/profile/Profile.tsx b/src/profile/Profile.tsx index aa8d36ec..0ce5282a 100644 --- a/src/profile/Profile.tsx +++ b/src/profile/Profile.tsx @@ -1,22 +1,25 @@ import React from 'react'; -import { SafeAreaView, ScrollView, Text } from 'react-native'; +import { Text } from 'react-native'; -import { Button } from '../_components'; +import { Button, SafeAreaView } from '../_components'; import { useToggle } from '../_hooks'; +import { useGetMe } from './_queries/useGetMe'; import LogoutModal from './LogOutModal'; const Profile = () => { const [logOutModalVisible, toggleLogOutModalVisible] = useToggle(false); + const { data, isLoading } = useGetMe(); + console.log({ data, isLoading }); // @TODO: remove this console.log return ( - - - + <> + {/* @TODO: This is placeholder content */} This is the profile page