feat: implement login auth for all

also show the username underneath the logo
This commit is contained in:
2025-03-06 13:29:10 +01:00
parent 99e80c8077
commit 8b092fed51
9 changed files with 252 additions and 108 deletions

View File

@@ -1,36 +1,94 @@
import { createContext, ReactNode, useContext, useLayoutEffect, useState } from "react";
import { currentUser, User } from "./api";
import {
createContext,
ReactNode,
useContext,
useEffect,
useState,
} from "react";
import { currentUser, logout, User } from "./api";
import { Login } from "./Login";
import Header from "./Header";
export interface SessionProviderProps {
children: ReactNode;
}
const sessionContext = createContext<User | null>(null);
export interface Session {
user: User | null;
onLogout: () => void;
}
const sessionContext = createContext<Session>({
user: null,
onLogout: () => {},
});
export function SessionProvider(props: SessionProviderProps) {
const { children } = props;
const [user, setUser] = useState<User | 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); });
.then((user) => {
setUser(user);
setErr(null);
})
.catch((err) => {
setUser(null);
setErr(err);
})
.finally(() => setLoading(false));
}
useLayoutEffect(() => { loadUser(); }, [err]);
useEffect(() => {
loadUser();
}, []);
function onLogin(user: User) {
setUser(user);
setErr(null);
}
async function onLogout() {
try {
logout();
setUser(null);
setErr({ message: "Logged out successfully" });
console.log("logged out.");
setLoading(true); // Set loading to true
loadUser();
} catch (e) {
console.error(e);
setErr(e); // Update the error state if logout fails
}
}
console.log("sanity", user);
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>;
if (loading || (!err && !user))
content = (
<>
<Header />
<span className="loader" />
</>
);
else if (err) {
if ((err as any).message === "Logged out successfully") {
setTimeout(() => setErr(null), 1000);
content = <Login onLogin={onLogin} />;
} else {
content = <Login onLogin={onLogin} />;
}
} else
content = (
<sessionContext.Provider value={{ user, onLogout }}>
{children}
</sessionContext.Provider>
);
return content;
}