feat: establish NekoNest Cloud control and relay

This commit is contained in:
2026-08-12 23:25:43 +08:00
commit f27606b709
222 changed files with 71456 additions and 0 deletions
+138
View File
@@ -0,0 +1,138 @@
import Link from "next/link";
import { requireCloudViewer } from "../cloud-auth";
import {
DashboardShell,
PageHeading,
StatusPill,
formatDate,
} from "../components/Shells";
import { getDashboardSnapshot, getOrCreateAccount } from "@/db/repository";
import { getConnectionCopy } from "./connection-copy";
import { OpenPwaButton } from "./OpenPwaButton";
import { deriveControlPlaneContact } from "@/db/device-control-plane";
import { deriveBetaOnboarding } from "./onboarding";
export const dynamic = "force-dynamic";
export default async function DashboardPage() {
const viewer = await requireCloudViewer("/dashboard");
const account = await getOrCreateAccount(viewer);
const snapshot = await getDashboardSnapshot(account);
const activeHosts = snapshot.hosts.filter((host) => host.lifecycle === "active");
const entitlement = snapshot.entitlement;
const connection = getConnectionCopy(snapshot.connection.state);
const onboarding = deriveBetaOnboarding({
entitlement,
hasPendingRequest: snapshot.accessRequests.some((request) => request.status === "requested"),
});
const entitlementLabel = entitlement.mode === "public_beta"
? "公测免费"
: entitlement.mode === "grant"
? "闭测邀请"
: entitlement.publicBetaState === "gated"
? "等待安全门禁"
: "无有效权益";
const entitlementDetail = entitlement.mode === "none" && entitlement.publicBetaState === "gated"
? `公开接入仍有 ${entitlement.blockedP0} 项 P0 未通过;管理员邀请账户可继续闭测`
: entitlement.unlimited
? "费用全免;当前策略未按槽位限额"
: `可用 ${entitlement.availableSlots ?? 0} 个槽位`;
return (
<DashboardShell
viewer={viewer}
active="/dashboard"
serviceStatus={snapshot.serviceStatus}
>
<div className="cloud-page">
<PageHeading
eyebrow="OVERVIEW / 总览"
title={`晚上好,${viewer.displayName}`}
description="这里显示控制平面真实保存的公测接入状态;原生会话仍由你的主机和 NekoNest PWA 提供。"
actions={snapshot.connection.state === "ready"
? <OpenPwaButton />
: <Link className="button button-primary" href={onboarding.primaryHref}>{onboarding.primaryLabel}</Link>}
/>
<section className="metric-grid" aria-label="账户概览">
<article className="metric-card accent-card">
<span></span>
<strong>{entitlementLabel}</strong>
<small>{entitlementDetail}</small>
</article>
<article className="metric-card">
<span></span>
<strong>{entitlement.activeSlots}</strong>
<small>{entitlement.reservedSlots ? `${entitlement.reservedSlots} 个配对请求占位中` : "没有等待配对的占位"}</small>
</article>
<article className="metric-card">
<span></span>
<strong>{connection.label}</strong>
<small>{snapshot.connection.homeRegion
? `${snapshot.connection.homeRegion} · generation ${snapshot.connection.placementGeneration ?? "-"}`
: "等待 home region 分配"}</small>
</article>
<article className="metric-card">
<span></span>
<strong></strong>
<small></small>
</article>
</section>
<div className="dashboard-columns">
<section className="panel">
<div className="panel-heading">
<div><span></span><h2></h2></div>
<Link href="/dashboard/hosts"> </Link>
</div>
{activeHosts.length ? (
<div className="host-list">
{activeHosts.slice(0, 4).map((host) => {
const contact = deriveControlPlaneContact(host.control_plane_last_seen_at);
return (
<article className="host-row" key={host.id}>
<span className={`host-icon host-${host.os}`}>{host.os === "windows" ? "W" : "L"}</span>
<div><strong>{host.name}</strong><small>{host.daemon_version || "daemon 版本待上报"}</small></div>
<div className="host-state">
<StatusPill tone={contact.tone}>{contact.label}</StatusPill>
<small>{host.control_plane_last_seen_at ? formatDate(host.control_plane_last_seen_at, true) : "等待首次 Relay 授权"}</small>
</div>
</article>
);
})}
</div>
) : (
<div className="empty-state compact-empty">
<span className="empty-symbol"></span>
<h3></h3>
<p>daemon Relay </p>
<Link className="button button-secondary" href="/dashboard/hosts/new"></Link>
</div>
)}
</section>
<section className="panel attention-panel">
<div className="panel-heading"><div><span></span><h2></h2></div></div>
<div className="attention-list">
{onboarding.state !== "ready" && <article><StatusPill tone={onboarding.tone}>{onboarding.state === "request_pending" ? "审核中" : onboarding.state === "request_needed" ? "先申请" : "容量已满"}</StatusPill><div><strong>{onboarding.title}</strong><p>{onboarding.detail} <Link className="text-link" href={onboarding.primaryHref}>{onboarding.primaryLabel} </Link></p></div></article>}
<article><StatusPill tone={connection.tone}>{connection.label}</StatusPill><div><strong>{connection.detail}</strong><p>{connection.nextStep}</p></div></article>
{entitlement.publicBetaState === "gated" && <article><StatusPill tone="warn"></StatusPill><div><strong>P0 </strong><p></p></div></article>}
<article><StatusPill tone="info"></StatusPill><div><strong></strong><p></p></div></article>
<article><StatusPill tone="info"></StatusPill><div><strong></strong><p></p></div></article>
</div>
</section>
</div>
<section className="path-panel">
<div><span className="eyebrow">CONNECTION PATH</span><h2></h2></div>
<ol>
<li className={entitlement.mode !== "none" ? "done" : "current"}><span>01</span><div><strong></strong><p>{onboarding.title}{onboarding.detail}</p></div></li>
<li className={snapshot.pairings.length || activeHosts.length ? "done" : onboarding.state === "ready" ? "current" : undefined}><span>02</span><div><strong></strong><p></p></div></li>
<li className={activeHosts.length ? "done" : snapshot.pairings.length ? "current" : undefined}><span>03</span><div><strong>daemon </strong><p> authorization revision</p></div></li>
<li className={snapshot.connection.state === "ready" ? "done" : activeHosts.length ? "current" : undefined}><span>04</span><div><strong> sealed Relay </strong><p>{snapshot.connection.state === "ready" ? "daemon 保持稳定服务地址即可连接。" : "等待租户 placement 指向健康节点;不会向客户端释放后端节点 URL。"}</p></div></li>
</ol>
</section>
</div>
</DashboardShell>
);
}