spb/autoscholar
Public
1import { listRuns } from "@autoscholar/core";2import { listPapersAdmin } from "@autoscholar/publisher";3import Link from "next/link";4import { StatusBadge } from "@/components/StatusBadge";5import { fmtDateTime } from "@/lib/format";6import { db } from "@/lib/server/db";7import { PaperActions, PublishButton } from "./PublicationActions";89export const dynamic = "force-dynamic";1011export default async function PublicationsPage() {12 const d = db();13 const pending = await listRuns(d, {14 status: ["awaiting_approval", "ready_to_publish", "publishing"],15 limit: 100,16 });17 const papers = await listPapersAdmin(d);18 return (19 <div className="space-y-8">20 <header>21 <p className="eyebrow">Release</p>22 <h1 className="title-2 mt-1">Publications</h1>23 </header>24 <section className="surface p-4">25 <h2 className="title-3">Awaiting release</h2>26 <table className="table mt-2">27 <thead>28 <tr>29 <th>Run</th>30 <th>Status</th>31 <th>Mode</th>32 <th>Action</th>33 </tr>34 </thead>35 <tbody>36 {pending.length === 0 && (37 <tr>38 <td colSpan={4} className="muted py-6 text-center">39 Nothing awaiting approval.40 </td>41 </tr>42 )}43 {pending.map((r) => (44 <tr key={r.id}>45 <td>46 <Link href={`/admin/runs/${r.id}`}>{r.title}</Link>47 </td>48 <td>49 <StatusBadge status={r.status} />50 </td>51 <td>{r.researchMode}</td>52 <td>53 {r.status === "publishing" ? (54 <span className="muted text-xs">publishing (scheduler)</span>55 ) : (56 <PublishButton57 runId={r.id}58 papers={papers.map((p) => ({ id: p.p.id, publicId: p.p.publicId, title: p.p.title }))}59 />60 )}61 </td>62 </tr>63 ))}64 </tbody>65 </table>66 </section>67 <section className="surface p-4">68 <h2 className="title-3">Published papers</h2>69 <table className="table mt-2">70 <thead>71 <tr>72 <th>ID</th>73 <th>Title</th>74 <th>Status</th>75 <th>Version</th>76 <th>Published</th>77 <th>Actions</th>78 </tr>79 </thead>80 <tbody>81 {papers.length === 0 && (82 <tr>83 <td colSpan={6} className="muted py-6 text-center">84 No paper published yet.85 </td>86 </tr>87 )}88 {papers.map((p) => (89 <tr key={p.p.id}>90 <td className="font-mono text-xs">{p.p.publicId}</td>91 <td>92 <Link href={`/research/${p.p.slug}`} target="_blank">93 {p.p.title}94 </Link>95 {p.p.synthetic && <span className="badge ml-1">staging</span>}96 </td>97 <td>98 <StatusBadge status={p.p.status} />99 </td>100 <td>v{p.v?.versionNo ?? "?"}</td>101 <td className="subtle text-xs">{fmtDateTime(p.p.firstPublishedAt)}</td>102 <td>103 <PaperActions104 id={p.p.id}105 status={p.p.status}106 title={p.v?.title ?? p.p.title}107 abstract={p.v?.abstract ?? ""}108 keywords={p.v?.keywords ?? []}109 />110 </td>111 </tr>112 ))}113 </tbody>114 </table>115 </section>116 </div>117 );118}119