gitdataai/src/app/skills/page.tsx
ZhenYi 4c77426965
Some checks are pending
CI / Rust Lint & Check (push) Waiting to run
CI / Rust Tests (push) Waiting to run
CI / Frontend Lint & Type Check (push) Waiting to run
CI / Frontend Build (push) Blocked by required conditions
docs(landing): align all non-business pages with Command as Service concept
2026-04-16 18:59:37 +08:00

134 lines
6.7 KiB
TypeScript

import {LandingLayout} from '@/components/landing/landing-layout';
import {useNavigate} from 'react-router-dom';
import {Bot, Code2, Globe, Layers, Search, Star} from 'lucide-react';
const FEATURED_SKILLS = [
{
icon: Code2,
name: 'Senior React Developer',
author: 'gitdataai',
rating: 4.9,
runs: 12400,
desc: 'Build production-ready React components with TypeScript, testing, and accessibility built in.',
tags: ['frontend', 'react', 'typescript'],
},
{
icon: Bot,
name: 'Code Reviewer',
author: 'gitdataai',
rating: 4.8,
runs: 8900,
desc: 'Perform thorough code reviews focusing on correctness, security, and maintainability.',
tags: ['review', 'security', 'quality'],
},
{
icon: Layers,
name: 'API Designer',
author: 'community',
rating: 4.7,
runs: 5600,
desc: 'Design REST and GraphQL APIs with OpenAPI specs and validation schemas.',
tags: ['api', 'rest', 'graphql'],
},
{
icon: Globe,
name: 'Documentation Writer',
author: 'community',
rating: 4.6,
runs: 4300,
desc: 'Generate comprehensive API documentation from source code and comments.',
tags: ['docs', 'markdown', 'openapi'],
},
];
const CATEGORIES = ['All', 'Frontend', 'Backend', 'DevOps', 'Security', 'Data', 'Testing'];
export default function SkillsPage() {
const navigate = useNavigate();
return (
<LandingLayout>
<section className="pt-24 pb-32">
<div className="mx-auto max-w-5xl px-6">
{/* Hero */}
<div className="text-center mb-16">
<h1 className="text-4xl md:text-6xl font-semibold tracking-tight mb-4">
The Skill Registry
</h1>
<p className="text-lg text-zinc-500 dark:text-zinc-500 max-w-2xl mx-auto">
Reusable, versioned agent behaviors packaged as skills invoked by command, deployed across your entire agent fleet.
</p>
</div>
{/* Search bar */}
<div className="max-w-xl mx-auto mb-12">
<div
className="flex items-center gap-3 h-11 px-4 rounded-full border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-950">
<Search className="h-4 w-4 text-zinc-400"/>
<input
type="text"
placeholder="Search skills..."
className="flex-1 bg-transparent text-sm text-zinc-900 dark:text-zinc-100 outline-none placeholder:text-zinc-400"
/>
</div>
</div>
{/* Categories */}
<div className="flex gap-2 justify-center mb-12 flex-wrap">
{CATEGORIES.map(cat => (
<button key={cat}
className="h-8 px-4 rounded-full text-xs font-medium transition-colors border border-zinc-200 dark:border-zinc-800 hover:bg-zinc-100 dark:hover:bg-zinc-800/50 bg-white dark:bg-zinc-950">
{cat}
</button>
))}
</div>
{/* Featured skills */}
<div className="grid md:grid-cols-2 gap-5 mb-16">
{FEATURED_SKILLS.map(skill => (
<div key={skill.name}
className="p-6 rounded-2xl border border-zinc-200 dark:border-zinc-800 bg-white dark:bg-zinc-950 hover:border-zinc-300 dark:hover:border-zinc-700 transition-all cursor-pointer group">
<div className="flex items-start gap-4">
<div
className="h-10 w-10 rounded-xl bg-zinc-100 dark:bg-zinc-800/50 flex items-center justify-center shrink-0">
<skill.icon className="h-5 w-5 text-zinc-600 dark:text-zinc-400"/>
</div>
<div className="flex-1 min-w-0">
<div className="flex items-center justify-between mb-1">
<h3 className="text-sm font-semibold text-zinc-900 dark:text-zinc-100">{skill.name}</h3>
<div className="flex items-center gap-1 shrink-0">
<Star className="h-3 w-3 text-amber-500 fill-amber-500"/>
<span className="text-xs text-zinc-500">{skill.rating}</span>
</div>
</div>
<p className="text-xs text-zinc-500 mb-3">{skill.desc}</p>
<div className="flex items-center justify-between">
<div className="flex gap-1.5">
{skill.tags.map(tag => (
<span key={tag}
className="h-5 px-2 rounded-md bg-zinc-100 dark:bg-zinc-800 text-[10px] font-medium text-zinc-500 dark:text-zinc-400">
{tag}
</span>
))}
</div>
<span className="text-[10px] text-zinc-400">{skill.runs.toLocaleString()} runs</span>
</div>
</div>
</div>
</div>
))}
</div>
{/* CTA */}
<div className="text-center">
<p className="text-sm text-zinc-500 mb-4">Publish your own skill and join the registry.</p>
<button onClick={() => navigate('/skills/publish')}
className="h-10 px-6 bg-zinc-900 dark:bg-white text-white dark:text-zinc-900 rounded-full text-sm font-medium hover:bg-zinc-800 dark:hover:bg-zinc-100 transition-colors">
Publish a Skill
</button>
</div>
</div>
</section>
</LandingLayout>
);
}