cutt/src/Session.tsx
2025-03-26 17:37:02 +01:00

110 lines
2.2 KiB
TypeScript

import {
createContext,
ReactNode,
useContext,
useEffect,
useState,
} from "react";
import { apiAuth, currentUser, logout, User } from "./api";
import { Login } from "./Login";
import Header from "./Header";
import { Team } from "./types";
export interface SessionProviderProps {
children: ReactNode;
}
export interface TeamState {
teams: Team[];
activeTeam: number;
}
export interface Session {
user: User | null;
teams: TeamState | null;
setTeams: (teams: TeamState) => void;
onLogout: () => void;
}
const sessionContext = createContext<Session>({
user: null,
teams: null,
setTeams: () => {},
onLogout: () => {},
});
export function SessionProvider(props: SessionProviderProps) {
const { children } = props;
const [user, setUser] = useState<User | null>(null);
const [teams, setTeams] = useState<TeamState | null>(null);
const [err, setErr] = useState<unknown>(null);
const [loading, setLoading] = useState(false);
function loadUser() {
setLoading(true);
currentUser()
.then((user) => {
setUser(user);
setErr(null);
})
.catch((err) => {
setUser(null);
setErr(err);
})
.finally(() => setLoading(false));
}
async function loadTeam() {
const teams: Team[] = await apiAuth("player/me/teams", null, "GET");
if (teams) setTeams({ teams: teams, activeTeam: teams[0].id });
}
useEffect(() => {
loadUser();
}, []);
useEffect(() => {
loadTeam();
}, [user]);
function onLogin(user: User) {
setUser(user);
setErr(null);
}
async function onLogout() {
try {
logout();
setUser(null);
setErr({ message: "Logged out successfully" });
console.log("logged out.");
} catch (e) {
console.error(e);
setErr(e);
}
}
let content: ReactNode;
if (loading || (!err && !user))
content = (
<>
<Header />
<span className="loader" />
</>
);
else if (err) {
content = <Login onLogin={onLogin} />;
} else
content = (
<sessionContext.Provider value={{ user, teams, setTeams, onLogout }}>
{children}
</sessionContext.Provider>
);
return content;
}
export function useSession() {
return useContext(sessionContext);
}