Files
hanzo.ai/components/home/OpenSource.tsx

229 lines
9.2 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use client'
import { useState } from 'react'
import { ArrowRight, ArrowUpRight, Star } from 'lucide-react'
import { phrase } from '@hanzo/i18n'
import { useI18n } from '@hanzo/i18n/react'
import { Text, View, XStack, YStack } from '@hanzo/ui'
import { Action, More } from '@hanzo/ui/marketing'
import oss from '@/lib/data/oss.json'
import recency from '@/lib/data/oss-pushed.json'
import { Section } from './chrome'
import HanzoOpenSourceShowcase from '@/components/oss/HanzoOpenSourceShowcase'
import ForgeBetaBanner from './ForgeBetaBanner'
import RepoCard, { GithubMark, ForgeMark } from '@/components/oss/RepoCard'
import BulkStarModal from '@/components/oss/BulkStarModal'
type Repo = { repo: string; line: string; language: string }
/** The 16 featured core repositories */
const FEATURED_16: readonly Repo[] = [
{ repo: 'hanzoai/ai', line: phrase('Model routing and OpenAI-compatible API'), language: 'Go' },
{ repo: 'hanzoai/engine', line: phrase('High-performance model inference'), language: 'Rust' },
{ repo: 'hanzoai/cloud', line: phrase('Open AI cloud infrastructure'), language: 'Go' },
{ repo: 'hanzoai/dev', line: phrase('Autonomous coding agent'), language: 'Rust' },
{ repo: 'hanzoai/base', line: phrase('The data layer: a database per org, live updates and files.'), language: 'Go' },
{ repo: 'hanzoai/iam', line: phrase('Identity: sign-in, organizations, roles and API keys.'), language: 'Go' },
{ repo: 'hanzoai/kms', line: phrase('Secrets, held encrypted and handed out at runtime.'), language: 'Go' },
{ repo: 'hanzoai/commerce', line: phrase('Billing: plans, subscriptions, usage metering and invoices.'), language: 'Go' },
{ repo: 'hanzoai/s3', line: phrase('S3-compatible object storage.'), language: 'Go' },
{ repo: 'hanzoai/ui', line: phrase('The component kit every Hanzo app is built with.'), language: 'TypeScript' },
{ repo: 'hanzoai/mcp', line: phrase('An MCP server with hundreds of tools for agents.'), language: 'Rust' },
{ repo: 'hanzoai/ml', line: phrase('The tensor and ML framework, on CPU, CUDA, Metal and ROCm.'), language: 'Rust' },
{ repo: 'hanzoai/ci', line: phrase('The CI and deploys every repository ships with.'), language: 'Shell' },
{ repo: 'hanzoai/enso', line: phrase('Examples and recipes for Enso, the router.'), language: 'Rust' },
{ repo: 'hanzoai/kai', line: phrase('Examples and recipes for Kai decisions.'), language: 'TypeScript' },
{ repo: 'hanzoai/zen', line: phrase('Zen open models, with examples to run them anywhere.'), language: 'Rust' },
]
const PUBLIC = new Set(oss.public as string[])
const PUSHED = recency.pushed as Record<string, string | null>
type Order = 'name' | 'recent'
function Pick({ on, label, set }: { on: boolean; label: string; set: () => void }) {
return (
<XStack
render={<button type="button" aria-pressed={on} onClick={set} />}
px={12}
py={5}
rounded={6}
bg={on ? 'var(--foreground)' : 'transparent'}
cursor="pointer"
hoverStyle={on ? undefined : { bg: 'var(--white-06)' }}
$platform-web={{ borderRadius: '6px', border: 'none' }}
>
<Text fontSize="$2" lineHeight="$2" fontWeight="500" color={on ? 'var(--background)' : 'var(--muted-foreground)'}>
{label}
</Text>
</XStack>
)
}
export default function OpenSource() {
const { t } = useI18n()
const [order, setOrder] = useState<Order>('name')
const [modalOpen, setModalOpen] = useState(false)
const core = [...FEATURED_16].filter((r) => PUBLIC.has(r.repo)).sort((a, b) =>
order === 'recent' ? String(PUSHED[b.repo] ?? '').localeCompare(String(PUSHED[a.repo] ?? '')) : a.repo.localeCompare(b.repo),
)
return (
<Section
id="open-source"
label="Open.Source"
title={t('Open-source repositories')}
lede={t('Explore, star and follow Hanzo development')}
>
{/* 4 Large Counters and Green Activity Heatmap */}
<HanzoOpenSourceShowcase showHero={false} activityOnly embedded />
<ForgeBetaBanner />
{/* Control bar above the grid */}
<XStack items="center" justify="space-between" flexWrap="wrap" gap={12} pt={8} pb={4}>
<XStack gap={10} items="center">
<Text fontFamily="$mono" fontSize="$1" color="var(--muted-foreground)">
{t('Sort')}
</Text>
<XStack role="group" aria-label={t('Sort repositories')} gap={2} p={3} rounded={9} borderWidth={1} borderColor="var(--border)" $platform-web={{ borderRadius: '9px' }}>
<Pick on={order === 'name'} label={t('A–Z')} set={() => setOrder('name')} />
<Pick on={order === 'recent'} label={t('Recently updated')} set={() => setOrder('recent')} />
</XStack>
</XStack>
<XStack items="center" gap={10}>
{/* Star all (16) dialog trigger */}
<XStack
render={<button type="button" onClick={() => setModalOpen(true)} />}
items="center"
gap={6}
px={12}
py={6}
rounded={8}
borderWidth={1}
borderColor="var(--border)"
bg="rgba(255, 255, 255, 0.04)"
hoverStyle={{ borderColor: 'var(--border-strong)', bg: 'rgba(255, 255, 255, 0.08)' }}
cursor="pointer"
$platform-web={{ borderRadius: '8px', borderStyle: 'solid' }}
>
<Star size={13} color="#39bd7d" fill="#39bd7d" />
<Text fontSize="$2" fontWeight="600" color="var(--foreground)">
{t('Star all 16')}
</Text>
</XStack>
{/* Follow Hanzo link */}
<XStack
render={<a href="https://github.com/hanzoai" target="_blank" rel="noopener noreferrer" />}
items="center"
gap={6}
px={12}
py={6}
rounded={8}
borderWidth={1}
borderColor="var(--border)"
hoverStyle={{ borderColor: 'var(--border-strong)' }}
cursor="pointer"
$platform-web={{ borderRadius: '8px', borderStyle: 'solid', textDecoration: 'none' }}
>
<GithubMark size={14} color="var(--muted-foreground)" />
<Text fontSize="$2" fontWeight="500" color="var(--foreground)">
{t('Follow Hanzo')}
</Text>
<ArrowUpRight size={13} color="var(--muted-foreground)" aria-hidden />
</XStack>
{/* Star on GitHub pill button matching screenshot */}
<XStack
render={<a href="https://github.com/hanzoai" target="_blank" rel="noopener noreferrer" />}
items="center"
gap={6}
px={14}
py={6}
rounded={9999}
bg="#fff"
hoverStyle={{ opacity: 0.9 }}
cursor="pointer"
$platform-web={{ borderRadius: '9999px', textDecoration: 'none' }}
>
<Star size={14} color="#000" />
<Text fontSize="$2" fontWeight="600" color="#000">
{t('Star on GitHub')}
</Text>
<ArrowUpRight size={14} color="#000" aria-hidden />
</XStack>
</XStack>
</XStack>
{/* 4-column minimal grid */}
<View
display="grid"
width="100%"
gap={12}
gridTemplateColumns="minmax(0, 1fr)"
$sm={{ gridTemplateColumns: 'repeat(2, minmax(0, 1fr))' }}
$lg={{ gridTemplateColumns: 'repeat(4, minmax(0, 1fr))' }}
>
{core.map((r) => (
<RepoCard
key={r.repo}
repo={r.repo}
line={r.line}
language={r.language}
/>
))}
</View>
{/* Bottom Footer Row matching screenshot */}
<XStack items="center" justify="space-between" width="100%" pt={12} pb={8} flexWrap="wrap" gap={12}>
<XStack items="center" gap={10}>
<Text fontSize="$2" color="var(--muted-foreground)">
{t('Follow development')}
</Text>
<XStack
render={<a href="https://github.com/hanzoai" target="_blank" rel="noopener noreferrer" title="Follow on GitHub" />}
p={4}
rounded={6}
hoverStyle={{ bg: 'var(--white-06)' }}
$platform-web={{ textDecoration: 'none' }}
>
<GithubMark size={16} color="var(--foreground)" />
</XStack>
<XStack
render={<a href="https://forge.hanzo.ai/hanzoai" target="_blank" rel="noopener noreferrer" title="Follow on Hanzo Forge" />}
p={4}
rounded={6}
hoverStyle={{ bg: 'var(--white-06)' }}
$platform-web={{ textDecoration: 'none' }}
>
<ForgeMark size={16} color="#39bd7d" />
</XStack>
</XStack>
<XStack
render={<a href="/open-source" />}
items="center"
gap={6}
cursor="pointer"
$platform-web={{ textDecoration: 'none' }}
>
<Text fontSize="$2" fontWeight="500" color="var(--foreground)" hoverStyle={{ color: '#39bd7d' }}>
{t('View all')}
</Text>
<ArrowRight size={14} color="var(--foreground)" aria-hidden data-i18n-mirror="" />
</XStack>
</XStack>
{/* Bulk Star Modal */}
<BulkStarModal
open={modalOpen}
onClose={() => setModalOpen(false)}
repositories={FEATURED_16}
/>
</Section>
)
}