Files
gitlab-instance-0a899031_do…/components/auth-provider.tsx
2026-04-02 07:15:42 -05:00

67 lines
1.8 KiB
TypeScript

"use client";
import { createContext, PropsWithChildren, useContext, useMemo, useState } from "react";
import { AccessLevel, SessionState } from "@/lib/types";
interface AuthContextValue {
session: SessionState;
loginAs: (name?: string) => void;
logout: () => void;
setAccessLevel: (level: AccessLevel) => void;
}
const STORAGE_KEY = "download_nova_session";
const defaultSession: SessionState = {
isLoggedIn: false,
accessLevel: "guest",
};
const AuthContext = createContext<AuthContextValue | null>(null);
function readSession(): SessionState {
if (typeof window === "undefined") return defaultSession;
const raw = localStorage.getItem(STORAGE_KEY);
if (!raw) return defaultSession;
try {
return { ...defaultSession, ...JSON.parse(raw) } as SessionState;
} catch {
return defaultSession;
}
}
export function AuthProvider({ children }: PropsWithChildren) {
const [session, setSession] = useState<SessionState>(() => readSession());
const persist = (next: SessionState) => {
setSession(next);
if (typeof window !== "undefined") {
localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
}
};
const value = useMemo<AuthContextValue>(
() => ({
session,
loginAs: (name = "Nova 用户") =>
persist({
...session,
isLoggedIn: true,
userName: name,
accessLevel: session.accessLevel === "guest" ? "unlocked" : session.accessLevel,
}),
logout: () => persist(defaultSession),
setAccessLevel: (level) => persist({ ...session, isLoggedIn: true, accessLevel: level }),
}),
[session],
);
return <AuthContext.Provider value={value}>{children}</AuthContext.Provider>;
}
export function useAuth() {
const ctx = useContext(AuthContext);
if (!ctx) throw new Error("useAuth must be used within AuthProvider");
return ctx;
}