SPB Git

spb/autoscholar

Public
3.8 KB · 119 lines tsx
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
Files · main
Menu

Theme