91 lines
2.4 KiB
TypeScript
91 lines
2.4 KiB
TypeScript
"use client";
|
|
|
|
import {
|
|
createContext,
|
|
useContext,
|
|
useState,
|
|
useEffect,
|
|
useCallback,
|
|
type ReactNode,
|
|
} from "react";
|
|
import { type AuthUser } from "@/lib/types";
|
|
import { postAPI, fetchAPI } from "@/lib/api";
|
|
import type { LoginResponse } from "@/lib/types";
|
|
|
|
interface AuthContextValue {
|
|
user: AuthUser | null;
|
|
loading: boolean;
|
|
login: (email: string, password: string) => Promise<void>;
|
|
logout: () => void;
|
|
refreshUser: () => Promise<void>;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextValue>({
|
|
user: null,
|
|
loading: true,
|
|
login: async () => {},
|
|
logout: () => {},
|
|
refreshUser: async () => {},
|
|
});
|
|
|
|
export function AuthProvider({ children }: { children: ReactNode }) {
|
|
const [user, setUser] = useState<AuthUser | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const token = localStorage.getItem("auth_token");
|
|
const storedUser = localStorage.getItem("auth_user");
|
|
if (token && storedUser) {
|
|
try {
|
|
setUser(JSON.parse(storedUser));
|
|
} catch {
|
|
localStorage.removeItem("auth_token");
|
|
localStorage.removeItem("auth_user");
|
|
}
|
|
}
|
|
setLoading(false);
|
|
}, []);
|
|
|
|
const login = useCallback(async (email: string, password: string) => {
|
|
const res = await postAPI<LoginResponse>("/api/auth/login", {
|
|
email,
|
|
password,
|
|
});
|
|
localStorage.setItem("auth_token", res.token);
|
|
// Temporarily set user from login response, then refresh to get full data (enabled_modules etc.)
|
|
setUser(res.user);
|
|
localStorage.setItem("auth_user", JSON.stringify(res.user));
|
|
// Refresh to get complete user data including enabled_modules
|
|
const userData = await fetchAPI<AuthUser>("/api/auth/me");
|
|
localStorage.setItem("auth_user", JSON.stringify(userData));
|
|
setUser(userData);
|
|
}, []);
|
|
|
|
const logout = useCallback(() => {
|
|
localStorage.removeItem("auth_token");
|
|
localStorage.removeItem("auth_user");
|
|
setUser(null);
|
|
window.location.href = "/login";
|
|
}, []);
|
|
|
|
const refreshUser = useCallback(async () => {
|
|
try {
|
|
const userData = await fetchAPI<AuthUser>("/api/auth/me");
|
|
localStorage.setItem("auth_user", JSON.stringify(userData));
|
|
setUser(userData);
|
|
} catch {
|
|
// Token might be invalid
|
|
}
|
|
}, []);
|
|
|
|
return (
|
|
<AuthContext.Provider value={{ user, loading, login, logout, refreshUser }}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useAuth() {
|
|
return useContext(AuthContext);
|
|
}
|