{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "notification-2",
  "dependencies": [
    "lucide-react",
    "react-icons"
  ],
  "registryDependencies": [
    "avatar",
    "badge",
    "button",
    "card",
    "scroll-area",
    "tabs",
    "utils"
  ],
  "files": [
    {
      "path": "src/components/watermelon-ui/notification-2.tsx",
      "content": "import React from \"react\";\nimport { RiBellFill, RiCheckDoubleFill, RiCircleFill } from \"react-icons/ri\";\nimport { cn } from \"@/lib/utils\";\nimport { Card, CardContent, CardHeader } from \"@/components/ui/card\";\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\";\nimport { Button } from \"@/components/ui/button\";\nimport { Badge } from \"@/components/ui/badge\";\nimport { Tabs, TabsContent, TabsList, TabsTrigger } from \"@/components/ui/tabs\";\nimport { ScrollArea } from \"@/components/ui/scroll-area\";\n\nexport type UpdateType = \"pull_request\" | \"alert\" | \"team\" | \"deploy\" | \"doc\";\nexport type UpdatePriority = \"urgent\" | \"normal\" | \"low\";\nexport type UpdateTab = \"all\" | \"unread\" | \"mentions\";\n\nexport interface UpdateAuthor {\n  name: string;\n  initials: string;\n  avatar?: string;\n}\n\nexport interface TeamUpdate {\n  id: string;\n  type: UpdateType;\n  priority: UpdatePriority;\n  author: UpdateAuthor;\n  project: string;\n  message: string;\n  detail?: string;\n  timestamp: string;\n  isUnread: boolean;\n  isMention: boolean;\n}\n\nexport interface Notification2Props {\n  heading?: string;\n  updates?: TeamUpdate[];\n  className?: string;\n}\n\nconst TypeLabelMap: Record<UpdateType, string> = {\n  pull_request: \"Pull Request\",\n  alert: \"Alert\",\n  team: \"Team\",\n  deploy: \"Deploy\",\n  doc: \"Docs\",\n};\n\nconst PriorityBadgeMap: Record<UpdatePriority, string> = {\n  urgent: \"bg-destructive/10 text-destructive\",\n  normal: \"bg-primary/10 text-primary\",\n  low: \"bg-muted text-muted-foreground\",\n};\n\nconst defaultUpdates: TeamUpdate[] = [\n  {\n    id: \"1\",\n    type: \"alert\",\n    priority: \"urgent\",\n    author: {\n      name: \"Ops Monitor\",\n      initials: \"OM\",\n    },\n    project: \"Infrastructure\",\n    message: \"Production database CPU spiked above 90%\",\n    detail:\n      \"Auto-scaling triggered. A new replica node has been provisioned and is now handling read traffic.\",\n    timestamp: \"2m ago\",\n    isUnread: true,\n    isMention: false,\n  },\n  {\n    id: \"2\",\n    type: \"pull_request\",\n    priority: \"normal\",\n    author: {\n      name: \"Leo Hayashi\",\n      initials: \"LH\",\n      avatar: \"https://assets.watermelon.sh/wm_alex.png\",\n    },\n    project: \"Nebula UI\",\n    message: \"PR #241 — Refactor token pipeline ready for review\",\n    timestamp: \"18m ago\",\n    isUnread: true,\n    isMention: true,\n  },\n  {\n    id: \"3\",\n    type: \"deploy\",\n    priority: \"normal\",\n    author: {\n      name: \"CI Runner\",\n      initials: \"CI\",\n    },\n    project: \"API Gateway\",\n    message: \"v3.7.1 deployed to staging successfully\",\n    detail: \"42 tests passed · Build time 1m 34s · No regressions detected.\",\n    timestamp: \"1h ago\",\n    isUnread: true,\n    isMention: false,\n  },\n  {\n    id: \"4\",\n    type: \"team\",\n    priority: \"low\",\n    author: {\n      name: \"Maya Osei\",\n      initials: \"MO\",\n      avatar: \"https://assets.watermelon.sh/wm_emma.png\",\n    },\n    project: \"Nebula UI\",\n    message: \"Invited Priya Sharma to the Design Tokens workspace\",\n    timestamp: \"3h ago\",\n    isUnread: false,\n    isMention: false,\n  },\n  {\n    id: \"5\",\n    type: \"doc\",\n    priority: \"low\",\n    author: {\n      name: \"James Okafor\",\n      initials: \"JO\",\n      avatar: \"https://assets.watermelon.sh/wm_ben.png\",\n    },\n    project: \"API Gateway\",\n    message: \"Updated the authentication flow runbook\",\n    timestamp: \"Yesterday\",\n    isUnread: false,\n    isMention: true,\n  },\n  {\n    id: \"6\",\n    type: \"pull_request\",\n    priority: \"normal\",\n    author: {\n      name: \"Priya Sharma\",\n      initials: \"PS\",\n      avatar: \"https://assets.watermelon.sh/wm_mia.png\",\n    },\n    project: \"Infrastructure\",\n    message: \"PR #198 — Kubernetes node pool migration merged\",\n    timestamp: \"Yesterday\",\n    isUnread: false,\n    isMention: false,\n  },\n];\n\nexport default function Notification2({\n  heading = \"Team Updates\",\n  updates = defaultUpdates,\n  className,\n}: Notification2Props) {\n  const unreadCount = updates.filter((u) => u.isUnread).length;\n  const mentionCount = updates.filter((u) => u.isMention).length;\n\n  return (\n    <section\n      className={cn(\n        \"bg-background flex items-center justify-center p-4 md:p-8\",\n        className,\n      )}\n    >\n      <Card className=\"w-full max-w-sm gap-1 overflow-hidden rounded-4xl p-2\">\n        <CardHeader className=\"p-2\">\n          <div className=\"flex items-center justify-between\">\n            <div className=\"flex items-center gap-3\">\n              <div className=\"bg-primary/10 flex h-9 w-9 items-center justify-center rounded-xl\">\n                <RiBellFill className=\"text-primary h-4 w-4\" />\n              </div>\n              <div>\n                <h2 className=\"text-foreground text-base font-bold tracking-tight\">\n                  {heading}\n                </h2>\n                <p className=\"text-muted-foreground text-xs font-medium\">\n                  {unreadCount} unread · {updates.length} total\n                </p>\n              </div>\n            </div>\n\n            <div className=\"flex items-center\">\n              <Button\n                variant=\"ghost\"\n                size=\"sm\"\n                className=\"text-primary hover:bg-primary/5 gap-1 rounded-lg text-xs font-semibold\"\n              >\n                <RiCheckDoubleFill className=\"h-3.5 w-3.5\" />\n                Mark all read\n              </Button>\n            </div>\n          </div>\n        </CardHeader>\n        <Tabs defaultValue=\"all\" className=\"w-full\">\n          <div className=\"px-2\">\n            <TabsList className=\"bg-muted h-auto gap-0 rounded-full\">\n              <TabItem value=\"all\" label=\"All\" count={updates.length} />\n              <TabItem value=\"unread\" label=\"Unread\" count={unreadCount} />\n              <TabItem value=\"mentions\" label=\"Mentions\" count={mentionCount} />\n            </TabsList>\n          </div>\n\n          <CardContent className=\"p-0\">\n            <ScrollArea className=\"h-[300px] w-full\">\n              <TabsContent\n                value=\"all\"\n                className=\"m-0 focus-visible:outline-none\"\n              >\n                <UpdateList updates={updates} />\n              </TabsContent>\n              <TabsContent\n                value=\"unread\"\n                className=\"m-0 focus-visible:outline-none\"\n              >\n                <UpdateList updates={updates.filter((u) => u.isUnread)} />\n              </TabsContent>\n              <TabsContent\n                value=\"mentions\"\n                className=\"m-0 focus-visible:outline-none\"\n              >\n                <UpdateList updates={updates.filter((u) => u.isMention)} />\n              </TabsContent>\n            </ScrollArea>\n          </CardContent>\n        </Tabs>\n      </Card>\n    </section>\n  );\n}\n\nfunction TabItem({\n  value,\n  label,\n  count,\n}: {\n  value: string;\n  label: string;\n  count: number;\n}) {\n  return (\n    <TabsTrigger\n      value={value}\n      className={cn(\n        \"text-muted-foreground data-[state=active]:text-foreground relative flex items-center gap-1.5 rounded-full border-transparent px-4 py-2.5 text-sm font-medium transition-colors\",\n        \"data-[state=active]:border-transparent\",\n        \"hover:text-foreground\",\n        \"bg-transparent shadow-none\",\n      )}\n    >\n      {label}\n      {count > 0 && (\n        <span\n          className={cn(\n            \"flex h-4 min-w-[16px] items-center justify-center rounded-full px-1 text-[10px] font-bold tabular-nums\",\n            \"bg-muted text-muted-foreground\",\n          )}\n        >\n          {count}\n        </span>\n      )}\n    </TabsTrigger>\n  );\n}\n\nfunction UpdateList({ updates }: { updates: TeamUpdate[] }) {\n  if (updates.length === 0) {\n    return (\n      <div className=\"flex h-64 flex-col items-center justify-center gap-3\">\n        <div className=\"bg-muted flex h-12 w-12 items-center justify-center rounded-full\">\n          <RiBellFill className=\"text-muted-foreground h-5 w-5 opacity-40\" />\n        </div>\n        <p className=\"text-muted-foreground text-sm font-medium\">\n          Nothing here yet\n        </p>\n      </div>\n    );\n  }\n\n  return (\n    <div className=\"\">\n      {updates.map((update) => (\n        <React.Fragment key={update.id}>\n          <UpdateRow update={update} />\n        </React.Fragment>\n      ))}\n    </div>\n  );\n}\n\nfunction UpdateRow({ update }: { update: TeamUpdate }) {\n  return (\n    <div\n      className={cn(\n        \"group relative flex gap-4 rounded-md px-5 py-4 transition-colors duration-150\",\n        \"hover:bg-muted/40\",\n      )}\n    >\n      <div className=\"relative flex-shrink-0\">\n        <Avatar className=\"h-10 w-10 border-none\">\n          <AvatarImage\n            src={update.author.avatar}\n            alt={update.author.name}\n            className=\"border border-white/10\"\n          />\n          <AvatarFallback className=\"text-secondary-foreground bg-transparent text-xs font-bold\">\n            {update.author.initials}\n          </AvatarFallback>\n        </Avatar>\n      </div>\n\n      <div className=\"flex min-w-0 flex-1 flex-col gap-1\">\n        <div className=\"flex items-center justify-between gap-2\">\n          <div className=\"flex min-w-0 items-center gap-2\">\n            <span className=\"text-foreground truncate text-sm font-semibold\">\n              {update.author.name}\n            </span>\n            <Badge\n              variant=\"outline\"\n              className={cn(\n                \"h-4 shrink-0 rounded-full border-0 px-1.5 text-[10px] font-bold\",\n                PriorityBadgeMap[update.priority],\n              )}\n            >\n              {TypeLabelMap[update.type]}\n            </Badge>\n          </div>\n          <div className=\"flex shrink-0 items-center gap-1\">\n            <span className=\"text-muted-foreground/50 text-xs font-medium tabular-nums\">\n              {update.timestamp}\n            </span>\n            {update.isUnread && (\n              <RiCircleFill className=\"text-primary h-2 w-2 animate-pulse\" />\n            )}\n          </div>\n        </div>\n\n        <span className=\"text-muted-foreground/60 text-xs font-medium\">\n          {update.project}\n        </span>\n\n        <p className=\"text-foreground/80 mt-0.5 text-sm leading-snug font-normal\">\n          {update.message}\n        </p>\n        {update.detail && (\n          <div className=\"border-border bg-muted/30 group-hover:bg-muted/50 mt-2 rounded-lg border p-2 transition-colors\">\n            <p className=\"text-muted-foreground text-xs leading-relaxed\">\n              {update.detail}\n            </p>\n          </div>\n        )}\n      </div>\n    </div>\n  );\n}\n",
      "type": "registry:ui",
      "target": "components/ui/notification-2.tsx"
    }
  ],
  "type": "registry:ui"
}
