import type { ImainStackNavigator } from "@/navigations/Types"; import type { IuserInformations } from "@/utils/requests/Types"; import authenticateUser from "@/utils/requests/authenticateUser"; import getUserInformations from "@/utils/requests/userInformations"; import { LOG } from "@logger"; import { type NavigationProp, useNavigation } from "@react-navigation/native"; import { useMutation } from "@tanstack/react-query"; import type { AxiosError } from "axios"; import { createContext, useCallback, useContext, useState } from "react"; import type { IauthenticationData } from "./Types"; const log = LOG.extend("UserAuthenticationContext"); export interface UserAuthenticationContextProps { isAuthenticated: boolean; setIsAuthenticated: React.Dispatch>; setAuthenticationData: React.Dispatch>; userInformations: IuserInformations; setUserInformations: React.Dispatch>; login: (email: string, password: string) => void; isAuthenticating: boolean; logout: () => void; } export const UserAuthenticationContext = createContext({ isAuthenticated: false, setIsAuthenticated: () => {}, setAuthenticationData: () => {}, userInformations: { username: "", email: "", // biome-ignore lint/style/useNamingConvention: first_name: "", // biome-ignore lint/style/useNamingConvention: last_name: "", marchand: { // biome-ignore lint/style/useNamingConvention: marchand_id: "", nom: "", code: "", adresse: "", // biome-ignore lint/style/useNamingConvention: url_succes: "", // biome-ignore lint/style/useNamingConvention: url_echec: "", entreprise: 0, user: 0, }, }, setUserInformations: () => {}, login: () => {}, isAuthenticating: false, logout: () => {}, }); export const UserAuthenticationContextProvider = ({ children }: { children: React.ReactNode }) => { // States const [isAuthenticated, setIsAuthenticated] = useState(false); const [isAuthenticating, setIsAuthenticating] = useState(false); const [authenticationData, setAuthenticationData] = useState({ access: "", refresh: "", }); const [error, setError] = useState(""); const [userInformations, setUserInformations] = useState({ username: "JohnDoe", email: "JohnDoe@example.com", // biome-ignore lint/style/useNamingConvention: first_name: "John", // biome-ignore lint/style/useNamingConvention: last_name: "Doe", marchand: { // biome-ignore lint/style/useNamingConvention: marchand_id: "id123", nom: "Beasy", code: "BEASY-EXAMPLE-1", adresse: "Plateau 2, 1023, Immeuble Chardy", // biome-ignore lint/style/useNamingConvention: url_succes: "https://example.com/success", // biome-ignore lint/style/useNamingConvention: url_echec: "https://example.com/echec", entreprise: 0, user: 0, }, }); // Hoooks const navigation = useNavigation>(); // Mutations const authenticationMutation = useMutation({ mutationFn: authenticateUser, onMutate: () => { setIsAuthenticating(true); setError(""); }, onSuccess: (data) => { setAuthenticationData(data); // navigation.popToTop(); // navigation.replace("bottomTabs"); // navigation.navigate("bottomTabs"); log.info("Receive data from authenticateUser, running getUserInformations..."); userInformationsMutation.mutate(data.access); // console.log("user informations", userInformations); }, // biome-ignore lint/suspicious/noExplicitAny: onError: (error: AxiosError) => { log.error("authenticationMutation", error); if (error.response) { log.error("error :: ", error.response.data); if (error.response.status === 400) { return setError("Bad request"); } const message: string = error.response.data.detail; return setError(message); } setError("Unknown error"); }, }); const userInformationsMutation = useMutation({ mutationFn: (userAccessToken: string) => getUserInformations(userAccessToken), onMutate: () => { setIsAuthenticating(true); setError(""); }, onSettled: () => { setIsAuthenticating(false); }, onSuccess: (userInformations) => { log.info("getUserInformations request was a success, navigating to homepage"); setUserInformations(userInformations); navigation.navigate("appBottomTabsNavigator"); }, onError: (error) => { log.error("userInformationsMutation", error); }, }); // Methods const login = useCallback( (email: string, password: string) => { authenticationMutation.mutate({ username: email, password: password, }); }, [authenticationMutation], ); const logout = useCallback(() => { setIsAuthenticated(false); setAuthenticationData({ access: "", refresh: "", }); setUserInformations({ username: "", email: "", // biome-ignore lint/style/useNamingConvention: first_name: "", // biome-ignore lint/style/useNamingConvention: last_name: "", marchand: { // biome-ignore lint/style/useNamingConvention: marchand_id: "", nom: "", code: "", adresse: "", // biome-ignore lint/style/useNamingConvention: url_succes: "", // biome-ignore lint/style/useNamingConvention: url_echec: "", entreprise: 0, user: 0, }, }); navigation.reset({ index: 0, routes: [{ name: "userLoginScreen" }], }); }, [navigation]); return ( {children} ); }; export const useUserAuthenticationContext = () => { return useContext(UserAuthenticationContext); };