Some checks failed
Deploy to Production / test (push) Failing after 37s
Adds a React admin panel (panel/) with Discord OAuth2 login, live dashboard via WebSocket, and settings/management pages. Includes Docker build support, Vite proxy config for dev, game_settings migration, and open-redirect protection on auth callback. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
36 lines
931 B
TypeScript
36 lines
931 B
TypeScript
import { useState, useEffect } from "react";
|
|
|
|
export interface AuthUser {
|
|
discordId: string;
|
|
username: string;
|
|
avatar: string | null;
|
|
}
|
|
|
|
interface AuthState {
|
|
loading: boolean;
|
|
user: AuthUser | null;
|
|
}
|
|
|
|
export function useAuth(): AuthState & { logout: () => Promise<void> } {
|
|
const [state, setState] = useState<AuthState>({ loading: true, user: null });
|
|
|
|
useEffect(() => {
|
|
fetch("/auth/me", { credentials: "same-origin" })
|
|
.then((r) => r.json())
|
|
.then((data: { authenticated: boolean; user?: AuthUser }) => {
|
|
setState({
|
|
loading: false,
|
|
user: data.authenticated ? data.user! : null,
|
|
});
|
|
})
|
|
.catch(() => setState({ loading: false, user: null }));
|
|
}, []);
|
|
|
|
const logout = async () => {
|
|
await fetch("/auth/logout", { method: "POST", credentials: "same-origin" });
|
|
setState({ loading: false, user: null });
|
|
};
|
|
|
|
return { ...state, logout };
|
|
}
|