124 lines
6.1 KiB
TypeScript
124 lines
6.1 KiB
TypeScript
import { ArrowRight } from "lucide-react";
|
|
import type { Lang } from "@/app/page";
|
|
|
|
const copy = {
|
|
en: {
|
|
eyebrow: "User journey",
|
|
title: "Users see one continuous flow, not a wall of admin panels",
|
|
description:
|
|
"The homepage and primary workflow stay anchored to the active job: idea, resources, team, permissions, execution, launch, and maintenance.",
|
|
pathTitle: "Minimum MVP path",
|
|
pathDescription:
|
|
"Sign in, download the client, describe the idea, bind Git and cloud resources, confirm role permissions, preview the manifest, create an Agnet deployment placeholder, then keep development and testing moving.",
|
|
steps: [
|
|
["Sign in", "Users only sign in to Heicode, not CodeGW or the OpenBao console."],
|
|
["Describe the idea", "Capture the product, constraints, existing code, and deployment target in the client."],
|
|
["Bind resources", "Manager authorizes Git, SK, docs, and cloud accounts while storing secret_ref only."],
|
|
["Generate the team", "Recommend Product, Architect, Frontend, Backend, Reviewer, Ops, and other sub Agnets."],
|
|
["Assign permissions", "Confirm resources, actions, TTL, and approval requirements through role cards."],
|
|
["Close the loop", "Agnets keep pushing requirements, development, testing, fixes, deployment, and maintenance."],
|
|
],
|
|
cards: [
|
|
["Users do not write manifests", "The default flow shows roles, resources, actions, and approvals. Advanced users can expand the permission manifest."],
|
|
["The web app is not the IDE", "Manager handles auxiliary management and observation. Main development, continuation, and approvals return to the client."],
|
|
["Risky actions need explicit approval", "Production deploys, cloud operations, database writes, and production secret access must be confirmed in the client."],
|
|
],
|
|
},
|
|
zh: {
|
|
eyebrow: "User journey",
|
|
title: "用户看到的是连续流程,不是一堆后台菜单",
|
|
description:
|
|
"首页第一屏和主流程都围绕当前任务展开:想法、资源、团队、权限、执行、上线、维护。",
|
|
pathTitle: "MVP 最小路径",
|
|
pathDescription:
|
|
"登录、下载客户端、输入想法、绑定 Git 和云资源、确认角色权限、预览 manifest、创建 Agnet 部署占位任务、持续推进开发与测试。",
|
|
steps: [
|
|
["登录", "用户只登录 Heicode,不进入 CodeGW 后台或 OpenBao 控制台。"],
|
|
["输入想法", "在客户端描述产品、约束、已有代码和部署目标。"],
|
|
["绑定资源", "Manager 授权 Git、SK、文档、云账号并保存 secret_ref。"],
|
|
["生成团队", "推荐 Product、Architect、Frontend、Backend、Reviewer、Ops 等子 Agnet。"],
|
|
["分配权限", "用角色卡确认资源、动作、有效期和审批要求。"],
|
|
["执行闭环", "Agnet 持续推进需求、开发、测试、修复、部署和维护。"],
|
|
],
|
|
cards: [
|
|
["用户不手写 manifest", "普通流程只展示角色、资源、动作和审批要求,高级用户可以展开查看 permission manifest。"],
|
|
["网页不是 IDE", "Manager 完成辅助管理和观测,主开发对话、继续推进和审批仍回到客户端。"],
|
|
["高危操作单独审批", "生产部署、云操作、数据库写入、访问生产密钥都必须在客户端确认。"],
|
|
],
|
|
},
|
|
} satisfies Record<Lang, {
|
|
eyebrow: string;
|
|
title: string;
|
|
description: string;
|
|
pathTitle: string;
|
|
pathDescription: string;
|
|
steps: Array<[string, string]>;
|
|
cards: Array<[string, string]>;
|
|
}>;
|
|
|
|
export function Paradigm({ lang }: { lang: Lang }) {
|
|
const t = copy[lang];
|
|
|
|
return (
|
|
<section id="workflow" className="py-20 sm:py-28">
|
|
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
<div className="grid gap-12 lg:grid-cols-[0.8fr_1.2fr] lg:items-start">
|
|
<div>
|
|
<p className="text-sm font-bold uppercase tracking-widest text-primary">
|
|
{t.eyebrow}
|
|
</p>
|
|
<h2 className="mt-4 text-3xl font-black tracking-tight sm:text-5xl">
|
|
{t.title}
|
|
</h2>
|
|
<p className="mt-5 text-muted-foreground">
|
|
{t.description}
|
|
</p>
|
|
<div className="mt-8 rounded-[1.7rem] border border-primary/20 bg-primary/10 p-6">
|
|
<p className="text-sm font-semibold text-primary">{t.pathTitle}</p>
|
|
<p className="mt-2 text-sm leading-6 text-muted-foreground">
|
|
{t.pathDescription}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="rounded-[2rem] border border-border bg-card/60 p-4 shadow-sm">
|
|
<div className="grid gap-3">
|
|
{t.steps.map(([title, description], index) => (
|
|
<div
|
|
key={title}
|
|
className="grid gap-3 rounded-[1.4rem] border border-border bg-background/70 p-5 sm:grid-cols-[auto_1fr_auto] sm:items-center"
|
|
>
|
|
<div className="flex h-11 w-11 items-center justify-center rounded-2xl bg-foreground text-sm font-black text-background">
|
|
{String(index + 1).padStart(2, "0")}
|
|
</div>
|
|
<div>
|
|
<h3 className="font-semibold">{title}</h3>
|
|
<p className="mt-1 text-sm leading-6 text-muted-foreground">
|
|
{description}
|
|
</p>
|
|
</div>
|
|
{index < t.steps.length - 1 && (
|
|
<ArrowRight className="hidden h-5 w-5 text-muted-foreground sm:block" />
|
|
)}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="mt-14 grid gap-5 md:grid-cols-3">
|
|
{t.cards.map(([title, desc]) => (
|
|
<div
|
|
key={title}
|
|
className="rounded-[1.5rem] border border-border bg-card/60 p-6"
|
|
>
|
|
<h3 className="font-semibold">{title}</h3>
|
|
<p className="mt-2 text-sm leading-6 text-muted-foreground">{desc}</p>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|