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) => 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) => { try { const loggedInUser = await authenticationService.login(username, password); 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; } }; 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}; }