feat: assemble responsive app shell navigation
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
import { createContext, useContext, useMemo, useSyncExternalStore } from "react";
|
||||
|
||||
/**
|
||||
* @typedef {{
|
||||
* sessionState: import("../../application/ports/auth-session-port.js").SessionState,
|
||||
* beginSignIn: import("../../application/ports/auth-session-port.js").AuthSessionPort["beginSignIn"],
|
||||
* signOut: import("../../application/ports/auth-session-port.js").AuthSessionPort["signOut"],
|
||||
* recover: import("../../application/ports/auth-session-port.js").AuthSessionPort["recover"]
|
||||
* }} SessionContextValue
|
||||
*/
|
||||
|
||||
const SessionContext = createContext(
|
||||
/** @type {SessionContextValue | null} */ (null),
|
||||
);
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* authSession: import("../../application/ports/auth-session-port.js").AuthSessionPort,
|
||||
* children: React.ReactNode
|
||||
* }} props
|
||||
*/
|
||||
export function SessionProvider({ authSession, children }) {
|
||||
const sessionState = useSyncExternalStore(
|
||||
authSession.subscribe,
|
||||
authSession.getState,
|
||||
authSession.getState,
|
||||
);
|
||||
const value = useMemo(
|
||||
() =>
|
||||
Object.freeze({
|
||||
sessionState,
|
||||
beginSignIn: authSession.beginSignIn,
|
||||
signOut: authSession.signOut,
|
||||
recover: authSession.recover,
|
||||
}),
|
||||
[authSession, sessionState],
|
||||
);
|
||||
|
||||
return (
|
||||
<SessionContext.Provider value={value}>{children}</SessionContext.Provider>
|
||||
);
|
||||
}
|
||||
|
||||
export function useSession() {
|
||||
const session = useContext(SessionContext);
|
||||
if (!session) {
|
||||
throw new Error("SessionProvider is required");
|
||||
}
|
||||
return session;
|
||||
}
|
||||
Reference in New Issue
Block a user