185 lines
8.4 KiB
TypeScript
185 lines
8.4 KiB
TypeScript
import { Button } from "@/components/ui/button";
|
|
import { ArrowRight, CalendarDays, CheckCircle2, Rocket, ShieldCheck, Sparkles, Workflow } from "lucide-react";
|
|
import type { Lang } from "@/app/page";
|
|
|
|
const MANAGER_URL = "https://code.xinghanlab.com/";
|
|
const REGISTER_URL = "https://code.xinghanlab.com/sign-up";
|
|
|
|
const copy = {
|
|
en: {
|
|
eyebrow: "Full launch",
|
|
date: "June 5, 2026",
|
|
title: "Heicode goes fully live on June 5, 2026.",
|
|
lead:
|
|
"The public launch brings together Heicode Client, Heicode Manager, Agent Swarm, model usage, resource binding and approval audit into one delivery-ready product flow.",
|
|
primary: "Register now",
|
|
secondary: "Enter Heicode",
|
|
highlights: ["Client-first workflow", "Agent Swarm execution", "Resource and secret governance", "Usage, billing and audit visibility"],
|
|
sections: [
|
|
{
|
|
icon: Rocket,
|
|
title: "Launch scope",
|
|
desc: "Users can register, enter Heicode, bind development resources, start an Agent workflow and keep software delivery moving through the client.",
|
|
},
|
|
{
|
|
icon: Workflow,
|
|
title: "Delivery loop",
|
|
desc: "Idea intake, task decomposition, resource authorization, Agent execution, review, approval and deployment records stay in one traceable loop.",
|
|
},
|
|
{
|
|
icon: ShieldCheck,
|
|
title: "Governed access",
|
|
desc: "Production actions, cloud resources, secrets and model budget are controlled by explicit approvals and auditable grants.",
|
|
},
|
|
],
|
|
timelineTitle: "Launch path",
|
|
timeline: [
|
|
["Now", "Open registration and product preview entry."],
|
|
["Before launch", "Complete onboarding, docs, Manager links and launch readiness checks."],
|
|
["June 5, 2026", "Full public launch of the Heicode product flow."],
|
|
],
|
|
note:
|
|
"The launch page is designed as the public landing point for announcements, registration, and product readiness communication.",
|
|
},
|
|
zh: {
|
|
eyebrow: "全面上线",
|
|
date: "2026年6月5日",
|
|
title: "Heicode 将于 2026年6月5日全面上线。",
|
|
lead:
|
|
"全面上线版本会把 Heicode 客户端、Heicode Manager、Agent 蜂群、模型用量、资源绑定和审批审计整合成一条可交付的产品流程。",
|
|
primary: "立即注册",
|
|
secondary: "进入 Heicode",
|
|
highlights: ["客户端主流程", "Agent 蜂群执行", "资源与密钥治理", "用量、计费与审计可见"],
|
|
sections: [
|
|
{
|
|
icon: Rocket,
|
|
title: "上线范围",
|
|
desc: "用户可以注册、进入 Heicode、绑定开发资源、启动 Agent 工作流,并通过客户端持续推进软件交付。",
|
|
},
|
|
{
|
|
icon: Workflow,
|
|
title: "交付闭环",
|
|
desc: "想法输入、任务拆解、资源授权、Agent 执行、复核、审批和部署记录会留在同一个可追踪流程中。",
|
|
},
|
|
{
|
|
icon: ShieldCheck,
|
|
title: "受控访问",
|
|
desc: "生产动作、云资源、密钥和模型预算都通过明确审批和可审计授权控制。",
|
|
},
|
|
],
|
|
timelineTitle: "上线节奏",
|
|
timeline: [
|
|
["现在", "开放注册入口和产品预览入口。"],
|
|
["上线前", "完成新手引导、文档、Manager 链接和上线检查。"],
|
|
["2026年6月5日", "Heicode 产品流程全面公开上线。"],
|
|
],
|
|
note:
|
|
"该页面作为对外上线公告、注册引导和产品准备状态说明的统一入口。",
|
|
},
|
|
} satisfies Record<Lang, {
|
|
eyebrow: string;
|
|
date: string;
|
|
title: string;
|
|
lead: string;
|
|
primary: string;
|
|
secondary: string;
|
|
highlights: string[];
|
|
sections: Array<{ icon: typeof Rocket; title: string; desc: string }>;
|
|
timelineTitle: string;
|
|
timeline: Array<[string, string]>;
|
|
note: string;
|
|
}>;
|
|
|
|
export function LaunchPage({ lang }: { lang: Lang }) {
|
|
const t = copy[lang];
|
|
|
|
return (
|
|
<section className="relative overflow-hidden pt-28 pb-20 sm:pt-36 sm:pb-28">
|
|
<div className="pointer-events-none absolute inset-0 bg-[radial-gradient(circle_at_15%_10%,color-mix(in_oklch,var(--primary)_18%,transparent),transparent_32%),radial-gradient(circle_at_85%_15%,color-mix(in_oklch,var(--accent)_16%,transparent),transparent_30%)]" />
|
|
<div className="relative mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
<div className="grid gap-12 lg:grid-cols-[1fr_0.9fr] lg:items-center">
|
|
<div>
|
|
<div className="mb-6 inline-flex items-center gap-2 rounded-full border border-border bg-card/75 px-4 py-2 text-sm font-semibold shadow-sm backdrop-blur">
|
|
<Sparkles className="h-4 w-4 text-primary" />
|
|
{t.eyebrow}
|
|
</div>
|
|
<div className="mb-5 inline-flex items-center gap-2 rounded-2xl bg-foreground px-4 py-3 text-background shadow-xl">
|
|
<CalendarDays className="h-5 w-5 text-primary" />
|
|
<span className="text-sm font-black tracking-wide">{t.date}</span>
|
|
</div>
|
|
<h1 className="max-w-4xl text-5xl font-black leading-[0.95] tracking-[-0.06em] sm:text-7xl">
|
|
{t.title}
|
|
</h1>
|
|
<p className="mt-7 max-w-2xl text-lg leading-8 text-muted-foreground sm:text-xl">
|
|
{t.lead}
|
|
</p>
|
|
<div className="mt-9 flex flex-col gap-4 sm:flex-row">
|
|
<Button size="lg" className="h-12 rounded-full bg-primary px-7 text-primary-foreground hover:bg-primary/90" asChild>
|
|
<a href={REGISTER_URL} target="_blank" rel="noreferrer">
|
|
{t.primary}
|
|
<ArrowRight className="h-4 w-4" />
|
|
</a>
|
|
</Button>
|
|
<Button variant="outline" size="lg" className="h-12 rounded-full border-foreground/20 bg-card/50 px-7" asChild>
|
|
<a href={MANAGER_URL} target="_blank" rel="noreferrer">
|
|
{t.secondary}
|
|
</a>
|
|
</Button>
|
|
</div>
|
|
<div className="mt-8 grid gap-3 text-sm text-muted-foreground sm:grid-cols-2">
|
|
{t.highlights.map((item) => (
|
|
<div key={item} className="flex items-center gap-2 rounded-full bg-card/70 px-4 py-3">
|
|
<CheckCircle2 className="h-4 w-4 text-accent" />
|
|
{item}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
|
|
<div className="rounded-[2rem] border border-border bg-card/70 p-5 shadow-2xl backdrop-blur">
|
|
<div className="rounded-[1.5rem] bg-foreground p-6 text-background">
|
|
<p className="text-sm font-bold uppercase tracking-[0.22em] text-background/45">
|
|
{t.timelineTitle}
|
|
</p>
|
|
<div className="mt-6 space-y-4">
|
|
{t.timeline.map(([time, desc], index) => (
|
|
<div key={time} className="grid grid-cols-[auto_1fr] gap-4">
|
|
<div className="flex flex-col items-center">
|
|
<div className="flex h-10 w-10 items-center justify-center rounded-full bg-primary text-sm font-black text-primary-foreground">
|
|
{index + 1}
|
|
</div>
|
|
{index < t.timeline.length - 1 && <div className="h-full w-px bg-background/20" />}
|
|
</div>
|
|
<div className="pb-5">
|
|
<h3 className="font-semibold">{time}</h3>
|
|
<p className="mt-1 text-sm leading-6 text-background/65">{desc}</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
<p className="mt-2 rounded-2xl border border-background/10 bg-background/5 p-4 text-sm leading-6 text-background/70">
|
|
{t.note}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-16 grid gap-5 md:grid-cols-3">
|
|
{t.sections.map((section) => {
|
|
const Icon = section.icon;
|
|
return (
|
|
<div key={section.title} className="rounded-[1.6rem] border border-border bg-card/70 p-6 shadow-sm">
|
|
<div className="mb-5 flex h-12 w-12 items-center justify-center rounded-2xl bg-primary/10 text-primary">
|
|
<Icon className="h-6 w-6" />
|
|
</div>
|
|
<h2 className="text-xl font-bold">{section.title}</h2>
|
|
<p className="mt-3 text-sm leading-7 text-muted-foreground">{section.desc}</p>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|