103 lines
3.4 KiB
TypeScript
103 lines
3.4 KiB
TypeScript
"use client";
|
||
|
||
import Link from "next/link";
|
||
import { useEffect, useMemo, useState } from "react";
|
||
import { CommunityTimeline } from "../components/CommunityTimeline";
|
||
import { CommunityPageHero } from "../components/CommunityPageHero";
|
||
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 ExplorePage() {
|
||
const [userId, setUserId] = useState<string | null>(null);
|
||
const [isVip, setIsVip] = useState(false);
|
||
const [showLoginPrompt, setShowLoginPrompt] = useState(false);
|
||
const [query, setQuery] = useState("");
|
||
|
||
useEffect(() => {
|
||
const uid = getStorage("userId") || getStorage("memosAccount");
|
||
const type = getStorage("paidType");
|
||
setUserId(uid || null);
|
||
setIsVip(type === "vip");
|
||
}, []);
|
||
|
||
useEffect(() => {
|
||
if (typeof window === "undefined") {
|
||
return;
|
||
}
|
||
const tag = new URLSearchParams(window.location.search).get("tag");
|
||
if (tag) {
|
||
setQuery(`#${tag}`);
|
||
}
|
||
}, []);
|
||
|
||
const normalizedQuery = useMemo(() => query.trim(), [query]);
|
||
|
||
return (
|
||
<div className={styles.pageStack}>
|
||
<CommunityPageHero
|
||
eyebrow="Explore Topics"
|
||
title="发现高频问题与热门标签"
|
||
description="按关键词或标签搜索整个社群,把分散动态重新整理成可浏览的话题页。"
|
||
chips={["标签聚合", "关键词检索", "按时间流浏览"]}
|
||
actions={[{ href: "/community", label: "返回首页", secondary: true }]}
|
||
/>
|
||
|
||
<section className={styles.filterPanel}>
|
||
<div className={styles.searchField}>
|
||
<label htmlFor="community-search" className={styles.searchLabel}>
|
||
搜索内容
|
||
</label>
|
||
<input
|
||
id="community-search"
|
||
className={styles.searchInput}
|
||
value={query}
|
||
onChange={(event) => setQuery(event.target.value)}
|
||
placeholder="例如:AI 工具、远程工作、自动化"
|
||
/>
|
||
</div>
|
||
<div className={styles.filterHint}>
|
||
你可以直接输入 `#标签` 或普通关键词,结果会基于当前社群动态实时过滤。
|
||
</div>
|
||
</section>
|
||
|
||
{showLoginPrompt ? (
|
||
<section className={styles.vipBanner}>
|
||
<p>发现页仅对会员开放。</p>
|
||
<Link href="/" className={styles.ctaLink}>
|
||
立即加入会员
|
||
</Link>
|
||
</section>
|
||
) : null}
|
||
|
||
{isVip && userId ? (
|
||
<CommunityTimeline
|
||
userId={userId}
|
||
onVipRequired={() => setShowLoginPrompt(true)}
|
||
state="NORMAL"
|
||
query={normalizedQuery}
|
||
emptyText="没有匹配当前关键词的动态,换个标签试试。"
|
||
/>
|
||
) : (
|
||
<section className={styles.lockedPanel}>
|
||
<div className={styles.lockedPanelCopy}>
|
||
<span className={styles.lockedPanelEyebrow}>Members Only</span>
|
||
<h2 className={styles.lockedPanelTitle}>发现页需要会员权限</h2>
|
||
<p className={styles.lockedPanelDesc}>开通后即可按标签、关键词和时间流探索全部动态。</p>
|
||
</div>
|
||
<div className={styles.lockedPanelActions}>
|
||
<Link href="/" className={styles.heroPrimaryAction}>
|
||
立即加入
|
||
</Link>
|
||
</div>
|
||
</section>
|
||
)}
|
||
</div>
|
||
);
|
||
}
|