Files
heicode/website/components/products.tsx
T

101 lines
4.2 KiB
TypeScript

"use client";
import { MonitorDot, LayoutDashboard } from "lucide-react";
import { useLang } from "@/lib/language";
const t = {
zh: {
badge: "产品组成",
h2: "两个界面,一套完整体验",
subtitle: "客户端是主体验,Manager 是辅助控制台,用户不在网页上编码",
products: [
{
name: "Heicode 客户端",
badge: "主体验",
description: "用户的主入口。在本地输入产品想法、继续任务、查看 Agnet 执行反馈、接收交付结果、审批高危操作。登录 Heicode 即可使用,无需配置模型。",
features: ["任务驾驶舱", "高危审批", "执行反馈", "本地服务"],
},
{
name: "Heicode Manager",
badge: "辅助控制台",
description: "浏览器端辅助控制台。负责账号与安全、客户端下载、Git 与云资源绑定、Agnet 部署、任务状态总览、模型余额与用量、审计与日志查看。",
features: ["资源绑定", "Agnet 部署", "余额与用量", "审计日志"],
},
],
},
en: {
badge: "Product Components",
h2: "Two interfaces, one complete experience",
subtitle: "The client is the main experience, Manager is the auxiliary console",
products: [
{
name: "Heicode Client",
badge: "Main experience",
description: "The user's primary entry point. Input product ideas locally, continue tasks, view Agnet execution feedback, receive delivery results, approve high-risk operations. Log in to Heicode — no model configuration needed.",
features: ["Task dashboard", "Approval flow", "Exec feedback", "Local service"],
},
{
name: "Heicode Manager",
badge: "Aux console",
description: "Browser-based auxiliary console. Handles account & security, client download, Git & cloud resource binding, Agnet deployment, task status overview, model balance & usage, audit & log viewing.",
features: ["Resource binding", "Agnet deploy", "Balance & usage", "Audit log"],
},
],
},
};
const icons = [MonitorDot, LayoutDashboard];
export function Products() {
const { lang } = useLang();
const tx = t[lang];
return (
<section id="products" className="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 tracking-widest text-accent uppercase">
{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-8 md:grid-cols-2">
{tx.products.map((product, idx) => {
const Icon = icons[idx];
return (
<div
key={product.name}
className="group relative rounded-xl border border-border bg-card/50 p-8 transition-colors hover:border-accent/50 hover:bg-card"
>
<div className="mb-6 flex items-center gap-3">
<div className="flex h-12 w-12 items-center justify-center rounded-lg bg-secondary">
<Icon className="h-6 w-6 text-accent" />
</div>
<span className="rounded-full bg-accent/10 px-3 py-1 text-xs font-medium text-accent">
{product.badge}
</span>
</div>
<h3 className="text-xl font-semibold">{product.name}</h3>
<p className="mt-3 text-sm leading-relaxed text-muted-foreground">
{product.description}
</p>
<div className="mt-6 flex flex-wrap gap-2">
{product.features.map((feature) => (
<span
key={feature}
className="rounded-full bg-secondary px-3 py-1 text-xs text-muted-foreground"
>
{feature}
</span>
))}
</div>
</div>
);
})}
</div>
</div>
</section>
);
}