Files
superwork/vscode/src/codeReader/fixtures/overviewSection.tsx.txt
T

111 lines
3.8 KiB
Plaintext

"use client";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useMutation, useQueryClient } from "@tanstack/react-query";
import { Button } from "@/components/ui/button";
import { formatBytes } from "@/app/(main)/account/storage/format";
import { getStatusView } from "@/app/(main)/apps/deployment-status";
import { presentSessionCreateError } from "@/lib/api/balance-error";
import { type AppDetail, createAppSession, refreshAppQueries } from "@/lib/apps";
import { liveUrl as toLiveUrl } from "@/lib/deployments/live-url";
import { formatRelativeTime } from "@/lib/format/relative-time";
import { SESSION_ROUTE } from "@/lib/sessions";
import { SectionCard, SettingsRow } from "../SettingsRow";
import { sectionHref } from "../nav";
import { DeployTabLink } from "./DeployTabLink";
import { useResumeDeployment } from "./use-resume-deployment";
/** 概览: 一行一件事, 值在左、说明在下、次要动作靠右. */
export const OverviewSection = ({ detail }: { detail: AppDetail }) => {
const router = useRouter();
const queryClient = useQueryClient();
const deployment = detail.deployment ?? null;
const liveUrl = toLiveUrl(detail.custom_domain, deployment?.url);
const resume = useResumeDeployment(detail.id);
const newSession = useMutation({
mutationFn: () => createAppSession(detail.id),
onSuccess: (session) => {
void refreshAppQueries(queryClient, detail.id);
router.push(`${SESSION_ROUTE}?session_id=${session.id}`);
},
onError: (err) => presentSessionCreateError(err, router),
});
return (
<SectionCard title="概览">
<SettingsRow
label="线上地址"
value={
liveUrl ? (
<a href={liveUrl} target="_blank" rel="noreferrer" className="text-primary underline underline-offset-2">
{liveUrl.replace(/^https?:\/\//, "")}
</a>
) : (
"未发布"
)
}
note={detail.custom_domain ? null : "未绑自定义域名"}
action={
detail.custom_domain ? null : (
<Button variant="outline" size="sm" render={<Link href={sectionHref(detail.id, "domain")} />}>
绑定域名
</Button>
)
}
/>
<SettingsRow
label="状态"
value={deployment ? getStatusView(deployment.status).label : "未发布"}
note={deployment ? `${formatRelativeTime(deployment.updated_at)}发布` : null}
action={
deployment?.status === "suspended" ? (
<Button variant="outline" size="sm" onClick={() => resume.mutate(deployment.deployment_id)} disabled={resume.isPending}>
恢复部署
</Button>
) : deployment != null ? (
<DeployTabLink appId={detail.id} />
) : null
}
/>
<SettingsRow
label="规格"
value={deployment?.instance_type_code ?? "—"}
note="重新发布时可换档"
/>
<SettingsRow
label="托管库"
value={
detail.database
? `线上库 ${formatBytes(detail.database.prod_bytes)} · 开发库 ${formatBytes(detail.database.dev_bytes)}`
: "未创建"
}
/>
<SettingsRow
label="会话"
value={`${detail.session_count} 个`}
note={detail.archived_session_count > 0 ? `已归档 ${detail.archived_session_count} 个` : null}
action={
<Button
variant="outline"
size="sm"
onClick={() => newSession.mutate()}
disabled={newSession.isPending}
>
新建会话
</Button>
}
/>
<SettingsRow
label="创建于"
value={new Date(detail.created_at).toLocaleDateString("zh-CN")}
note={detail.slug}
/>
</SectionCard>
);
};