17 lines
4.8 KiB
TypeScript
17 lines
4.8 KiB
TypeScript
import Link from "next/link";
|
||
import { ArrowRight, ArrowUpRight, Search, X } from "lucide-react";
|
||
import { listPapers, normalizeFilters, paperDate, type Filters } from "@/lib/papers";
|
||
import { Button } from "@/components/ui/button";
|
||
export default async function Home({ searchParams }: { searchParams: Promise<Record<string,string | string[] | undefined>> }) {
|
||
const f = normalizeFilters(await searchParams), data = await listPapers(f);
|
||
const pages = Math.ceil(data.total / data.pageSize);
|
||
function href(changes: Filters) { return "/?" + new URLSearchParams(Object.entries({ ...f, ...changes }).filter(([, v]) => typeof v === "string" && !!v) as [string, string][]).toString(); }
|
||
return <main id="main" className="page-shell"><section className="index-intro"><div className="section-kicker">THE OPEN RESEARCH READER <span>01 — INDEX</span></div><h1>好研究,<br /><span className="muted-heading">值得被读到。</span></h1><div className="intro-bottom"><p>从一个问题,到一篇论文。<br />发现研究、阅读摘要,回到每一项工作的原始出处。</p><a href="#papers" className="text-link">浏览论文 <ArrowRight size={16} /></a></div></section>
|
||
{data.mode === "sample" && <div className="sample-note" role="note"><span className="status-dot" /><p>真实数据库样本 · 当前展示 2026-11-06 导出的前 20 条记录,搜索与筛选仅限此样本。</p><Link href="/about">数据说明 <ArrowUpRight size={13} /></Link></div>}
|
||
<section id="papers" className="index-grid"><aside className="index-aside"><h2>研究领域</h2><Link className={!f.topic ? "topic active" : "topic"} href={href({ topic: "", page: "1" })}>全部领域 <span>↗</span></Link>{data.topics.map(t => <Link key={t} className={f.topic === t ? "topic active" : "topic"} href={href({ topic: t, page: "1" })}>{t}</Link>)}<p className="aside-note">保留原始标题与摘要。<br />不把自动生成的解读当成论文结论。</p></aside><div className="paper-index"><div className="index-heading"><h2>{f.topic || "论文索引"}<span>{data.total.toString().padStart(2, "0")}</span></h2><form className="sort-form"><input type="hidden" name="q" value={f.q || ""} /><input type="hidden" name="topic" value={f.topic || ""} /><input type="hidden" name="searchIn" value={f.searchIn || "text"} /><label htmlFor="sort" className="sr-only">排序</label><select id="sort" name="sort" defaultValue={f.sort || "recent"}><option value="recent">收录顺序</option><option value="title">标题 A–Z</option></select><button type="submit" className="quiet-button">排序</button></form></div>
|
||
<form className="search-form" role="search"><Search size={18} aria-hidden /><select name="searchIn" aria-label="搜索范围" defaultValue={f.searchIn || "text"}><option value="text">标题 / 摘要</option><option value="author">作者</option></select><label htmlFor="paper-search" className="sr-only">搜索论文</label><input id="paper-search" name="q" placeholder={f.searchIn === "author" ? "搜索作者姓名…" : "搜索标题或摘要…"} defaultValue={f.q || ""} maxLength={200} /><input type="hidden" name="topic" value={f.topic || ""} /><input type="hidden" name="sort" value={f.sort || "recent"} /><button type="submit" aria-label="搜索论文"><ArrowRight size={18} /></button></form>
|
||
{(f.q || f.topic) && <div className="filter-note"><span>{f.q ? `搜索 “${f.q}”` : f.topic}</span><Link href="/">清除筛选 <X size={13} /></Link></div>}
|
||
{data.items.length ? <ol className="paper-list">{data.items.map((p, i) => <li key={p.id}><article className="paper-row"><span className="row-number">{String((data.page - 1) * data.pageSize + i + 1).padStart(2, "0")}</span><div><div className="paper-meta"><span>{p.topics[0] || "Research"}</span><span>{paperDate(p.publishedAt)}</span></div><h3><Link href={`/papers/${p.id}`}>{p.title}</Link></h3><p className="paper-summary">{p.abstract || "来源未提供摘要。"}</p><div className="row-bottom"><span className="authors">{p.authors.slice(0, 3).join(", ")}{p.authors.length > 3 ? ` +${p.authors.length - 3}` : ""}</span><Link href={`/papers/${p.id}`} className="read-link">阅读简介 <ArrowUpRight size={15} /></Link></div></div></article></li>)}</ol> : <div className="empty-state"><h3>没有找到符合条件的论文</h3><p>{data.mode === "sample" ? "当前只有 20 条样本,试试更短的关键词,或清除领域筛选。" : "试试其他关键词,或清除筛选。"}</p><Button asChild variant="outline"><Link href="/">查看全部论文</Link></Button></div>}
|
||
<nav className="pagination" aria-label="论文分页"><span>{data.total ? `${data.page} / ${Math.max(1,pages)}` : "0 条结果"}</span><div>{data.page > 1 && <Link href={href({ page: String(data.page - 1) })}>上一页</Link>}{data.page < pages && <Link href={href({ page: String(data.page + 1) })}>下一页 <ArrowRight size={14} /></Link>}</div></nav></div></section></main>;
|
||
}
|