import { createContext, useCallback, useState } from 'react'; import { GoogleSignin } from '@react-native-google-signin/google-signin'; import Toast from 'react-native-toast-message'; import CACHE_KEYS from 'constants/cacheKeys'; import { removeCache, getCache, setCache } from 'utils/cache'; import { googleLoginApi, loginApi, signupApi, retrieveUserApi, linkUserDataApi, } from 'services/auth'; import { RegistrationRequest, LoginRequest, LoginResponse, AuthUserResponse, } from 'services/auth/models'; import { setAuthHeader, resetAuthHeader } from 'services/api'; import { iUserContext } from './types'; export const initialUser = { id: null, email: '', name: '', role: null, transaction_status: null, is_finished_onboarding: false, cart_id: null, }; export const UserContext = createContext({ user: initialUser, isAuthenticated: false, isLoading: false, isFirstLoading: false, setUser: (_: AuthUserResponse) => {}, getUser: () => Promise.reject(), signup: () => Promise.reject(), login: () => Promise.reject(), loginWithGoogle: () => Promise.reject(), logout: () => Promise.reject(), }); export const useUserContext = (): iUserContext => { const [user, setUser] = useState(initialUser); const [isLoading, setIsLoading] = useState(false); const [isFirstLoading, setIsFirstLoading] = useState(false); const logout = useCallback(async () => { await GoogleSignin.signOut(); await removeCache(CACHE_KEYS.authToken); await removeCache(CACHE_KEYS.refreshToken); resetAuthHeader(); setUser(initialUser); }, []); const getUser = useCallback(async () => { setIsFirstLoading(true); const token = await getCache(CACHE_KEYS.authToken); if (token) { setAuthHeader(token); const response = await retrieveUserApi(); if (response.success && response.data) { setUser(response.data); } else { await logout(); Toast.show({ type: 'error', text1: 'Sesi Anda sudah berakhir.', text2: 'Silakan coba masuk lagi.', }); } } setIsFirstLoading(false); }, [logout]); const authSuccess = async (data: LoginResponse) => { const accessToken = data.access_token; await setCache(CACHE_KEYS.authToken, accessToken); await setCache(CACHE_KEYS.refreshToken, data.refresh_token); setAuthHeader(accessToken); setUser(data.user); }; const linkUserData = async (email: string) => { const dietProfileId = await getCache(CACHE_KEYS.dietProfileId); const cartId = await getCache(CACHE_KEYS.cartId); if (dietProfileId && cartId) { const response = await linkUserDataApi({ email, diet_profile_id: parseInt(dietProfileId, 10), cart_id: parseInt(cartId, 10), }); return response; } return { success: false, }; }; const signup = async (registerData: RegistrationRequest) => { const response = await signupApi(registerData); if (response.success && response.data) { await linkUserData(response.data.user.email); await authSuccess(response.data); } return response; }; const login = async (loginData: LoginRequest) => { const response = await loginApi(loginData); if (response.success && response.data) { await authSuccess(response.data); } return response; }; const loginWithGoogle = async (isLogin: boolean = true) => { try { await GoogleSignin.hasPlayServices(); await GoogleSignin.signIn(); const tokens = await GoogleSignin.getTokens(); const response = await googleLoginApi({ access_token: tokens.accessToken, }); if (response.success && response.data) { // If signup, link user to cart and diet profile if (!isLogin) { const linkResponse = await linkUserData(response.data.user.email); if (!linkResponse.success) { await logout(); Toast.show({ type: 'error', text1: 'Gagal registrasi dengan Google', text2: 'Terjadi kesalahan di sisi kami. Silakan coba lagi', }); } } await authSuccess(response.data); } else { await logout(); } } catch (error) { console.log(error); } setIsLoading(false); }; return { user, isAuthenticated: user.id !== null, isLoading, isFirstLoading, setUser, getUser, signup, login, loginWithGoogle, logout, }; };