# Profile And Notification Cards

> Settings page grouping a Profile card (display name, email, visibility select) and a Notifications card of labeled switches, saving with a toast confirmation.

A shadcn/ui block from the [@7ovr](https://7ovr.com) registry, listed on [shadcn.exchange](https://shadcn.exchange/r/7ovr/settings-1).

- Page, with a live preview: https://shadcn.exchange/r/7ovr/settings-1
- Screenshot: https://abzjhwgwpdpz7ua5.public.blob.vercel-storage.com/shots/7ovr/settings-1-light-a71b688b28087d76.png
- Registry item: https://7ovr.com/r/settings-1.json
- Categories: settings
- Listed: 2026-10-13, source last changed 2026-10-13

## Install

```bash
npx shadcn@latest add https://7ovr.com/r/settings-1.json
```

Run it in a project that has shadcn/ui set up. It adds the files below and installs what they depend on.

## Dependencies

- npm packages: `@base-ui/react`
- Registry items: `button`, `card`, `field`, `input`, `select`, `separator`, `sonner`, `switch`

## Files

### `registry/blocks/settings/1/settings-block.tsx`

```tsx
"use client"

import * as React from "react"
import { toast } from "sonner"

import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import {
  Field,
  FieldContent,
  FieldDescription,
  FieldLabel,
} from "@/components/ui/field"
import { Input } from "@/components/ui/input"
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select"
import { Separator } from "@/components/ui/separator"
import { Switch } from "@/components/ui/switch"
import { Toaster } from "@/components/ui/sonner"

const VISIBILITY_OPTIONS = [
  { value: "everyone", label: "Everyone" },
  { value: "team", label: "Only my team" },
  { value: "private", label: "Just me" },
]

const notificationRows = [
  {
    id: "product-updates",
    label: "Product updates",
    description: "News about features and improvements.",
    on: true,
  },
  {
    id: "weekly-digest",
    label: "Weekly digest",
    description: "A summary of your activity every Monday.",
    on: false,
  },
  {
    id: "mentions",
    label: "Mentions",
    description: "Get notified when someone mentions you.",
    on: true,
  },
] as const

export default function SettingsBlock() {
  const [displayName, setDisplayName] = React.useState("Ada Lovelace")
  const [email, setEmail] = React.useState("ada@acme.com")
  const [visibility, setVisibility] = React.useState("team")
  const [notifications, setNotifications] = React.useState<
    Record<string, boolean>
  >(() => Object.fromEntries(notificationRows.map((row) => [row.id, row.on])))

  function handleSave() {
    toast.success("Changes saved", {
      id: "changes-saved",
      description: "Your settings have been updated.",
    })
  }

  return (
    <section className="flex min-h-svh w-full justify-center bg-background px-4 py-10 text-foreground sm:py-16">
      <div className="flex w-full max-w-2xl flex-col gap-6">
        <div>
          <h1 className="font-heading text-2xl font-bold tracking-tight">
            Settings
          </h1>
          <p className="mt-1 text-sm text-muted-foreground">
            Manage your account preferences and how you receive updates.
          </p>
        </div>

        <Card>
          <CardHeader>
            <CardTitle>Profile</CardTitle>
          </CardHeader>
          <CardContent className="flex flex-col gap-4">
            <Field orientation="horizontal">
              <FieldContent>
                <FieldLabel htmlFor="display-name">Display name</FieldLabel>
                <FieldDescription>
                  The name shown across your workspace.
                </FieldDescription>
              </FieldContent>
              <Input
                id="display-name"
                type="text"
                value={displayName}
                onChange={(e) => setDisplayName(e.target.value)}
                className="w-44"
              />
            </Field>

            <Separator />

            <Field orientation="horizontal">
              <FieldContent>
                <FieldLabel htmlFor="email">Email address</FieldLabel>
                <FieldDescription>
                  Used for sign-in and account notices.
                </FieldDescription>
              </FieldContent>
              <Input
                id="email"
                type="email"
                value={email}
                onChange={(e) => setEmail(e.target.value)}
                className="w-44"
              />
            </Field>

            <Separator />

            <Field orientation="horizontal">
              <FieldContent>
                <FieldLabel htmlFor="profile-visibility">
                  Profile visibility
                </FieldLabel>
                <FieldDescription>
                  Choose who can view your activity.
                </FieldDescription>
              </FieldContent>
              <Select
                items={VISIBILITY_OPTIONS}
                value={visibility}
                onValueChange={(v) => v && setVisibility(v)}
              >
                <SelectTrigger id="profile-visibility" className="w-44">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent alignItemWithTrigger={false}>
                  {VISIBILITY_OPTIONS.map((option) => (
                    <SelectItem key={option.value} value={option.value}>
                      {option.label}
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>
          </CardContent>
        </Card>

        <Card>
          <CardHeader>
            <CardTitle>Notifications</CardTitle>
          </CardHeader>
          <CardContent className="flex flex-col gap-4">
            {notificationRows.map((row, index) => (
              <div key={row.id} className="flex flex-col gap-4">
                {index > 0 && <Separator />}
                <Field orientation="horizontal">
                  <FieldContent>
                    <FieldLabel htmlFor={row.id}>{row.label}</FieldLabel>
                    <FieldDescription>{row.description}</FieldDescription>
                  </FieldContent>
                  <Switch
                    id={row.id}
                    checked={notifications[row.id]}
                    onCheckedChange={(checked) =>
                      setNotifications((prev) => ({
                        ...prev,
                        [row.id]: checked,
                      }))
                    }
                  />
                </Field>
              </div>
            ))}
          </CardContent>
        </Card>

        <div className="flex justify-end">
          <Button onClick={handleSave}>Save Changes</Button>
        </div>
      </div>
      <Toaster />
    </section>
  )
}
```
