feat: implement auth, projects, and frontend foundation
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
||||
|
||||
import { apiClient } from "../api/client";
|
||||
import type { SessionPayload, SessionUser } from "../types";
|
||||
|
||||
type AuthState = "loading" | "authenticated" | "unauthenticated";
|
||||
|
||||
type AuthContextValue = {
|
||||
state: AuthState;
|
||||
user: SessionUser | null;
|
||||
refreshSession: () => Promise<void>;
|
||||
logout: () => Promise<void>;
|
||||
};
|
||||
|
||||
const AuthContext = createContext<AuthContextValue | undefined>(undefined);
|
||||
|
||||
export const AuthProvider = ({ children }: { children: React.ReactNode }) => {
|
||||
const [state, setState] = useState<AuthState>("loading");
|
||||
const [user, setUser] = useState<SessionUser | null>(null);
|
||||
|
||||
const refreshSession = useCallback(async () => {
|
||||
setState("loading");
|
||||
try {
|
||||
const response = await apiClient.get<SessionPayload>("/auth/me");
|
||||
setUser(response.data.user);
|
||||
setState("authenticated");
|
||||
} catch {
|
||||
setUser(null);
|
||||
setState("unauthenticated");
|
||||
}
|
||||
}, []);
|
||||
|
||||
const logout = useCallback(async () => {
|
||||
await apiClient.post("/auth/logout");
|
||||
setUser(null);
|
||||
setState("unauthenticated");
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
void refreshSession();
|
||||
}, [refreshSession]);
|
||||
|
||||
const value = useMemo(
|
||||
() => ({
|
||||
state,
|
||||
user,
|
||||
refreshSession,
|
||||
logout
|
||||
}),
|
||||
[refreshSession, state, user, logout]
|
||||
);
|
||||
|
||||
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
|
||||
};
|
||||
|
||||
export const useAuth = (): AuthContextValue => {
|
||||
const context = useContext(AuthContext);
|
||||
if (!context) {
|
||||
throw new Error("useAuth must be used within AuthProvider");
|
||||
}
|
||||
|
||||
return context;
|
||||
};
|
||||
Reference in New Issue
Block a user