{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "staff-banner",
  "type": "registry:component",
  "title": "Staff banner",
  "description": "Slim strip at the top of the content frame while Wibo staff are inside a Workspace.",
  "registryDependencies": [
    "@wibo/utils",
    "@wibo/button",
    "@wibo/app-shell"
  ],
  "files": [
    {
      "path": "src/shell/staff-banner.tsx",
      "type": "registry:component",
      "content": "import type { ComponentProps, ReactNode } from \"react\";\nimport { cn } from \"@/lib/utils\";\nimport { Button } from \"@/components/ui/button\";\nimport { useAppShell } from \"@/components/app-shell\";\n\ninterface StaffBannerProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n  /** Who is in: defaults to \"Wibo staff access\". */\n  label?: ReactNode;\n  /** Why the session exists (ticket, request). */\n  purpose: ReactNode;\n  /** When access ends. A `Date` is formatted with `locale` and `timeZone`; a string is shown as is. */\n  expiresAt?: Date | string;\n  expiresLabel?: string;\n  locale?: string;\n  /** The zone the expiry is read in. Pass it whenever the banner is server-rendered, so the server and the browser print the same time. */\n  timeZone?: string;\n  /** Link that ends the staff session. */\n  exitHref?: string;\n  /** Called instead of navigating when there is no `exitHref`. */\n  onExit?: () => void;\n  exitLabel?: string;\n  /** Disables the exit button while the exit runs. */\n  exiting?: boolean;\n  /** Further controls before the exit, for example a link back to the Admin Panel. */\n  actions?: ReactNode;\n}\n\n/**\n * Slim strip shown while Wibo staff are inside a client Workspace, at the\n * top of the content frame (`AppShell`'s `banner`): a pulsing warning dot,\n * who is in, why, until when, and the one way out. A state of the shell,\n * not an alert: the warning colour lives in the dot alone.\n */\nfunction StaffBanner({\n  label = \"Wibo staff access\",\n  purpose,\n  expiresAt,\n  expiresLabel = \"Expires\",\n  locale,\n  timeZone,\n  exitHref,\n  onExit,\n  exitLabel = \"Exit workspace\",\n  exiting = false,\n  actions,\n  className,\n  ...props\n}: StaffBannerProps) {\n  const { linkComponent: Link } = useAppShell();\n  const iso = expiresAt instanceof Date ? expiresAt.toISOString() : undefined;\n  const display =\n    expiresAt instanceof Date\n      ? new Intl.DateTimeFormat(locale, { dateStyle: \"medium\", timeStyle: \"short\", timeZone }).format(expiresAt)\n      : expiresAt;\n\n  return (\n    <div\n      data-slot=\"staff-banner\"\n      role=\"region\"\n      aria-label={typeof label === \"string\" ? label : \"Staff access\"}\n      className={cn(\n        \"flex min-h-10 shrink-0 flex-wrap items-center gap-x-3 gap-y-1.5 border-b border-border bg-card px-4 py-1.5 text-label text-foreground\",\n        className,\n      )}\n      {...props}\n    >\n      <span aria-hidden=\"true\" className=\"relative flex size-2 shrink-0\">\n        <span className=\"absolute inline-flex size-full animate-ping rounded-full bg-warning opacity-60 motion-reduce:hidden\" />\n        <span className=\"relative inline-flex size-2 rounded-full bg-warning\" />\n      </span>\n      <span className=\"font-medium\">{label}</span>\n      {/* On phones the purpose and the expiry take their own line under the label and the exit. */}\n      <span className=\"flex min-w-0 items-center gap-3 max-sm:order-last max-sm:basis-full sm:flex-1\">\n        <span className=\"min-w-0 flex-1 truncate text-muted-foreground\">{purpose}</span>\n        {display ? (\n          <span className=\"shrink-0 text-xs text-muted-foreground\">\n            {expiresLabel}{\" \"}\n            {/* Without a `timeZone` the runtime's zone applies, and the server's (UTC on Vercel) may differ from the browser's: that difference is expected. */}\n            <time dateTime={iso} className=\"font-mono text-foreground tabular-nums\" suppressHydrationWarning={timeZone === undefined}>\n              {display}\n            </time>\n          </span>\n        ) : null}\n      </span>\n      <span className=\"flex shrink-0 items-center gap-2 max-sm:ml-auto\">\n        {actions}\n        {exitHref ? (\n          <Button asChild variant=\"outline\" size=\"sm\">\n            <Link href={exitHref}>{exitLabel}</Link>\n          </Button>\n        ) : onExit ? (\n          <Button variant=\"outline\" size=\"sm\" loading={exiting} onClick={onExit}>\n            {exitLabel}\n          </Button>\n        ) : null}\n      </span>\n    </div>\n  );\n}\n\nexport { StaffBanner };\nexport type { StaffBannerProps };\n"
    }
  ]
}
