Archived
Reviewed and merged by Reid (Hermes Reviewer) Co-authored-by: crisleo-hermes <hermes@codescripters.org> Co-committed-by: crisleo-hermes <hermes@codescripters.org>
63 lines
2.1 KiB
TypeScript
63 lines
2.1 KiB
TypeScript
import React, { createContext, useCallback, useContext, useEffect, useState } from "react";
|
|
import api from "../api/client";
|
|
|
|
interface AuthContextValue {
|
|
isAuthenticated: boolean;
|
|
loading: boolean;
|
|
user: { email: string } | null;
|
|
login: (email: string, password: string) => Promise<void>;
|
|
register: (email: string, password: string) => Promise<void>;
|
|
logout: () => void;
|
|
}
|
|
|
|
const AuthContext = createContext<AuthContextValue | null>(null);
|
|
|
|
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
const [user, setUser] = useState<{ email: string } | null>(null);
|
|
const [loading, setLoading] = useState(true);
|
|
|
|
useEffect(() => {
|
|
const token = localStorage.getItem("access_token");
|
|
if (token) {
|
|
try {
|
|
const payload = JSON.parse(atob(token.split(".")[1] ?? ""));
|
|
setUser({ email: payload.email ?? payload.sub ?? "user" });
|
|
} catch {
|
|
localStorage.removeItem("access_token");
|
|
localStorage.removeItem("refresh_token");
|
|
}
|
|
}
|
|
setLoading(false);
|
|
}, []);
|
|
|
|
const login = useCallback(async (email: string, password: string) => {
|
|
const { data } = await api.post<{ access: string; refresh: string }>("/auth/token/", { email, password });
|
|
localStorage.setItem("access_token", data.access);
|
|
localStorage.setItem("refresh_token", data.refresh);
|
|
const payload = JSON.parse(atob(data.access.split(".")[1] ?? ""));
|
|
setUser({ email: payload.email ?? payload.sub ?? "user" });
|
|
}, []);
|
|
|
|
const register = useCallback(async (email: string, password: string) => {
|
|
await api.post("/auth/register/", { email, password });
|
|
await login(email, password);
|
|
}, [login]);
|
|
|
|
const logout = useCallback(() => {
|
|
localStorage.removeItem("access_token");
|
|
localStorage.removeItem("refresh_token");
|
|
setUser(null);
|
|
}, []);
|
|
|
|
return (
|
|
<AuthContext.Provider value={{ isAuthenticated: !!user, loading, user, login, register, logout }}>
|
|
{children}
|
|
</AuthContext.Provider>
|
|
);
|
|
}
|
|
|
|
export function useAuth(): AuthContextValue {
|
|
const ctx = useContext(AuthContext);
|
|
if (!ctx) throw new Error("useAuth must be used within an AuthProvider");
|
|
return ctx;
|
|
} |