mirror of
https://github.com/hanzo-apps/hanzo.ai.git
synced 2026-10-29 07:20:43 +00:00
Every import, the catalog pin and the docs name @hanzo/app and github.com/hanzoai/app. lib/rooms.ts is lib/app.ts and components/rooms.tsx is components/app.tsx.
101 lines
3.9 KiB
TypeScript
101 lines
3.9 KiB
TypeScript
'use client'
|
|
|
|
// The "try it" chat at the foot of /models. The conversation is the SAME one
|
|
// /chat offers — `Ask` from the workspace — so there is one chat surface on this
|
|
// site with one consent semantic. This section only says what sits under it
|
|
// while nobody is signed in.
|
|
//
|
|
// A SIGNED-IN READER CHATS IN THE APP: they are sent to /chat, which stands
|
|
// behind the organization gate (app/_web.tsx), so a team on Free is asked for
|
|
// its plan there rather than handed a thread here. A visitor who is not signed
|
|
// in keeps the thread.
|
|
//
|
|
// The provider is mounted HERE because this page has no shell above it to own
|
|
// one; on /chat the shell owns it. Whoever hosts the surface supplies the client.
|
|
|
|
import { AiProvider } from '@hanzo/ai/react'
|
|
import { useIam } from '@hanzo/iam/react'
|
|
import { Box, XStack } from '@hanzo/ui'
|
|
import { Card } from '@/components/marketing/band'
|
|
import { Ask } from '@hanzo/app/Chat'
|
|
import { useAi } from '@hanzo/app/lib/ai'
|
|
import { useHydrated } from '@hanzo/app/lib/hydrated'
|
|
import { hasSession } from '@hanzo/app/lib/session'
|
|
import { CHAT, KEYS } from '@/components/home/nav-data'
|
|
import { Action, Lede } from '@hanzo/ui/marketing'
|
|
|
|
export function TryChat() {
|
|
const { client } = useAi()
|
|
const { isAuthenticated, isLoading } = useIam()
|
|
const hydrated = useHydrated()
|
|
// Signed in by the same reading `Ask` makes; until it can be made, both draw the sign-in card.
|
|
if (hydrated && !isLoading && (isAuthenticated || hasSession())) return <Open />
|
|
return (
|
|
<Box
|
|
className="try-chat-container"
|
|
position="relative"
|
|
width="100%"
|
|
>
|
|
<style jsx global>{`
|
|
.try-chat-container [data-slot="crew"],
|
|
.try-chat-container [aria-label="Agents"] {
|
|
display: none !important;
|
|
}
|
|
`}</style>
|
|
<AiProvider client={client ?? undefined}>
|
|
{/* No placeholder: the composer says its own ("Type / for skills"),
|
|
and @hanzo/app' Ask no longer draws one it is handed. */}
|
|
<Ask idle={<SignIn />} />
|
|
</AiProvider>
|
|
</Box>
|
|
)
|
|
}
|
|
|
|
// `Card` carries the rounded border and the translucent fill the hand-written
|
|
// box drew; the paragraph is `Lede` and the two actions are `Action` and
|
|
// `Action fill`, the two weights every call-to-action on the site takes.
|
|
// The card steps its padding 32->48 at $md as the original did; the children
|
|
// centre themselves (the lede on its own measure, the actions in a full-width
|
|
// row) rather than the card being a flex container it never was.
|
|
function SignIn() {
|
|
return (
|
|
<Card mt="$5" p="$6" $md={{ p: '$8' }}>
|
|
<Lede
|
|
maxW={512}
|
|
mx="auto"
|
|
mb={32}
|
|
text="center"
|
|
>
|
|
Sign in to chat with Enso, Zen, or any model on the endpoint. Pick a model, start a thread,
|
|
billed to your account and kept private.
|
|
</Lede>
|
|
<XStack width="100%" flexWrap="wrap" justify="center" gap="$3">
|
|
<Action href={KEYS} fill>
|
|
Get free API key
|
|
</Action>
|
|
<Action href={CHAT}>
|
|
Open Hanzo Chat
|
|
</Action>
|
|
</XStack>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
/** A signed-in reader's way in: the app at /chat. */
|
|
function Open() {
|
|
return (
|
|
<Card mt="$5" p="$6" $md={{ p: '$8' }} data-slot="try-open">
|
|
<Lede maxW={512} mx="auto" mb={32} text="center">
|
|
Chat with Enso, Zen, or any model on the endpoint in Hanzo Chat, billed to your organization.
|
|
</Lede>
|
|
<XStack width="100%" flexWrap="wrap" justify="center" gap="$3">
|
|
<Action href={CHAT} fill>
|
|
Open Hanzo Chat
|
|
</Action>
|
|
</XStack>
|
|
</Card>
|
|
)
|
|
}
|
|
|
|
export default TryChat
|