Files
zeekayandGitHub e20dc71ad8 i18n: /s* to /z*, the app's rooms and settings read their copy through t (#69)
The product pages from /s3 to /zap, /university and its course data,
/trust, /security, /sdks, /support, /tasks, /startups, /sms-opt-in, the
buying specialist, Zen, Kai's guide, Studio, the settings pages, and the
shared sales, solutions, zap and ui pieces. Client code draws with t(),
server components with <T>, copy held as data is marked with phrase()
and drawn through t() where it lands. A link or a figure inside a
sentence is a value, so a translator reorders the whole sentence.

Rebased on main: every page main moved onto Fold or Steps keeps main's
layout, with its words wrapped (label, title, lede, points). Steps now
draws a step's body through t, as it already drew the title. Settings
keeps main's usage panel, refresh, rewards wallet and sign-in wallet
rows, each label wrapped.

Left English: the skills page's install line (a command and two URLs),
and the solution eyebrow and sibling heading built from a kind label.

Claude-Session: https://claude.ai/code/session_015XYKLjZtDTJEnMo4eK3AFH
2026-10-29 23:51:44 -07:00

101 lines
3.5 KiB
TypeScript

'use client'
import { useState } from 'react'
import { Room } from '@hanzo/app/Room'
import { Bots } from '@hanzo/app/bots/Bots'
import { Box, Text, XStack } from '@hanzo/ui'
import { Chip } from '@hanzo/ui/marketing'
import { AdditionalBotsWidget } from '@/components/bot/AdditionalBotsWidget'
import { Plus, Sparkles, X } from 'lucide-react'
import { useI18n } from '@hanzo/i18n/react'
export default function BotsRoom() {
const { t } = useI18n()
const [showAddon, setShowAddon] = useState(false)
return (
<Box width="100%" height="100%" display="flex" flexDirection="column">
{/* Bot Pricing & Additional Bots Bar */}
<Box
borderBottomWidth={1}
borderColor="var(--neutral-800)"
px={16}
py={10}
$platform-web={{
backgroundColor: 'color-mix(in oklab, var(--neutral-950) 90%, black)',
}}
>
<XStack flexWrap="wrap" items="center" justify="space-between" gap={12} maxW={1440} mx="auto">
<XStack items="center" gap={10} flexWrap="wrap" shrink={1} minW={0}>
<Chip px={10} py={2} gap={6} bg="var(--neutral-800)">
<Sparkles width={13} height={13} color="var(--primary)" />
{t('Resident Bots')}
</Chip>
<Text fontSize="$2" color="var(--muted-foreground)">
{t('{n} resident bot included on {price} Max plans ({tiers}).', { n: 1, price: '$100+', tiers: 'Max 5x, 20x, 50x' })}{' '}
{t('Need more? Add extra resident bots at {price} each.', {
price: (
<Text color="var(--foreground)" fontWeight="600">
$50/mo
</Text>
),
})}
</Text>
</XStack>
<XStack items="center" gap={16}>
<XStack
render="button"
{...{ type: 'button' }}
onClick={() => setShowAddon((s) => !s)}
px={14}
py={5}
rounded="var(--radius-md)"
borderWidth={1}
borderColor="var(--neutral-700)"
items="center"
gap={6}
$platform-web={{
backgroundColor: showAddon ? 'var(--neutral-800)' : 'color-mix(in oklab, var(--primary) 15%, transparent)',
cursor: 'pointer',
transition: 'all 0.15s ease',
}}
>
{showAddon ? <X width={14} height={14} /> : <Plus width={14} height={14} />}
<Text fontSize="$1" fontWeight="600" color="var(--foreground)">
{showAddon ? t('Close Calculator') : t('Add Additional Bots ({price})', { price: '$50/mo' })}
</Text>
</XStack>
<Text render="a" {...{ href: '/bot' }} fontSize="$1" color="var(--text-secondary)">
{t('Bot Plans & Pricing →')}
</Text>
</XStack>
</XStack>
</Box>
{/* Expandable Additional Bots Calculator Drawer */}
{showAddon && (
<Box
p={16}
$sm={{ p: 24 }}
borderBottomWidth={1}
borderColor="var(--neutral-800)"
$platform-web={{
backgroundColor: 'color-mix(in oklab, var(--neutral-900) 95%, black)',
}}
>
<Box maxW={1024} mx="auto">
<AdditionalBotsWidget />
</Box>
</Box>
)}
{/* Main Bots Workspace */}
<Box flex={1} overflow="hidden">
<Room mode="bots">
<Bots />
</Room>
</Box>
</Box>
)
}