# Profile settings

Who you are in the app: your name, your email (shown, but changed through your sign-in provider, which the field says), your time zone for schedules and timestamps, and your theme. Save is enabled only when something changed, and says when it's saved.

- Registry name: `profile-settings` (`@candor/profile-settings`)
- 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/profile-settings

## Install

```bash
npx candor-ui add profile-settings
```

Run `npx candor-ui@latest init` once first (https://candor.themethodic.com/get-started.md). Without the CLI: `npx shadcn@latest add @candor/profile-settings`.
It brings in: button, input, locale, locked, select, utils.
npm packages: lucide-react@^1.67.0.

## Example

```tsx
"use client"

import * as React from "react"
import { ProfileSettings, type Profile } from "@/components/profile-settings"

export default function Example() {
  const [profile, setProfile] = React.useState<Profile>({ name: "Jonas", email: "jonas@acme.example", timeZone: "Europe/Berlin", theme: "system" })
  return (
    <ProfileSettings
      className="w-full max-w-lg"
      profile={profile}
      timeZones={["America/New_York", "Europe/London", "Europe/Berlin", "Asia/Kolkata"]}
      emailManagedBy="Acme’s sign-in provider"
      emailVerified
      onSave={async (next) => {
        await new Promise((r) => setTimeout(r, 500))
        setProfile(next)
      }}
    />
  )
}
```

## <ProfileSettings>

Props:

- `profile: Profile`: The saved profile; the form starts from it and Save enables once it differs.
- `timeZones: string[]`: IANA time zones offered, e.g. "Europe/London".
- `emailManagedBy: string`: Where the email is changed, e.g. "Your company’s Okta".
- `emailVerified: boolean`: Marks the email as verified.
- `onSave: (p: Profile) => void | Promise<void>`: Called on save with the edited profile; "Saved" shows once it resolves.
- `className?: string | undefined`

## Strings (`profileSettings`)

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

- `label`: Profile
- `name`: Name
- `email`: Email
- `emailFrom`: Your email comes from {provider}; change it there.
- `verified`: Verified
- `notVerified`: Not verified
- `timeZone`: Time zone
- `timeZoneHint`: Used for schedules and times you see.
- `theme`: Theme
- `themeSystem`: Match my system
- `themeLight`: Light
- `themeDark`: Dark
- `themeHighContrast`: High contrast
- `saved`: Saved
- `saving`: Saving…
- `save`: Save

## Types

### Profile

```ts
{ name: string; email: string; timeZone: string; theme: "system" | "light" | "dark" | "hc" }
```

## 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`.
