161 lines
6.9 KiB
TypeScript
161 lines
6.9 KiB
TypeScript
"use client";
|
|
import { Cable, LockKeyhole, Network, CirclePlay, ArrowRight } from "lucide-react";
|
|
import Link from "next/link";
|
|
import { useLang } from "@/lib/language";
|
|
|
|
const icons = [Cable, LockKeyhole, Network, CirclePlay];
|
|
|
|
const t = {
|
|
zh: {
|
|
badge: "平台资源层",
|
|
h2: "Resources",
|
|
subtitle: "Git、云账号、密钥、模型能力统一纳入可审计、可流程的授权边界",
|
|
footerLink: "查看完整产品文档",
|
|
resources: [
|
|
{
|
|
title: "资源绑定",
|
|
subtitle: "Resource Binding",
|
|
description: "一次授权,全流程复用。支持 Git 仓库、云账号、SK 工具包和项目文档。Agnet 按任务权限申请使用,操作有记录,权限可流程。",
|
|
tags: ["Git 仓库", "云账号", "SK 工具包", "项目文档"],
|
|
href: "/docs#resource-binding",
|
|
},
|
|
{
|
|
title: "密钥保管器",
|
|
subtitle: "Secret Vault",
|
|
description: "长期凭证进入 OpenBao 密钥保管器,数据库只保存引用。Agnet 执行时按审批派生短期最小权限凭证,TTL 到期自动失效。",
|
|
tags: ["OpenBao", "短期凭证", "最小权限", "审计日志"],
|
|
href: "/docs#secret-vault",
|
|
},
|
|
{
|
|
title: "模型网关",
|
|
subtitle: "CodeGW Boundary",
|
|
description: "所有模型调用统一走 CodeGW 路由,用户只见 Heicode 提供的模型,不暴露底层提供商。额度、用量和计费在网关层集中管控。",
|
|
tags: ["统一路由", "额度管控", "用量统计", "计费边界"],
|
|
href: "/docs#codegw",
|
|
},
|
|
{
|
|
title: "产品演示",
|
|
subtitle: "Product Demo",
|
|
description: "完整五步流程:注册登录 → 下载客户端 → 输入想法 → Agnet 执行 → 查看交付结果。10 分钟跑通完整链路。",
|
|
tags: ["快速上手", "完整流程", "使用指南"],
|
|
href: "/docs#demo",
|
|
highlight: true,
|
|
},
|
|
],
|
|
highlightLink: "查看完整使用指南 →",
|
|
},
|
|
en: {
|
|
badge: "Platform Resources",
|
|
h2: "Resources",
|
|
subtitle: "Git, cloud accounts, secrets and model capabilities unified under auditable authorization boundaries",
|
|
footerLink: "View full product documentation",
|
|
resources: [
|
|
{
|
|
title: "Resource Binding",
|
|
subtitle: "Resource Binding",
|
|
description: "Authorize once, reuse across the full lifecycle. Supports Git repos, cloud accounts, SK toolkits and project docs. Agnets request access per-task permission, all operations logged, permissions revocable.",
|
|
tags: ["Git repo", "Cloud account", "SK toolkit", "Project docs"],
|
|
href: "/docs#resource-binding",
|
|
},
|
|
{
|
|
title: "Secret Vault",
|
|
subtitle: "Secret Vault",
|
|
description: "Long-term credentials go into OpenBao secret vault; database stores only references. Agnets receive short-term least-privilege credentials at execution time, TTL expires automatically.",
|
|
tags: ["OpenBao", "Short-term creds", "Least privilege", "Audit log"],
|
|
href: "/docs#secret-vault",
|
|
},
|
|
{
|
|
title: "Model Gateway",
|
|
subtitle: "CodeGW Boundary",
|
|
description: "All model calls route through CodeGW. Users only see Heicode-defined models, never the underlying provider. Quotas, usage and billing are centrally managed at the gateway layer.",
|
|
tags: ["Unified routing", "Quota control", "Usage stats", "Billing boundary"],
|
|
href: "/docs#codegw",
|
|
},
|
|
{
|
|
title: "Product Demo",
|
|
subtitle: "Product Demo",
|
|
description: "Complete 5-step flow: register & login → download client → input idea → Agnet executes → view delivery. Full pipeline in 10 minutes.",
|
|
tags: ["Quick start", "Full flow", "Usage guide"],
|
|
href: "/docs#demo",
|
|
highlight: true,
|
|
},
|
|
],
|
|
highlightLink: "View full usage guide →",
|
|
},
|
|
};
|
|
|
|
export function Resources() {
|
|
const { lang } = useLang();
|
|
const tx = t[lang];
|
|
|
|
return (
|
|
<section id="resources" className="border-y border-border bg-card/20 py-20 sm:py-32">
|
|
<div className="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8">
|
|
<div className="mx-auto max-w-2xl text-center">
|
|
<p className="text-sm font-medium uppercase tracking-widest text-accent">{tx.badge}</p>
|
|
<h2 className="mt-4 text-3xl font-bold tracking-tight sm:text-4xl">{tx.h2}</h2>
|
|
<p className="mt-4 text-muted-foreground">{tx.subtitle}</p>
|
|
</div>
|
|
|
|
<div className="mt-16 grid gap-6 sm:grid-cols-2 lg:gap-8">
|
|
{tx.resources.map((resource, idx) => {
|
|
const Icon = icons[idx];
|
|
return (
|
|
<Link
|
|
key={resource.title}
|
|
href={resource.href}
|
|
className={`group flex flex-col rounded-xl border bg-card/50 p-8 transition-all hover:bg-card hover:shadow-md ${
|
|
resource.highlight
|
|
? "border-accent/40 hover:border-accent/70"
|
|
: "border-border hover:border-accent/40"
|
|
}`}
|
|
>
|
|
<div className="flex items-start gap-4">
|
|
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-accent/10 text-accent">
|
|
<Icon className="h-5 w-5" />
|
|
</div>
|
|
<div className="min-w-0 flex-1">
|
|
<h3 className="text-lg font-semibold">{resource.title}</h3>
|
|
<p className="font-mono text-xs text-muted-foreground">{resource.subtitle}</p>
|
|
</div>
|
|
<ArrowRight className="h-4 w-4 shrink-0 text-muted-foreground/40 transition-transform group-hover:translate-x-1 group-hover:text-accent" />
|
|
</div>
|
|
<p className="mt-4 text-sm leading-relaxed text-muted-foreground">
|
|
{resource.description}
|
|
</p>
|
|
<div className="mt-5 flex flex-wrap gap-2">
|
|
{resource.tags.map((tag) => (
|
|
<span
|
|
key={tag}
|
|
className="rounded-full bg-secondary px-3 py-1 text-xs text-muted-foreground"
|
|
>
|
|
{tag}
|
|
</span>
|
|
))}
|
|
</div>
|
|
{resource.highlight && (
|
|
<div className="mt-5 border-t border-accent/20 pt-4">
|
|
<span className="text-sm font-medium text-accent">{tx.highlightLink}</span>
|
|
</div>
|
|
)}
|
|
</Link>
|
|
);
|
|
})}
|
|
</div>
|
|
|
|
<div className="mt-10 text-center">
|
|
<Link
|
|
href="/docs"
|
|
className="inline-flex items-center gap-2 text-sm text-muted-foreground hover:text-foreground transition-colors"
|
|
>
|
|
{tx.footerLink}
|
|
<ArrowRight className="h-3.5 w-3.5" />
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
|