Utilisation de mutations plutôt que d'appels fetch directs
This commit is contained in:
@ -1,33 +1,45 @@
|
||||
import { DarkTheme, DefaultTheme, ThemeProvider } from '@react-navigation/native'
|
||||
import { Stack } from "expo-router"
|
||||
import { useColorScheme } from '@/hooks/useColorScheme'
|
||||
import { Stack, useNavigationContainerRef } from 'expo-router'
|
||||
import { StatusBar } from 'expo-status-bar'
|
||||
import { Provider as StoreProvider } from 'react-redux'
|
||||
import { MD3DarkTheme, MD3LightTheme, PaperProvider } from 'react-native-paper'
|
||||
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
|
||||
import { useReactNavigationDevTools } from '@dev-plugins/react-navigation'
|
||||
import { useReactQueryDevTools } from '@dev-plugins/react-query'
|
||||
import { useColorScheme } from '@/hooks/useColorScheme'
|
||||
import store from '@/utils/store'
|
||||
import { useStartBackgroundFetchServiceEffect } from '@/utils/background'
|
||||
import { useStartGeolocationServiceEffect } from '@/utils/geolocation'
|
||||
import LoginProvider from '@/components/LoginProvider'
|
||||
|
||||
const queryClient = new QueryClient()
|
||||
|
||||
export default function RootLayout() {
|
||||
useStartGeolocationServiceEffect()
|
||||
useStartBackgroundFetchServiceEffect()
|
||||
const colorScheme = useColorScheme()
|
||||
|
||||
const navigationRef = useNavigationContainerRef()
|
||||
useReactNavigationDevTools(navigationRef)
|
||||
|
||||
useReactQueryDevTools(queryClient)
|
||||
|
||||
return (
|
||||
<StoreProvider store={store}>
|
||||
<LoginProvider loginRedirect={'/login'}>
|
||||
<PaperProvider theme={colorScheme === 'dark' ? MD3DarkTheme : MD3LightTheme}>
|
||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="login" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="+not-found" />
|
||||
</Stack>
|
||||
<StatusBar style="auto" />
|
||||
</ThemeProvider>
|
||||
</PaperProvider>
|
||||
</LoginProvider>
|
||||
<QueryClientProvider client={queryClient}>
|
||||
<LoginProvider loginRedirect={'/login'}>
|
||||
<PaperProvider theme={colorScheme === 'dark' ? MD3DarkTheme : MD3LightTheme}>
|
||||
<ThemeProvider value={colorScheme === 'dark' ? DarkTheme : DefaultTheme}>
|
||||
<Stack>
|
||||
<Stack.Screen name="(tabs)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="login" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="+not-found" />
|
||||
</Stack>
|
||||
<StatusBar style="auto" />
|
||||
</ThemeProvider>
|
||||
</PaperProvider>
|
||||
</LoginProvider>
|
||||
</QueryClientProvider>
|
||||
</StoreProvider>
|
||||
)
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { useLoginMutation } from "@/hooks/mutations/useLoginMutation"
|
||||
import { useAuth, useAuthLogin, useAuthLogout } from "@/hooks/useAuth"
|
||||
import * as SecureStore from "@/utils/SecureStore"
|
||||
import { useMutation } from "@tanstack/react-query"
|
||||
import { useRouter } from "expo-router"
|
||||
import { useRef, useState } from "react"
|
||||
import { Platform } from "react-native"
|
||||
import { Appbar, Button, Dialog, Portal, Surface, Text, TextInput } from "react-native-paper"
|
||||
|
||||
export default function Login() {
|
||||
@ -13,7 +13,6 @@ export default function Login() {
|
||||
const authLogout = useAuthLogout()
|
||||
|
||||
const isLoggedIn = auth.loggedIn
|
||||
const [loggingIn, setLoggingIn] = useState(false)
|
||||
const [name, setName] = useState(auth.name ?? "")
|
||||
const [password, setPassword] = useState("")
|
||||
const [errorDialogVisible, setErrorDialogVisible] = useState(false)
|
||||
@ -25,80 +24,55 @@ export default function Login() {
|
||||
|
||||
const hideErrorDialog = () => setErrorDialogVisible(false)
|
||||
|
||||
async function login() {
|
||||
if (loggingIn)
|
||||
return
|
||||
setLoggingIn(true)
|
||||
const resp = await fetch(`${process.env.EXPO_PUBLIC_TRAINTRAPE_MOI_SERVER}/auth/login/`, {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ name: name, password: password })
|
||||
})
|
||||
.then(resp => resp.json())
|
||||
.catch(err => {
|
||||
const loginMutation = useLoginMutation({
|
||||
authLogin,
|
||||
onPostSuccess: () => {
|
||||
if (router.canGoBack())
|
||||
router.back()
|
||||
else
|
||||
router.navigate('/')
|
||||
},
|
||||
onError: ({ response, error }) => {
|
||||
setErrorDialogVisible(true)
|
||||
setErrorTitle("Erreur")
|
||||
setErrorText("Une erreur inconnue est survenue lors de la connexion. Veuillez réessayer plus tard. " + err)
|
||||
setLoggingIn(false)
|
||||
})
|
||||
if (!resp)
|
||||
return
|
||||
else if (resp.error) {
|
||||
setErrorDialogVisible(true)
|
||||
setErrorTitle(resp.error)
|
||||
setErrorText(resp.message)
|
||||
setLoggingIn(false)
|
||||
return
|
||||
if (response) {
|
||||
setErrorTitle(response.error)
|
||||
setErrorText(response.message)
|
||||
}
|
||||
else {
|
||||
setErrorTitle("Erreur")
|
||||
setErrorText(`Une erreur est survenue lors de la connexion : ${error}`)
|
||||
}
|
||||
}
|
||||
setLoggingIn(false)
|
||||
authLogin({ name: name, token: resp.accessToken })
|
||||
SecureStore.setItem("apiName", name)
|
||||
if (Platform.OS !== "web") {
|
||||
// Le stockage navigateur n'est pas sûr, on évite de stocker un mot de passe à l'intérieur
|
||||
SecureStore.setItem("apiPassword", password)
|
||||
}
|
||||
SecureStore.setItem("apiToken", resp.accessToken)
|
||||
if (router.canGoBack())
|
||||
router.back()
|
||||
else
|
||||
router.navigate('/')
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
authLogout()
|
||||
await SecureStore.deleteItemAsync("apiName")
|
||||
await SecureStore.deleteItemAsync("apiPassword")
|
||||
await SecureStore.deleteItemAsync("apiToken")
|
||||
}
|
||||
})
|
||||
|
||||
return (
|
||||
<Surface style={{ flex: 1 }}>
|
||||
<Appbar.Header>
|
||||
{isLoggedIn && router.canGoBack() ? <Appbar.BackAction onPress={() => router.back()} /> : undefined}
|
||||
<Appbar.Content title={"Connexion"} />
|
||||
{isLoggedIn ? <Appbar.Action icon={"logout"} onPress={logout} /> : undefined}
|
||||
{isLoggedIn ? <Appbar.Action icon={"logout"} onPress={authLogout} /> : undefined}
|
||||
</Appbar.Header>
|
||||
<TextInput
|
||||
ref={loginRef}
|
||||
label="Nom"
|
||||
value={name}
|
||||
onChangeText={(text) => setName(text)}
|
||||
onChangeText={setName}
|
||||
onSubmitEditing={() => passwordRef?.current.focus()}
|
||||
style={{ margin: 8 }} />
|
||||
<TextInput
|
||||
ref={passwordRef}
|
||||
label="Mot de passe"
|
||||
value={password}
|
||||
onChangeText={(text) => setPassword(text)}
|
||||
onSubmitEditing={login}
|
||||
onChangeText={setPassword}
|
||||
onSubmitEditing={() => loginMutation.mutate({ name, password })}
|
||||
secureTextEntry={true}
|
||||
style={{ margin: 8 }} />
|
||||
<Button
|
||||
key={loggingIn ? "disabledLoginButton" : "loginButton"}
|
||||
onPress={login}
|
||||
key={loginMutation.isPending ? "disabledLoginButton" : "loginButton"}
|
||||
onPress={() => loginMutation.mutate({ name, password })}
|
||||
mode={"contained"}
|
||||
icon="login"
|
||||
disabled={loggingIn}
|
||||
disabled={loginMutation.isPending}
|
||||
style={{ margin: 8 }}>
|
||||
Se connecter
|
||||
</Button>
|
||||
|
Reference in New Issue
Block a user