{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "activity-4",
  "description": "An activity panel with All, Mentions, and Comments tabs, an unread count, and rows showing the actor avatar with a type icon, the action, target, timestamp, and an unread dot.",
  "dependencies": [
    "@remixicon/react",
    "@base-ui/react"
  ],
  "registryDependencies": [
    "avatar",
    "badge",
    "tabs"
  ],
  "files": [
    {
      "path": "registry/blocks/activity/4/activity-block.tsx",
      "content": "import { RiAtLine, RiChat3Line, RiGitPullRequestLine } from \"@remixicon/react\"\n\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\"\n\ntype ActivityType = \"mention\" | \"comment\" | \"review\"\n\ntype Item = {\n  id: number\n  type: ActivityType\n  actor: { name: string; initials: string; avatar: string }\n  action: string\n  target: string\n  time: string\n  unread: boolean\n}\n\nconst typeIcon = {\n  mention: RiAtLine,\n  comment: RiChat3Line,\n  review: RiGitPullRequestLine,\n}\n\nconst items: Item[] = [\n  {\n    id: 1,\n    type: \"mention\",\n    actor: {\n      name: \"Mara Lin\",\n      initials: \"ML\",\n      avatar: \"https://i.pravatar.cc/64?img=32\",\n    },\n    action: \"mentioned you in\",\n    target: \"Q3 Launch Plan\",\n    time: \"9:42 AM\",\n    unread: true,\n  },\n  {\n    id: 2,\n    type: \"review\",\n    actor: {\n      name: \"Leo Tanaka\",\n      initials: \"LT\",\n      avatar: \"https://i.pravatar.cc/64?img=12\",\n    },\n    action: \"requested your review on\",\n    target: \"PR #418\",\n    time: \"9:15 AM\",\n    unread: true,\n  },\n  {\n    id: 3,\n    type: \"comment\",\n    actor: {\n      name: \"Priya Nair\",\n      initials: \"PN\",\n      avatar: \"https://i.pravatar.cc/64?img=45\",\n    },\n    action: \"commented on\",\n    target: \"Dark Theme Tokens\",\n    time: \"Yesterday\",\n    unread: false,\n  },\n  {\n    id: 4,\n    type: \"mention\",\n    actor: {\n      name: \"Owen Reyes\",\n      initials: \"OR\",\n      avatar: \"https://i.pravatar.cc/64?img=53\",\n    },\n    action: \"mentioned you in\",\n    target: \"Standup Notes\",\n    time: \"Yesterday\",\n    unread: false,\n  },\n]\n\nconst tabs: { value: string; label: string; filter?: ActivityType }[] = [\n  { value: \"all\", label: \"All\" },\n  { value: \"mentions\", label: \"Mentions\", filter: \"mention\" },\n  { value: \"comments\", label: \"Comments\", filter: \"comment\" },\n]\n\nfunction ActivityRow({ item }: { item: Item }) {\n  const Icon = typeIcon[item.type]\n  return (\n    <li className=\"flex items-start gap-3 px-4 py-3\">\n      <div className=\"relative\">\n        <Avatar className=\"size-9\">\n          <AvatarImage\n            src={item.actor.avatar}\n            alt={item.actor.name}\n            className=\"grayscale\"\n          />\n          <AvatarFallback>{item.actor.initials}</AvatarFallback>\n        </Avatar>\n        <span className=\"absolute -right-0.5 -bottom-0.5 flex size-4 items-center justify-center rounded-full bg-background\">\n          <Icon className=\"size-3 text-muted-foreground\" aria-hidden=\"true\" />\n        </span>\n      </div>\n      <div className=\"min-w-0 flex-1\">\n        <p className=\"text-sm text-pretty\">\n          <span className=\"font-medium\">{item.actor.name}</span>{\" \"}\n          <span className=\"text-muted-foreground\">{item.action}</span>{\" \"}\n          <span className=\"font-medium\">{item.target}</span>\n        </p>\n        <span className=\"text-xs text-muted-foreground\">{item.time}</span>\n      </div>\n      {item.unread && (\n        <span\n          className=\"mt-1.5 size-2 shrink-0 rounded-full bg-sky-500\"\n          aria-label=\"Unread\"\n        />\n      )}\n    </li>\n  )\n}\n\nfunction ActivityList({ filter }: { filter?: ActivityType }) {\n  const list = filter ? items.filter((item) => item.type === filter) : items\n  return (\n    <ul className=\"divide-y divide-border\">\n      {list.map((item) => (\n        <ActivityRow key={item.id} item={item} />\n      ))}\n    </ul>\n  )\n}\n\nexport default function ActivityBlock() {\n  const unread = items.filter((item) => item.unread).length\n\n  return (\n    <section className=\"flex min-h-svh w-full items-center justify-center bg-background px-6 py-16 text-foreground\">\n      <div className=\"w-full max-w-md border border-border bg-card ring-1 ring-foreground/5\">\n        <div className=\"flex items-center justify-between gap-2 border-b border-border p-4\">\n          <h2 className=\"text-sm font-semibold\">Activity</h2>\n          <Badge variant=\"secondary\">{unread} New</Badge>\n        </div>\n        <Tabs defaultValue=\"all\">\n          <div className=\"px-4 pt-3\">\n            <TabsList className=\"w-full\">\n              {tabs.map((tab) => (\n                <TabsTrigger key={tab.value} value={tab.value}>\n                  {tab.label}\n                </TabsTrigger>\n              ))}\n            </TabsList>\n          </div>\n          {tabs.map((tab) => (\n            <TabsContent key={tab.value} value={tab.value} className=\"mt-2\">\n              <ActivityList filter={tab.filter} />\n            </TabsContent>\n          ))}\n        </Tabs>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "meta": {
    "height": "500px",
    "tier": "free"
  },
  "categories": [
    "activity"
  ],
  "type": "registry:block"
}