{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "settings-2",
  "title": "Compact Profile Card",
  "description": "Compact centered settings card with avatar upload, name and email fields, timezone, density radios, notification checkboxes, a two-factor switch, and delete-account confirmation.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "alert-dialog",
    "avatar",
    "button",
    "card",
    "checkbox",
    "field",
    "input",
    "radio-group",
    "select",
    "separator",
    "sonner",
    "switch"
  ],
  "files": [
    {
      "path": "registry/blocks/settings/2/settings-block.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { toast } from \"sonner\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport {\n  AlertDialog,\n  AlertDialogAction,\n  AlertDialogCancel,\n  AlertDialogContent,\n  AlertDialogDescription,\n  AlertDialogFooter,\n  AlertDialogHeader,\n  AlertDialogTitle,\n  AlertDialogTrigger,\n} from \"@/components/ui/alert-dialog\"\nimport { Button } from \"@/components/ui/button\"\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardFooter,\n  CardHeader,\n  CardTitle,\n} from \"@/components/ui/card\"\nimport { Checkbox } from \"@/components/ui/checkbox\"\nimport {\n  Field,\n  FieldDescription,\n  FieldGroup,\n  FieldLabel,\n  FieldLegend,\n  FieldSet,\n} from \"@/components/ui/field\"\nimport { Input } from \"@/components/ui/input\"\nimport { RadioGroup, RadioGroupItem } from \"@/components/ui/radio-group\"\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\"\nimport { Separator } from \"@/components/ui/separator\"\nimport { Switch } from \"@/components/ui/switch\"\nimport { Toaster } from \"@/components/ui/sonner\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\n\nconst profile = {\n  name: \"Marcus Trent\",\n  email: \"marcus.trent@acme.com\",\n  role: \"Product Designer\",\n  initials: \"MT\",\n  avatar: \"https://i.pravatar.cc/150?img=13\",\n  twoFactor: true,\n}\n\nconst TIMEZONES = [\n  { value: \"pst\", label: \"Pacific (UTC−8)\" },\n  { value: \"est\", label: \"Eastern (UTC−5)\" },\n  { value: \"gmt\", label: \"London (UTC+0)\" },\n  { value: \"cet\", label: \"Central Europe (UTC+1)\" },\n  { value: \"jst\", label: \"Tokyo (UTC+9)\" },\n]\n\nconst DENSITIES = [\n  { value: \"comfortable\", label: \"Comfortable\" },\n  { value: \"compact\", label: \"Compact\" },\n]\n\nconst NOTIFICATION_PREFS = [\n  { id: \"email-digest\", label: \"Weekly email digest\" },\n  { id: \"mentions\", label: \"Mentions and replies\" },\n  { id: \"product-news\", label: \"Product news\" },\n]\n\nexport default function SettingsBlock() {\n  const [name, setName] = React.useState(profile.name)\n  const [email, setEmail] = React.useState(profile.email)\n  const [role, setRole] = React.useState(profile.role)\n  const [twoFactor, setTwoFactor] = React.useState(profile.twoFactor)\n  const [timezone, setTimezone] = React.useState(\"pst\")\n  const [density, setDensity] = React.useState(\"comfortable\")\n  const [prefs, setPrefs] = React.useState<Record<string, boolean>>({\n    \"email-digest\": true,\n    mentions: true,\n    \"product-news\": false,\n  })\n  const [deleteOpen, setDeleteOpen] = React.useState(false)\n  const avatarInputRef = React.useRef<HTMLInputElement>(null)\n\n  function handleAvatarChange(event: React.ChangeEvent<HTMLInputElement>) {\n    const file = event.target.files?.[0]\n    if (file) {\n      toast.success(\"Photo updated\", {\n        id: \"photo-updated\",\n        description: file.name,\n      })\n    }\n  }\n\n  function handleSave() {\n    toast.success(\"Profile updated\", {\n      id: \"profile-updated\",\n      description: \"Your changes have been saved.\",\n    })\n  }\n\n  function handleDelete() {\n    setDeleteOpen(false)\n    toast.error(\"Account scheduled for deletion\", {\n      id: \"account-deletion\",\n      description: \"You can undo this within 30 days from your inbox.\",\n    })\n  }\n\n  return (\n    <section className=\"flex w-full items-center justify-center bg-background px-6 py-12 text-foreground\">\n      <Card className=\"w-full max-w-sm border-border shadow-sm\">\n        <CardHeader className=\"pb-4\">\n          <CardTitle className=\"text-base font-semibold tracking-tight\">\n            Profile\n          </CardTitle>\n          <CardDescription className=\"text-xs leading-relaxed\">\n            Update your personal details and preferences.\n          </CardDescription>\n        </CardHeader>\n\n        <CardContent className=\"flex flex-col gap-0 p-0\">\n          <div className=\"flex items-center gap-4 border-y border-border bg-muted/40 px-6 py-4\">\n            <div className=\"relative shrink-0\">\n              <Avatar className=\"size-14 border border-border\">\n                <AvatarImage\n                  src={profile.avatar}\n                  alt={profile.name}\n                  className=\"grayscale\"\n                />\n                <AvatarFallback className=\"bg-muted text-sm font-medium text-foreground\">\n                  {profile.initials}\n                </AvatarFallback>\n              </Avatar>\n              <span className=\"absolute right-0.5 bottom-0.5 size-2.5 border-2 border-card bg-primary\" />\n            </div>\n\n            <div className=\"flex min-w-0 flex-1 flex-col gap-0.5\">\n              <span className=\"truncate text-sm leading-tight font-semibold\">\n                {name}\n              </span>\n              <span className=\"truncate text-xs text-muted-foreground\">\n                {role}\n              </span>\n            </div>\n\n            <input\n              ref={avatarInputRef}\n              type=\"file\"\n              accept=\"image/*\"\n              className=\"hidden\"\n              aria-hidden=\"true\"\n              tabIndex={-1}\n              onChange={handleAvatarChange}\n            />\n            <Button\n              variant=\"outline\"\n              size=\"xs\"\n              className=\"shrink-0 gap-1.5 text-xs\"\n              onClick={() => avatarInputRef.current?.click()}\n            >\n              <IconPlaceholder\n                lucide=\"Upload\"\n                tabler=\"IconUpload\"\n                hugeicons=\"UploadIcon\"\n                phosphor=\"Upload\"\n                remixicon=\"RiUploadLine\"\n                className=\"size-3.5\"\n              />\n              Upload\n            </Button>\n          </div>\n\n          <div className=\"px-6 py-5\">\n            <FieldGroup className=\"flex flex-col gap-4\">\n              <Field>\n                <FieldLabel\n                  htmlFor=\"full-name\"\n                  className=\"flex items-center gap-1.5 text-xs font-medium text-muted-foreground\"\n                >\n                  <IconPlaceholder\n                    lucide=\"User\"\n                    tabler=\"IconUser\"\n                    hugeicons=\"UserIcon\"\n                    phosphor=\"User\"\n                    remixicon=\"RiUserLine\"\n                    className=\"size-3.5\"\n                  />\n                  Full name\n                </FieldLabel>\n                <Input\n                  id=\"full-name\"\n                  type=\"text\"\n                  value={name}\n                  onChange={(e) => setName(e.target.value)}\n                  placeholder=\"Your full name\"\n                  className=\"mt-1.5 h-8 text-sm transition-shadow focus-visible:shadow-sm\"\n                />\n              </Field>\n\n              <Field>\n                <FieldLabel\n                  htmlFor=\"email-address\"\n                  className=\"flex items-center gap-1.5 text-xs font-medium text-muted-foreground\"\n                >\n                  <IconPlaceholder\n                    lucide=\"Mail\"\n                    tabler=\"IconMail\"\n                    hugeicons=\"MailIcon\"\n                    phosphor=\"Envelope\"\n                    remixicon=\"RiMailLine\"\n                    className=\"size-3.5\"\n                  />\n                  Email address\n                </FieldLabel>\n                <Input\n                  id=\"email-address\"\n                  type=\"email\"\n                  value={email}\n                  onChange={(e) => setEmail(e.target.value)}\n                  placeholder=\"you@acme.com\"\n                  className=\"mt-1.5 h-8 text-sm transition-shadow focus-visible:shadow-sm\"\n                />\n                <FieldDescription className=\"mt-1.5 text-[11px] leading-relaxed text-muted-foreground\">\n                  Changing your email will require re-verification.\n                </FieldDescription>\n              </Field>\n\n              <Field>\n                <FieldLabel\n                  htmlFor=\"job-title\"\n                  className=\"flex items-center gap-1.5 text-xs font-medium text-muted-foreground\"\n                >\n                  <IconPlaceholder\n                    lucide=\"Briefcase\"\n                    tabler=\"IconBriefcase\"\n                    hugeicons=\"BriefcaseIcon\"\n                    phosphor=\"Briefcase\"\n                    remixicon=\"RiBriefcaseLine\"\n                    className=\"size-3.5\"\n                  />\n                  Job title\n                </FieldLabel>\n                <Input\n                  id=\"job-title\"\n                  type=\"text\"\n                  value={role}\n                  onChange={(e) => setRole(e.target.value)}\n                  placeholder=\"e.g. Senior Engineer\"\n                  className=\"mt-1.5 h-8 text-sm transition-shadow focus-visible:shadow-sm\"\n                />\n              </Field>\n\n              <Field>\n                <FieldLabel\n                  htmlFor=\"timezone\"\n                  className=\"text-xs font-medium text-muted-foreground\"\n                >\n                  Timezone\n                </FieldLabel>\n                <Select\n                  items={TIMEZONES}\n                  value={timezone}\n                  onValueChange={(v) => v && setTimezone(v)}\n                >\n                  <SelectTrigger\n                    id=\"timezone\"\n                    className=\"mt-1.5 h-8 w-full text-sm\"\n                  >\n                    <SelectValue />\n                  </SelectTrigger>\n                  <SelectContent>\n                    {TIMEZONES.map((tz) => (\n                      <SelectItem key={tz.value} value={tz.value}>\n                        {tz.label}\n                      </SelectItem>\n                    ))}\n                  </SelectContent>\n                </Select>\n              </Field>\n            </FieldGroup>\n          </div>\n\n          <Separator />\n\n          <div className=\"flex flex-col gap-5 px-6 py-5\">\n            <FieldSet>\n              <FieldLegend variant=\"label\">Interface density</FieldLegend>\n              <RadioGroup\n                value={density}\n                onValueChange={(value) => setDensity(String(value))}\n              >\n                {DENSITIES.map((option) => (\n                  <Field\n                    key={option.value}\n                    orientation=\"horizontal\"\n                    className=\"gap-2\"\n                  >\n                    <RadioGroupItem\n                      value={option.value}\n                      id={`density-${option.value}`}\n                    />\n                    <FieldLabel\n                      htmlFor={`density-${option.value}`}\n                      className=\"text-xs font-normal\"\n                    >\n                      {option.label}\n                    </FieldLabel>\n                  </Field>\n                ))}\n              </RadioGroup>\n            </FieldSet>\n\n            <FieldSet>\n              <FieldLegend variant=\"label\">Email notifications</FieldLegend>\n              <div data-slot=\"checkbox-group\" className=\"flex flex-col gap-3\">\n                {NOTIFICATION_PREFS.map((pref) => (\n                  <Field\n                    key={pref.id}\n                    orientation=\"horizontal\"\n                    className=\"gap-2\"\n                  >\n                    <Checkbox\n                      id={pref.id}\n                      checked={prefs[pref.id]}\n                      onCheckedChange={(checked) =>\n                        setPrefs((prev) => ({\n                          ...prev,\n                          [pref.id]: checked === true,\n                        }))\n                      }\n                    />\n                    <FieldLabel\n                      htmlFor={pref.id}\n                      className=\"text-xs font-normal\"\n                    >\n                      {pref.label}\n                    </FieldLabel>\n                  </Field>\n                ))}\n              </div>\n            </FieldSet>\n          </div>\n\n          <Separator />\n\n          <div className=\"px-6 py-4\">\n            <div className=\"flex items-start justify-between gap-4\">\n              <div className=\"flex flex-col gap-1\">\n                <div className=\"flex items-center gap-1.5\">\n                  <IconPlaceholder\n                    lucide=\"ShieldCheck\"\n                    tabler=\"IconShieldCheck\"\n                    hugeicons=\"Shield01Icon\"\n                    phosphor=\"ShieldCheck\"\n                    remixicon=\"RiShieldCheckLine\"\n                    className=\"size-3.5 text-muted-foreground\"\n                  />\n                  <span className=\"text-xs font-medium\">\n                    Two-factor authentication\n                  </span>\n                </div>\n                <p className=\"text-[11px] leading-relaxed text-muted-foreground\">\n                  Require a verification code on every sign-in.\n                </p>\n              </div>\n              <Switch\n                id=\"two-factor\"\n                checked={twoFactor}\n                onCheckedChange={setTwoFactor}\n                className=\"mt-0.5 shrink-0\"\n              />\n            </div>\n          </div>\n        </CardContent>\n\n        <CardFooter className=\"flex items-center justify-between gap-3 px-6 py-3\">\n          <AlertDialog open={deleteOpen} onOpenChange={setDeleteOpen}>\n            <AlertDialogTrigger\n              render={\n                <Button\n                  variant=\"ghost\"\n                  size=\"sm\"\n                  className=\"text-xs text-destructive hover:text-destructive\"\n                >\n                  Delete Account\n                </Button>\n              }\n            />\n            <AlertDialogContent>\n              <AlertDialogHeader>\n                <AlertDialogTitle>Delete your account?</AlertDialogTitle>\n                <AlertDialogDescription>\n                  This permanently removes your profile and all associated data.\n                  This action cannot be undone.\n                </AlertDialogDescription>\n              </AlertDialogHeader>\n              <AlertDialogFooter>\n                <AlertDialogCancel>Cancel</AlertDialogCancel>\n                <AlertDialogAction variant=\"destructive\" onClick={handleDelete}>\n                  Delete Account\n                </AlertDialogAction>\n              </AlertDialogFooter>\n            </AlertDialogContent>\n          </AlertDialog>\n          <Button size=\"sm\" className=\"gap-1.5 text-xs\" onClick={handleSave}>\n            Save Changes\n          </Button>\n        </CardFooter>\n      </Card>\n      <Toaster />\n    </section>\n  )\n}\n",
      "type": "registry:component",
      "target": "components/blocks/settings-2.tsx"
    }
  ],
  "meta": {
    "height": "1006px",
    "tier": "free"
  },
  "docs": "Requires a `base-*` style in components.json (the `shadcn init` default). Legacy `new-york`/`radix-*` styles install Radix primitives, which reject the `render` prop this block uses.",
  "categories": [
    "settings"
  ],
  "type": "registry:block"
}