# Account state

A whole-page stop for a signed-in person the app can't show anything to yet: no account, removed from one, email not verified, an invite to accept. It says who is signed in and offers sign-out, because the usual cause is the wrong email. The wording is the product's, passed in.

As a setup gate (before the app can work at all: connect a model, verify a domain), `steps` lists what's left as a checklist inside the card, `children` holds your own controls for the current step, and an action can stay `locked` with its reason until the steps are done.

- Registry name: `account-state` (`@candor/account-state`)
- Tier: Pro. Installing it needs a Pro, Premium or Team licence key: the person runs `npx candor-ui key <key>` themselves; never ask for the key in chat or write it to a file.
- Docs: https://candor.themethodic.com/docs/account-state

## Install

```bash
npx candor-ui add account-state
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/account-state`.
It brings in: button, locale, locked, setup-checklist, team, utils.

## Example

```tsx
"use client"

import * as React from "react"
import { AccountState } from "@/components/account-state"
import type { SetupStep } from "@/lib/team"

export default function Example() {
  const [gate, setGate] = React.useState(false)
  const [tested, setTested] = React.useState(false)
  // As a setup gate: what's left as a checklist, your own control for the step, Continue locked until it's done.
  const steps: SetupStep[] = [
    { id: "workspace", title: "Name your workspace", status: "done" },
    { id: "model", title: "Connect a model", detail: "Paste an API key in Settings, then test it here.", status: tested ? "done" : "current", action: tested ? undefined : { label: "Test the connection", onClick: () => setTested(true) } },
  ]
  return (
    <div className="flex flex-col gap-2">
      <label className="flex items-center gap-1.5 text-xs text-muted-foreground">
        <input type="checkbox" checked={gate} onChange={(e) => setGate(e.target.checked)} />
        As a setup gate
      </label>
      {!gate ? (
        <div className="flex h-[440px] overflow-hidden rounded-lg border">
          <AccountState
            brand={<span className="text-lg font-semibold tracking-tight">Keel</span>}
            title="You don’t have access to Acme yet"
            detail="Ask an owner of the Acme workspace to invite this email, or sign in with the email you were invited with."
            actions={[
              { label: "Request access", onClick: () => {} },
              { label: "Use a different email", onClick: () => {} },
            ]}
            email="sam@acme.example"
            onSignOut={() => {}}
          />
        </div>
      ) : (
        <div className="flex h-[520px] overflow-hidden rounded-lg border">
          <AccountState
            brand={<span className="text-lg font-semibold tracking-tight">Keel</span>}
            title="One thing before we start"
            detail="Keel needs a model it can reach before it can work on anything."
            steps={steps}
            actions={[{ label: "Continue", onClick: () => {}, locked: tested ? undefined : "Connect a model first." }]}
          />
        </div>
      )}
    </div>
  )
}
```

## <AccountState>

Props:

- `brand: React.ReactNode`: The product's logo or name, shown above the card.
- `title: string`: What's wrong, as the heading, e.g. "You don't have an account yet".
- `detail?: React.ReactNode | undefined`: More on the situation and what to do, under the title.
- `actions: { label: string; onClick: () => void; locked?: string | undefined }[]`: The next steps, the first one primary; `locked` keeps one listed but unusable, with the reason on it.
- `email?: string | undefined`: Who is signed in; with `onSignOut`, printed under the card with a Sign out link.
- `onSignOut?: (() => void) | undefined`: Called when the person chooses Sign out.
- `steps?: SetupStep[] | undefined`: What's left before the app can work, as a checklist in the card (a setup gate).
- `children?: React.ReactNode | undefined`: Your own controls in the card, under the detail and above the steps, such as a choice for the current step.
- `className?: string | undefined`

## Strings (`accountState`)

The fixed words, English by default. Override any of them under `accountState` in `<LocaleProvider strings={{ accountState: { … } }}>`; the table is exported as `accountStateStrings`.

- `signedInAs`: Signed in as {email}
- `signOut`: Sign out

## Rules for using Candor UI

- Components take plain typed data. Never pass model output as HTML or render it as a link; messages are typed blocks.
- A control that can't be used says why: wrap it in `<Locked reason="…">`, don't just disable it.
- Don't show a value you don't have: leave it out (it renders as —) rather than guess. An estimate is labelled as one.
- Nothing is pre-selected in a decision a person makes, and the agent is named from your app's data, never from model output.
- Your app's words go in `LocaleProvider` (fixed strings) and `TermsProvider` (nouns); entity kinds and agent roles in `EntityKindsProvider` and `AgentRolesProvider`.
