58 lines
1.9 KiB
TypeScript
58 lines
1.9 KiB
TypeScript
import React, { createContext, useContext, useEffect, useState } from "react";
|
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
|
import { authApi, LoginPayload, RegisterPayload, JwtResponse } from "../services/api";
|
|
|
|
type User = { email: string; token: string };
|
|
|
|
type AuthContextValue = {
|
|
user: User | null;
|
|
loading: boolean;
|
|
login: (p: LoginPayload) => Promise<void>;
|
|
register: (p: RegisterPayload) => Promise<void>;
|
|
logout: () => Promise<void>;
|
|
};
|
|
|
|
const AuthContext = createContext<AuthContextValue | null>(null);
|
|
|
|
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
const [user, setUser] = useState<User | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
// Restore session on mount
|
|
useEffect(() => {
|
|
AsyncStorage.getItem("auth_user")
|
|
.then((raw) => { if (raw) setUser(JSON.parse(raw)); })
|
|
.finally(() => setLoading(false));
|
|
}, []);
|
|
|
|
const persist = async (u: User | null) => {
|
|
if (u) await AsyncStorage.setItem("auth_user", JSON.stringify(u));
|
|
else await AsyncStorage.removeItem("auth_user");
|
|
setUser(u);
|
|
};
|
|
|
|
const login = async (payload: LoginPayload) => {
|
|
const res = await authApi.login(payload);
|
|
await persist({ email: res.email, token: res.token });
|
|
};
|
|
|
|
const register = async (payload: RegisterPayload) => {
|
|
await authApi.register(payload);
|
|
// Auto-login after register
|
|
await login({ email: payload.email, password: payload.password });
|
|
};
|
|
|
|
const logout = () => persist(null);
|
|
|
|
return (
|
|
<AuthContext.Provider value={{ user, loading, login, register, logout }}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useAuth() {
|
|
const ctx = useContext(AuthContext);
|
|
if (!ctx) throw new Error("useAuth must be used inside AuthProvider");
|
|
return ctx;
|
|
} |