41 lines
1.1 KiB
TypeScript
41 lines
1.1 KiB
TypeScript
import { createContext, ReactNode, useContext, useLayoutEffect, useState } from "react";
|
|
import { currentUser, User } from "./api";
|
|
import { Login } from "./Login";
|
|
|
|
export interface SessionProviderProps {
|
|
children: ReactNode;
|
|
}
|
|
|
|
const sessionContext = createContext<User | null>(null);
|
|
|
|
export function SessionProvider(props: SessionProviderProps) {
|
|
const { children } = props;
|
|
|
|
const [user, setUser] = useState<User | null>(null);
|
|
const [err, setErr] = useState<unknown>(null);
|
|
|
|
function loadUser() {
|
|
currentUser()
|
|
.then((user) => { setUser(user); setErr(null); })
|
|
.catch((err) => { setUser(null); setErr(err); });
|
|
}
|
|
|
|
useLayoutEffect(() => { loadUser(); }, [err]);
|
|
|
|
function onLogin(user: User) {
|
|
setUser(user);
|
|
setErr(null);
|
|
}
|
|
|
|
let content: ReactNode;
|
|
if (!err && !user) content = <span className="loader" />;
|
|
else if (err) content = <Login onLogin={onLogin} />;
|
|
else content = <sessionContext.Provider value={user}>{children}</sessionContext.Provider>;
|
|
|
|
return content;
|
|
}
|
|
|
|
export function useSession() {
|
|
return useContext(sessionContext);
|
|
}
|