import { createContext, useCallback, useEffect, useState } from 'react'; import { GoogleSignin } from '@react-native-google-signin/google-signin'; import { Toast } from 'components/core'; import CACHE_KEYS from 'constants/cacheKeys'; import { removeCache, getCache, setCache } from 'utils/cache'; import { googleLoginApi, loginApi, signupApi, retrieveUserApi, linkUserDataApi, } from 'services/auth'; import { User, RegistrationRequest, LoginRequest, LoginResponse, UserRole, } from 'services/auth/models'; import { set401Callback, setAuthHeader, resetAuthHeader } from 'services/api'; import { iUserContext } from './types'; import { TransactionStatus } from 'services/payment/models'; const initialUser = { id: null, email: '', name: '', role: null, }; export const UserContext = createContext({ user: initialUser, isAuthenticated: false, isUnpaidClient: false, isPaidClient: false, isNutritionist: false, isAdmin: false, isLoading: false, isFirstLoading: false, 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 [transactionStatus, setTransactionStatus] = useState( TransactionStatus.UNPAID, ); const logout = useCallback(async () => { await GoogleSignin.signOut(); await removeCache(CACHE_KEYS.authToken); await removeCache(CACHE_KEYS.refreshToken); setUser(initialUser); resetAuthHeader(); }, []); 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) { const { cart, ...userData } = response.data; setUser(userData); setTransactionStatus(cart.transaction_status); } 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); setUser(data.user); setAuthHeader(accessToken); }; 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 authSuccess(response.data); return await linkUserData(response.data.user.email); } 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) { await authSuccess(response.data); 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', }); } } } else { await logout(); } } catch (error) { console.log(error); } setIsLoading(false); }; useEffect(() => { // TODO: save to .env GoogleSignin.configure({ webClientId: '813112248680-ulv0amtocut652j31qbpvubtclbd2c7o.apps.googleusercontent.com', }); getUser(); set401Callback(logout); }, [getUser, logout]); return { user, isAuthenticated: user.id !== null, isUnpaidClient: user.role === UserRole.CLIENT && transactionStatus === TransactionStatus.UNPAID, isPaidClient: user.role === UserRole.CLIENT, isNutritionist: user.role === UserRole.NUTRITIONIST, isAdmin: user.role === UserRole.ADMIN, isLoading, isFirstLoading, signup, login, loginWithGoogle, logout, }; };