import { useState } from "react"; import { MotionConfig } from "motion/react"; import { Checkbox } from "../ui/checkbox"; import { AgentPreview } from "./AgentPreview"; import { CredentialModeLink } from "./CredentialModeLink"; import { FooterNav } from "./FooterNav"; import { ModelSourceTiles, type CredentialMode, type ModelSource, } from "./ModelSourceTiles"; import { OnboardingHeading } from "./OnboardingPrimitives"; import { PillGuy } from "./PillGuy"; import { SleepingZs } from "./SleepingZs"; import { Stepper } from "./Stepper"; /** * A prototype of the connect step, from the PCLP-Onboarding file (nodes * 2941:8291 and 2933:4592). * * A mock, not the shipped step. The wizard's real step 4 puts two adapter cards * over an advanced-settings disclosure and probes the environment before * hiring; none of that is wired up here. What is here is the part the design is * actually asking a question about — how the row of sources reads as you point * at it, pick one, and flip the whole row between subscription and API * credentials — so it can be judged before any of that machinery is moved. * * It lives in `components/` rather than beside a story because two surfaces * render it: the Storybook stories, and the standalone * `connect-model-preview.html` entry that gets deployed for review. A copy in * each would have drifted the moment one was tweaked. * * Nothing here reaches a backend, and it needs none of the app's providers — * every piece it composes is presentational. */ /** * The two sources the step offers, matching the shipped step's own list. * * Claude Code and Codex are the only adapters the display registry marks * `recommended`, and the real step builds its row from exactly that filter — so * a third tile here would be a design the wizard could never render. OpenCode * was drawn at one point and is deliberately gone. */ const MODEL_SOURCES: ModelSource[] = [ { id: "claude_local", label: "Claude Code", icon: , }, { id: "codex_local", label: "Codex", icon: , }, ]; /** * Which control flips the credential mode. Two alternates of the same * behaviour, kept side by side so they can be compared rather than argued * about: * * `checkbox` is the Figma frames — a ticked box reading "Use API keys instead", * which shows the current state plainly and costs a row of chrome. * * `link` is a line of text that renames itself on press. Lighter, and it turns * the row into a single sentence, but it can only ever name the destination — * so where you are now is left entirely to the tiles' tags. */ export type CredentialControl = "checkbox" | "link"; export function ConnectModelPreview({ initialSourceId = null, initialUseApiKeys = false, control = "checkbox", }: { initialSourceId?: string | null; initialUseApiKeys?: boolean; control?: CredentialControl; }) { const [selectedId, setSelectedId] = useState(initialSourceId); const [useApiKeys, setUseApiKeys] = useState(initialUseApiKeys); const mode: CredentialMode = useApiKeys ? "api" : "subscription"; return ( // The arc's own convention: OS-level reduced motion neutralises the // movement, and every piece below still arrives in its final state.
{/* Connect is the arc's second step. `Stepper` carries its own bottom margin, which is the gap the frame wants under the dots. */}
{/* `relative` is load-bearing: the sleep marks anchor to this box and travel out past its top-right corner. */}
{control === "link" ? ( setUseApiKeys(next === "api")} /> ) : ( )}
{/* The CTA has nothing to connect until a source is picked, so it stays disabled rather than failing on press. */} {}} primaryLabel="Connect" primaryDisabled={selectedId === null} onPrimary={() => {}} />
); }