import React, { ReactNode, createContext, useEffect, useState } from 'react'; import { useContext } from 'react'; import { router, useSegments } from 'expo-router'; import AsyncStorage from '@react-native-async-storage/async-storage'; import axios from 'axios'; import { Alert } from 'react-native'; import * as SecureStore from 'expo-secure-store'; type User = { id: string; username: string; }; type AuthProvider = { user: User | null; login: (username: string, password: string) => Promise; logout: () => void; }; function useProtectedRoute(user: User | null) { const segments = useSegments(); useEffect(() => { const inAuthGroup = segments[0] === '(auth)'; if (!user && inAuthGroup) { router.replace('/login'); } else if (user && !inAuthGroup) { router.replace('/(auth)/(tabs)/'); } }, [user, segments]); } export const AuthContext = createContext({ user: null, login: async () => false, logout: () => {} }); 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(() => { // Load user from AsyncStorage if token exists const loadUser = async () => { const token = await SecureStore.getItemAsync('accessToken'); const username = await AsyncStorage.getItem('username'); if (token) { // Fetch user details from API by decoding the token // For now, I am just setting a dummy user setUser({ id: '1', username: username || '' }); } }; loadUser(); }, [user]); const login = async (username: string, password: string) => { try { const apiUrl = process.env.EXPO_PUBLIC_API_URL; if (!apiUrl) { throw new Error( 'API URL is not defined in environment variables' ); } const response = await axios.post( `${apiUrl}/clients/customer/sign-in`, // 'http://192.168.1.33:12000/api/v1/clients/customer/sign-in', { email: username, password: password }, { headers: { 'Content-Type': 'application/json', Accept: 'application/json' } } ); if (response.status === 201) { const token = response.data.accessToken; await SecureStore.setItemAsync('accessToken', token); await AsyncStorage.setItem('username', username); //-- use jwt_decode to decode the accesstoken, //-- set the user according to decoded information setUser({ id: '9999', username: username }); console.log('Login successful!'); return true; } else { console.error('Login failed:', response.status); Alert.alert('Error', 'Invalid username or password'); return false; } } catch (error) { console.error('Login error:', error); Alert.alert( 'Error', 'Something went wrong. Please try again later.' ); return false; } }; const logout = async () => { await SecureStore.deleteItemAsync('accessToken'); setUser(null); router.replace('/login'); }; useProtectedRoute(user); return ( {children} ); }