Files
gitlab-instance-0a899031_di…/app/lib/useAuthAndVip.ts
2026-03-12 05:40:18 -05:00

68 lines
2.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client";
import { useState, useEffect, useCallback } from "react";
import { getStoredUser, getStoredToken } from "@/app/lib/pocketbase";
export interface AuthAndVipState {
user: { id: string; email: string } | null;
vip: boolean;
loading: boolean;
refetch: () => Promise<{ user: { id: string; email: string } | null; vip: boolean }>;
}
export function useAuthAndVip(): AuthAndVipState {
const [user, setUser] = useState<{ id: string; email: string } | null>(null);
const [vip, setVip] = useState(false);
const [loading, setLoading] = useState(true);
const refetch = useCallback(async (): Promise<{ user: { id: string; email: string } | null; vip: boolean }> => {
setLoading(true);
try {
const [meRes, vipRes] = await Promise.all([
fetch("/api/auth/me", { credentials: "include" }),
fetch("/api/vip/check", { credentials: "include" }),
]);
const meData = await meRes.json();
const vipData = await vipRes.json();
let newUser = meData?.user ?? null;
let newVip = vipData?.vip === true;
// 与 Header 一致API 无用户时,尝试从 localStorage 恢复(如 cookie 未同步、localhost 开发等)
if (!newUser) {
const storedUser = getStoredUser();
const storedToken = getStoredToken();
if (storedUser && storedToken) {
newUser = storedUser;
try {
await fetch("/api/auth/sync-session", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token: storedToken, record: storedUser }),
credentials: "include",
});
} catch {
/* ignore */
}
}
}
setUser(newUser);
setVip(newVip);
return { user: newUser, vip: newVip };
} catch {
const storedUser = getStoredUser();
setUser(storedUser);
setVip(false);
return { user: storedUser, vip: false };
} finally {
setLoading(false);
}
}, []);
useEffect(() => {
refetch();
}, [refetch]);
return { user, vip, loading, refetch };
}