{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "dashboard-2",
  "title": "KPI Cards And Activity Feed",
  "description": "Dashboard pairing four KPI cards carrying trend badges with a full-width recent activity feed of avatars, events, status badges, and timestamps.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "avatar",
    "badge",
    "card",
    "select",
    "separator"
  ],
  "files": [
    {
      "path": "registry/blocks/dashboard/2/dashboard-block.tsx",
      "content": "\"use client\"\n\nimport * as React from \"react\"\nimport { Avatar, AvatarFallback, AvatarImage } from \"@/components/ui/avatar\"\nimport { Badge } from \"@/components/ui/badge\"\nimport {\n  Card,\n  CardContent,\n  CardDescription,\n  CardHeader,\n  CardTitle,\n} from \"@/components/ui/card\"\nimport {\n  Select,\n  SelectContent,\n  SelectItem,\n  SelectTrigger,\n  SelectValue,\n} from \"@/components/ui/select\"\nimport { Separator } from \"@/components/ui/separator\"\nimport { cn } from \"@/lib/utils\"\nimport { IconPlaceholder } from \"@/components/icons/icon-placeholder\"\n\n/** Props a call site may pass through to an icon. */\ntype IconProps = { className?: string; size?: number | string }\n\nconst PERIODS = [\n  { value: \"jun-2026\", label: \"June 2026\" },\n  { value: \"may-2026\", label: \"May 2026\" },\n  { value: \"apr-2026\", label: \"April 2026\" },\n  { value: \"q2-2026\", label: \"Q2 2026\" },\n]\n\ntype Stat = {\n  label: string\n  value: string\n  delta: string\n  trend: \"up\" | \"down\"\n  good: boolean\n  sub: string\n}\n\nconst STATS_BY_PERIOD: Record<string, Stat[]> = {\n  \"jun-2026\": [\n    {\n      label: \"Monthly Revenue\",\n      value: \"$94,310\",\n      delta: \"+8.2%\",\n      trend: \"up\",\n      good: true,\n      sub: \"Vs. Last Month\",\n    },\n    {\n      label: \"New Signups\",\n      value: \"1,482\",\n      delta: \"+23.5%\",\n      trend: \"up\",\n      good: true,\n      sub: \"Vs. Last Month\",\n    },\n    {\n      label: \"Churn Rate\",\n      value: \"1.7%\",\n      delta: \"+0.4%\",\n      trend: \"up\",\n      good: false,\n      sub: \"Vs. Last Month\",\n    },\n    {\n      label: \"Support Tickets\",\n      value: \"38\",\n      delta: \"-14.9%\",\n      trend: \"down\",\n      good: true,\n      sub: \"Vs. Last Month\",\n    },\n  ],\n  \"may-2026\": [\n    {\n      label: \"Monthly Revenue\",\n      value: \"$87,140\",\n      delta: \"+5.1%\",\n      trend: \"up\",\n      good: true,\n      sub: \"Vs. Last Month\",\n    },\n    {\n      label: \"New Signups\",\n      value: \"1,199\",\n      delta: \"+11.2%\",\n      trend: \"up\",\n      good: true,\n      sub: \"Vs. Last Month\",\n    },\n    {\n      label: \"Churn Rate\",\n      value: \"1.6%\",\n      delta: \"-0.2%\",\n      trend: \"down\",\n      good: true,\n      sub: \"Vs. Last Month\",\n    },\n    {\n      label: \"Support Tickets\",\n      value: \"45\",\n      delta: \"-8.0%\",\n      trend: \"down\",\n      good: true,\n      sub: \"Vs. Last Month\",\n    },\n  ],\n  \"apr-2026\": [\n    {\n      label: \"Monthly Revenue\",\n      value: \"$82,920\",\n      delta: \"+3.4%\",\n      trend: \"up\",\n      good: true,\n      sub: \"Vs. Last Month\",\n    },\n    {\n      label: \"New Signups\",\n      value: \"1,078\",\n      delta: \"+6.7%\",\n      trend: \"up\",\n      good: true,\n      sub: \"Vs. Last Month\",\n    },\n    {\n      label: \"Churn Rate\",\n      value: \"1.8%\",\n      delta: \"+0.3%\",\n      trend: \"up\",\n      good: false,\n      sub: \"Vs. Last Month\",\n    },\n    {\n      label: \"Support Tickets\",\n      value: \"49\",\n      delta: \"+4.2%\",\n      trend: \"up\",\n      good: false,\n      sub: \"Vs. Last Month\",\n    },\n  ],\n  \"q2-2026\": [\n    {\n      label: \"Quarterly Revenue\",\n      value: \"$264,370\",\n      delta: \"+6.0%\",\n      trend: \"up\",\n      good: true,\n      sub: \"Vs. Last Quarter\",\n    },\n    {\n      label: \"New Signups\",\n      value: \"3,759\",\n      delta: \"+14.1%\",\n      trend: \"up\",\n      good: true,\n      sub: \"Vs. Last Quarter\",\n    },\n    {\n      label: \"Churn Rate\",\n      value: \"1.7%\",\n      delta: \"+0.1%\",\n      trend: \"up\",\n      good: false,\n      sub: \"Vs. Last Quarter\",\n    },\n    {\n      label: \"Support Tickets\",\n      value: \"132\",\n      delta: \"-9.3%\",\n      trend: \"down\",\n      good: true,\n      sub: \"Vs. Last Quarter\",\n    },\n  ],\n}\n\nconst ACTIVITY = [\n  {\n    id: 1,\n    initials: \"SN\",\n    actor: \"Sofia N.\",\n    avatarSrc: \"https://i.pravatar.cc/40?img=47\",\n    action: \"exported the Q2 revenue report\",\n    timestamp: \"Just Now\",\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"FileText\"\n        tabler=\"IconFileText\"\n        hugeicons=\"File01Icon\"\n        phosphor=\"FileText\"\n        remixicon=\"RiFileTextLine\"\n        {...p}\n      />\n    ),\n    status: \"Completed\",\n    statusVariant: \"default\" as const,\n  },\n  {\n    id: 2,\n    initials: \"JP\",\n    actor: \"James P.\",\n    avatarSrc: \"https://i.pravatar.cc/40?img=12\",\n    action: \"invited two new team members\",\n    timestamp: \"12 Min Ago\",\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"UserPlus\"\n        tabler=\"IconUserPlus\"\n        hugeicons=\"UserAddIcon\"\n        phosphor=\"UserPlus\"\n        remixicon=\"RiUserAddLine\"\n        {...p}\n      />\n    ),\n    status: \"Pending\",\n    statusVariant: \"secondary\" as const,\n  },\n  {\n    id: 3,\n    initials: \"RL\",\n    actor: \"Riya L.\",\n    avatarSrc: \"https://i.pravatar.cc/40?img=32\",\n    action: \"resolved billing dispute #4821\",\n    timestamp: \"1 Hour Ago\",\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"Check\"\n        tabler=\"IconCheck\"\n        hugeicons=\"Tick02Icon\"\n        phosphor=\"Check\"\n        remixicon=\"RiCheckLine\"\n        {...p}\n      />\n    ),\n    status: \"Resolved\",\n    statusVariant: \"outline\" as const,\n  },\n  {\n    id: 4,\n    initials: \"MC\",\n    actor: \"Marco C.\",\n    avatarSrc: \"https://i.pravatar.cc/40?img=15\",\n    action: \"flagged an anomaly in usage metrics\",\n    timestamp: \"3 Hours Ago\",\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"CircleAlert\"\n        tabler=\"IconAlertCircle\"\n        hugeicons=\"AlertCircleIcon\"\n        phosphor=\"WarningCircle\"\n        remixicon=\"RiErrorWarningLine\"\n        {...p}\n      />\n    ),\n    status: \"Review\",\n    statusVariant: \"secondary\" as const,\n  },\n  {\n    id: 5,\n    initials: \"HK\",\n    actor: \"Hana K.\",\n    avatarSrc: \"https://i.pravatar.cc/40?img=48\",\n    action: \"scheduled the monthly all-hands\",\n    timestamp: \"Yesterday\",\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"Clock\"\n        tabler=\"IconClock\"\n        hugeicons=\"TimeIcon\"\n        phosphor=\"Clock\"\n        remixicon=\"RiTimeLine\"\n        {...p}\n      />\n    ),\n    status: \"Scheduled\",\n    statusVariant: \"outline\" as const,\n  },\n  {\n    id: 6,\n    initials: \"OB\",\n    actor: \"Owen B.\",\n    avatarSrc: \"https://i.pravatar.cc/40?img=53\",\n    action: \"published the July product changelog\",\n    timestamp: \"2 Days Ago\",\n    icon: (p: IconProps) => (\n      <IconPlaceholder\n        lucide=\"FileText\"\n        tabler=\"IconFileText\"\n        hugeicons=\"File01Icon\"\n        phosphor=\"FileText\"\n        remixicon=\"RiFileTextLine\"\n        {...p}\n      />\n    ),\n    status: \"Completed\",\n    statusVariant: \"default\" as const,\n  },\n]\n\nexport default function DashboardBlock() {\n  const [period, setPeriod] = React.useState(\"jun-2026\")\n  const stats = STATS_BY_PERIOD[period] ?? STATS_BY_PERIOD[\"jun-2026\"]\n\n  return (\n    <section className=\"flex w-full items-center justify-center bg-background px-6 py-12 text-foreground\">\n      <div className=\"mx-auto flex w-full max-w-4xl flex-col gap-8\">\n        <div className=\"flex items-start justify-between gap-4\">\n          <div className=\"flex flex-col gap-1\">\n            <h1 className=\"font-heading text-2xl font-bold tracking-tight\">\n              Dashboard\n            </h1>\n            <p className=\"text-sm text-muted-foreground\">\n              Welcome back, here&apos;s what&apos;s happening at Acme.\n            </p>\n          </div>\n          <Select\n            items={PERIODS}\n            value={period}\n            onValueChange={(v) => v && setPeriod(v)}\n          >\n            <SelectTrigger className=\"shrink-0\" aria-label=\"Reporting period\">\n              <IconPlaceholder\n                lucide=\"Calendar\"\n                tabler=\"IconCalendar\"\n                hugeicons=\"CalendarIcon\"\n                phosphor=\"Calendar\"\n                remixicon=\"RiCalendarLine\"\n                className=\"size-3.5\"\n                aria-hidden=\"true\"\n              />\n              <SelectValue />\n            </SelectTrigger>\n            <SelectContent>\n              {PERIODS.map((p) => (\n                <SelectItem key={p.value} value={p.value}>\n                  {p.label}\n                </SelectItem>\n              ))}\n            </SelectContent>\n          </Select>\n        </div>\n\n        <div className=\"grid grid-cols-1 gap-px overflow-hidden rounded-xl border border-border bg-border sm:grid-cols-2 md:grid-cols-4\">\n          {stats.map((stat) => (\n            <div\n              key={stat.label}\n              className=\"flex flex-col gap-4 bg-card px-5 py-5 transition-colors hover:bg-muted/40\"\n            >\n              <span className=\"text-xs font-medium tracking-widest text-muted-foreground uppercase\">\n                {stat.label}\n              </span>\n              <span className=\"text-3xl font-bold tracking-tight tabular-nums\">\n                {stat.value}\n              </span>\n              <div className=\"flex items-center gap-2\">\n                <span\n                  className={cn(\n                    \"inline-flex items-center gap-0.5 text-xs font-semibold\",\n                    stat.good ? \"text-foreground\" : \"text-muted-foreground\"\n                  )}\n                >\n                  {stat.trend === \"up\" ? (\n                    <IconPlaceholder\n                      lucide=\"ArrowUp\"\n                      tabler=\"IconArrowUp\"\n                      hugeicons=\"ArrowUpIcon\"\n                      phosphor=\"ArrowUp\"\n                      remixicon=\"RiArrowUpLine\"\n                      className=\"size-3.5\"\n                      aria-hidden=\"true\"\n                    />\n                  ) : (\n                    <IconPlaceholder\n                      lucide=\"ArrowDown\"\n                      tabler=\"IconArrowDown\"\n                      hugeicons=\"ArrowDownIcon\"\n                      phosphor=\"ArrowDown\"\n                      remixicon=\"RiArrowDownLine\"\n                      className=\"size-3.5\"\n                      aria-hidden=\"true\"\n                    />\n                  )}\n                  {stat.delta}\n                </span>\n                <span className=\"text-xs text-muted-foreground\">\n                  {stat.sub}\n                </span>\n              </div>\n            </div>\n          ))}\n        </div>\n\n        <Card className=\"overflow-hidden\">\n          <CardHeader className=\"border-b border-border pb-4\">\n            <div className=\"flex items-center justify-between gap-4\">\n              <div className=\"flex flex-col gap-0.5\">\n                <CardTitle className=\"text-base font-semibold\">\n                  Recent Activity\n                </CardTitle>\n                <CardDescription className=\"text-xs\">\n                  The latest actions taken across your workspace.\n                </CardDescription>\n              </div>\n              <Badge variant=\"secondary\" className=\"shrink-0 gap-1 text-xs\">\n                <span className=\"font-semibold tabular-nums\">\n                  {ACTIVITY.length}\n                </span>\n                Events\n              </Badge>\n            </div>\n          </CardHeader>\n          <CardContent className=\"p-0\">\n            <ul className=\"flex flex-col\">\n              {ACTIVITY.map((item, index) => {\n                const Icon = item.icon\n                return (\n                  <li key={item.id}>\n                    <div className=\"group flex items-center gap-4 px-6 py-3.5 transition-colors hover:bg-muted/40\">\n                      <Avatar size=\"sm\" className=\"shrink-0 ring-1 ring-border\">\n                        <AvatarImage\n                          src={item.avatarSrc}\n                          alt={item.actor}\n                          className=\"grayscale\"\n                        />\n                        <AvatarFallback className=\"text-xs font-medium\">\n                          {item.initials}\n                        </AvatarFallback>\n                      </Avatar>\n\n                      <div className=\"flex min-w-0 flex-1 flex-col gap-0.5 sm:flex-row sm:items-center sm:gap-1.5\">\n                        <span className=\"shrink-0 text-sm font-semibold text-foreground\">\n                          {item.actor}\n                        </span>\n                        <span className=\"truncate text-sm text-muted-foreground\">\n                          {item.action}\n                        </span>\n                      </div>\n\n                      <div className=\"flex shrink-0 items-center gap-3\">\n                        <Badge\n                          variant={item.statusVariant}\n                          className=\"hidden sm:flex\"\n                        >\n                          <Icon data-icon=\"inline-start\" aria-hidden=\"true\" />\n                          {item.status}\n                        </Badge>\n                        <span className=\"text-xs whitespace-nowrap text-muted-foreground\">\n                          {item.timestamp}\n                        </span>\n                      </div>\n                    </div>\n                    {index < ACTIVITY.length - 1 && <Separator />}\n                  </li>\n                )\n              })}\n            </ul>\n          </CardContent>\n        </Card>\n      </div>\n    </section>\n  )\n}\n",
      "type": "registry:component"
    }
  ],
  "meta": {
    "height": "794px",
    "tier": "free"
  },
  "categories": [
    "dashboard"
  ],
  "type": "registry:block"
}