import { ReactNode, createContext, useEffect, useState } from 'react'; import { useContext } from 'react'; import { router, useSegments } from 'expo-router'; import * as SecureStore from 'expo-secure-store'; import axios from 'axios'; import { EXPO_PUBLIC_API_URL } from '@env'; import { User } from '../types/user'; import { authenticationService } from '../service/authService'; type AuthProvider = { user: User | null; login: (username: string, password: string, isBinding: boolean) => Promise; logout: () => void; setUser: React.Dispatch>; }; function useProtectedRoute(user: User | null) { const segments = useSegments(); const isUserEmpty = (user: User | null): boolean => { return !user || Object.values(user).every((value) => value === undefined); }; useEffect(() => { if (!segments.length) return; // console.log('Current segment:', segments[0]); // console.log('Is user empty?', isUserEmpty(user)); const inAuthGroup = segments[0] === '(auth)'; const inPublicGroup = segments[0] === '(public)'; // console.log('In auth group?', inAuthGroup); if (isUserEmpty(user) && !inPublicGroup) { router.replace('/login'); } else if (!isUserEmpty(user) && inPublicGroup) { router.replace('/(auth)/(tabs)/(home)/mainPage'); } }, [user, segments]); } export const AuthContext = createContext({ user: null, login: async () => false, logout: () => {}, setUser: () => {} }); export function useAuth() { const context = useContext(AuthContext); if (!context) { throw new Error('useAuth must be used within a '); } return context; } export default function AuthProvider({ children }: { children: ReactNode }) { const [user, setUser] = useState(null); useEffect(() => { const checkToken = async () => { const token = await SecureStore.getItemAsync('accessToken'); if (token) { const userInfo = await getUserFromAccessToken(); if (userInfo) { setUser(userInfo); } } }; checkToken(); }, []); const login = async (username: string, password: string, isBinding: boolean) => { try { const loggedInUser = await authenticationService.phoneLogin(username, password, isBinding); if (loggedInUser) { const token = await SecureStore.getItemAsync('accessToken'); if (token) { const userInfo = await getUserFromAccessToken(); if (userInfo) { setUser(userInfo); } } return true; } else { return false; } } catch (error) { console.error('Login error:', error); return false; } }; //this is urgent login, only for testing & debugging // const login = async (username: string, password: string, isBinding: boolean) => { // try { // const loggedInUser = { // accessToken: // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiY3VzdG9tZXIiLCJjcmVhdGVkQXQiOiIyMDI0LTA5LTAzVDA2OjM4OjU3LjI5NloiLCJ1cGRhdGVkQXQiOiIyMDI0LTEyLTAyVDE3OjUwOjQyLjI1MloiLCJpZCI6IjA2ZTRkNjU0LTliNDEtNDExMy1hZjBmLTE5OTIzYjc0YzEwZSIsImZpcnN0bmFtZSI6bnVsbCwibGFzdG5hbWUiOm51bGwsIm5pY2tuYW1lIjoiVGVzdCAyIiwiZW1haWwiOiJ0ZXN0MkBnbWFpbC5jb20iLCJwaG9uZSI6NjgxMDAxMTYsImljX2NhcmQiOiIwMDAwMDAwMDAwMDAxNDk2Iiwid2FsbGV0Ijo5NzYwLCJpY29uX3VybCI6bnVsbCwicmVtYXJrIjpudWxsLCJhZGRyZXNzIjpudWxsLCJzdGF0dXNfZmsiOiIxIiwiZ2VuZGVyIjoibWFuIiwiYmlydGhkYXkiOiIwNC8wNi8xMSIsImljX2Nhcl9pZCI6bnVsbCwiaWF0IjoxNzMzMTkyNjgzLCJleHAiOjE3MzMxOTk4ODN9.1VvQacR5SJ1JiRlnmy_m5rcrKN8wXsPTZ9_QLas8CEQ', // refreshToken: // 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJyb2xlIjoiY3VzdG9tZXIiLCJjcmVhdGVkQXQiOiIyMDI0LTA5LTAzVDA2OjM4OjU3LjI5NloiLCJ1cGRhdGVkQXQiOiIyMDI0LTEyLTAyVDE3OjUwOjQyLjI1MloiLCJpZCI6IjA2ZTRkNjU0LTliNDEtNDExMy1hZjBmLTE5OTIzYjc0YzEwZSIsImZpcnN0bmFtZSI6bnVsbCwibGFzdG5hbWUiOm51bGwsIm5pY2tuYW1lIjoiVGVzdCAyIiwiZW1haWwiOiJ0ZXN0MkBnbWFpbC5jb20iLCJwaG9uZSI6NjgxMDAxMTYsImljX2NhcmQiOiIwMDAwMDAwMDAwMDAxNDk2Iiwid2FsbGV0Ijo5NzYwLCJpY29uX3VybCI6bnVsbCwicmVtYXJrIjpudWxsLCJhZGRyZXNzIjpudWxsLCJzdGF0dXNfZmsiOiIxIiwiZ2VuZGVyIjoibWFuIiwiYmlydGhkYXkiOiIwNC8wNi8xMSIsImljX2Nhcl9pZCI6bnVsbCwiaWF0IjoxNzMzMTkyMjY5LCJleHAiOjE3MzY2NDgyNjl9.OrZqQyLkHL0eojesrn3xqoxIYatanjCX-GyXTcmNoys' // }; // if (loggedInUser) { // //this is only for urgent login, uncomment getItemAsync after // await SecureStore.setItemAsync('accessToken', loggedInUser.accessToken); // const token = await SecureStore.getItemAsync('accessToken'); // if (token) { // const userInfo = await getUserFromAccessToken(); // if (userInfo) { // console.log('userInfouserInfouserInfouserInfouserInfouserInfo', userInfo); // setUser(userInfo); // } // } // return true; // } else { // return false; // } // } catch (error) { // console.error('Login error:', error); // return false; // } // }; const getUserFromAccessToken = async () => { const token = await SecureStore.getItemAsync('accessToken'); try { const res = await axios.get(`${EXPO_PUBLIC_API_URL}/clients/customer`, { headers: { Authorization: `Bearer ${token}` } }); const items = { address: res.data.address, birthday: res.data.birthday, gender: res.data.gender, email: res.data.email, nickname: res.data.nickname, phone: res.data.phone }; return items; } catch (error) { console.error('GetUser Error:', error); } }; const logout = async () => { try { await authenticationService.logout(); await SecureStore.deleteItemAsync('accessToken'); setUser(null); router.replace('/login'); } catch (error) { console.log('error during logout', error); } }; // console.log('user', user); useProtectedRoute(user); return {children}; }