import { apiConfig, apiLogin, apiRegister, apiValidationCode, } from "@/service/api-config"; import { IUser } from "@/types/User"; import AsyncStorage from "@react-native-async-storage/async-storage"; import { router } from "expo-router"; import { createContext, useEffect, useState } from "react"; import Toast from "react-native-toast-message"; // --- Types --- type AuthContextType = { user: IUser | null; token: string | null; isLoading: boolean; isAuthenticated: boolean; isAdmin: boolean; isUserActive: boolean; loginWithNomor: (nomor: string) => Promise; validateOtp: (nomor: string) => Promise; logout: () => Promise; registerUser: (userData: { username: string; nomor: string; }) => Promise; userData: (token: string) => Promise; }; // --- Create Context --- export const AuthContext = createContext( undefined ); export const AuthProvider = ({ children }: { children: React.ReactNode }) => { const [user, setUser] = useState(null); const [token, setToken] = useState(null); const [isLoading, setIsLoading] = useState(true); const isAuthenticated = !!user; const isAdmin = user?.masterUserRoleId !== "1"; const isUserActive = user?.active === true; // --- Load session from AsyncStorage on app start --- useEffect(() => { const loadSession = async () => { try { const storedToken = await AsyncStorage.getItem("authToken"); const storedUser = await AsyncStorage.getItem("userData"); if (storedToken) { setToken(storedToken); } if (storedToken && storedUser) { setToken(storedToken); setUser(JSON.parse(storedUser)); } } catch (error) { console.error("Failed to load session", error); } finally { setIsLoading(false); } }; loadSession(); }, []); // --- 1. Kirim nomor → dapat OTP --- const loginWithNomor = async (nomor: string) => { setIsLoading(true); try { const response = await apiLogin({ nomor: nomor }); await AsyncStorage.setItem("kode_otp", response.kodeId); } catch (error: any) { throw new Error(error.response?.data?.message || "Gagal kirim OTP"); } finally { setIsLoading(false); } }; // --- 2. Validasi OTP & cek user --- const validateOtp = async (nomor: string) => { try { setIsLoading(true); const response = await apiValidationCode({ nomor: nomor }); const { token } = response; if (response.success) { setToken(token); await AsyncStorage.setItem("authToken", token); const responseUser = await apiConfig.get( `/mobile/user?token=${token}`, { headers: { Authorization: `Bearer ${token}`, }, } ); const dataUser = responseUser.data.data; setUser(dataUser); await AsyncStorage.setItem("userData", JSON.stringify(dataUser)); if (response.active) { if (response.roleId === "1") { return "/(application)/(user)/home"; } else { return "/(application)/admin/dashboard"; } } else { return "/(application)/(user)/waiting-room"; } } else { Toast.show({ type: "info", text1: "Anda belum terdaftar", text2: "Silahkan daftar terlebih dahulu", }); return `/register?nomor=${nomor}`; } } catch (error: any) { console.log("Error validasi otp >>", (error as Error).message || error); throw new Error( error.response?.data?.message || "OTP salah atau user tidak ditemukan" ); } finally { setIsLoading(false); } }; // --- 3. Ambil data user --- const userData = async (token: string) => { try { setIsLoading(true); const response = await apiConfig.get(`/mobile/user?token=${token}`, { headers: { Authorization: `Bearer ${token}`, }, }); const dataUser = response.data.data; setUser(dataUser); await AsyncStorage.setItem("userData", JSON.stringify(dataUser)); return dataUser; } catch (error: any) { throw new Error( error.response?.data?.message || "Gagal mengambil data user" ); } finally { setIsLoading(false); } }; // --- 4. Register jika user belum ada --- const registerUser = async (userData: { username: string; nomor: string; }) => { setIsLoading(true); try { const response = await apiRegister({ data: userData }); const { token } = response; if (!response.success) { Toast.show({ type: "info", text1: "Info", text2: response.message, }); return; } setToken(token); await AsyncStorage.setItem("authToken", token); Toast.show({ type: "success", text1: "Sukses", text2: "Anda berhasil terdaftar", }); router.replace("/(application)/(user)/waiting-room"); return; } catch (error: any) { console.log("Error register", error); } finally { setIsLoading(false); } }; // --- 5. Logout --- const logout = async () => { try { setIsLoading(true); setToken(null); setUser(null); await AsyncStorage.removeItem("authToken"); await AsyncStorage.removeItem("userData"); setIsLoading(false); Toast.show({ type: "success", text1: "Logout berhasil", text2: "Anda berhasil keluar dari akun.", }); router.replace("/"); } catch (error) { console.log("Logout error (optional):", error); } finally { setIsLoading(false); } }; return ( <> {children} ); };