93 lines
2.8 KiB
TypeScript
93 lines
2.8 KiB
TypeScript
"use client";
|
|
|
|
import { useCallback, useEffect, useState } from "react";
|
|
import { usePathname } from "next/navigation";
|
|
import { VipLayout } from "@/app/vip/components/VipLayout";
|
|
import { COMMUNITY_CONFIG } from "@/config/community.config";
|
|
import { MemoExplorer } from "./components/MemoExplorer";
|
|
import { CommunitySidebar } from "./components/CommunitySidebar";
|
|
import styles from "./components/memos.module.css";
|
|
|
|
function getStorage(key: string): string | null {
|
|
if (typeof window === "undefined") {
|
|
return null;
|
|
}
|
|
return localStorage.getItem(key);
|
|
}
|
|
|
|
export default function CommunityLayout({ children }: { children: React.ReactNode }) {
|
|
const pathname = usePathname();
|
|
const [userId, setUserId] = useState<string | null>(null);
|
|
const [isVip, setIsVip] = useState(false);
|
|
const [userName, setUserName] = useState<string | null>(null);
|
|
const [userEmail, setUserEmail] = useState<string | null>(null);
|
|
const [showVipPrompt, setShowVipPrompt] = useState(false);
|
|
|
|
useEffect(() => {
|
|
const nextUserId = getStorage("userId") || getStorage("memosAccount");
|
|
const type = getStorage("paidType");
|
|
const name = getStorage("userName") || getStorage("userEmail");
|
|
const email = getStorage("userEmail");
|
|
|
|
setUserId(nextUserId || null);
|
|
setIsVip(type === "vip");
|
|
setUserName(name || null);
|
|
setUserEmail(email || null);
|
|
}, []);
|
|
|
|
const handleLogout = useCallback(async () => {
|
|
const { pbLogout } = await import("@/app/lib/pocketbase");
|
|
await pbLogout();
|
|
if (typeof window !== "undefined") {
|
|
localStorage.clear();
|
|
window.location.replace("/");
|
|
}
|
|
}, []);
|
|
|
|
if (!COMMUNITY_CONFIG.enabled) {
|
|
return (
|
|
<VipLayout isLoggedIn={false} onLogout={handleLogout}>
|
|
<div className={styles.main}>
|
|
<p className={styles.pageDesc}>社区功能暂未开启。</p>
|
|
</div>
|
|
</VipLayout>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<VipLayout
|
|
isLoggedIn={Boolean(userId)}
|
|
userName={userName}
|
|
userEmail={userEmail}
|
|
onLogout={handleLogout}
|
|
>
|
|
<div className={styles.communityShell}>
|
|
<aside className={styles.leftRail}>
|
|
<MemoExplorer
|
|
userId={userId}
|
|
isVip={isVip}
|
|
pathname={pathname}
|
|
onVipRequired={() => setShowVipPrompt(true)}
|
|
/>
|
|
</aside>
|
|
|
|
<main className={styles.centerRail}>
|
|
{showVipPrompt ? (
|
|
<div className={styles.vipBanner}>
|
|
<p>探索、归档和附件页仅对会员开放。</p>
|
|
<a href="/" className={styles.ctaLink}>
|
|
立即加入会员
|
|
</a>
|
|
</div>
|
|
) : null}
|
|
{children}
|
|
</main>
|
|
|
|
<aside className={styles.rightRail}>
|
|
<CommunitySidebar userId={userId} isVip={isVip} />
|
|
</aside>
|
|
</div>
|
|
</VipLayout>
|
|
);
|
|
}
|