{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "access-request-workflow",
  "title": "Access Request Workflow",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/access-request-workflow/AccessRequestWorkflow.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport {\n  Check,\n  Clock,\n  Copy,\n  FileText,\n  History,\n  Hourglass,\n  KeyRound,\n  Lock,\n  MoreHorizontal,\n  Plus,\n  Search,\n  Send,\n  ShieldAlert,\n  ShieldCheck,\n  UserCheck,\n  X,\n} from 'lucide-react'\nimport { cn } from '@/lib/utils'\nimport { Avatar, AvatarFallback } from '@/components/ui/avatar'\nimport { Badge, type BadgeVariants } from '@/components/ui/badge'\nimport { Button } from '@/components/ui/button'\nimport { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card'\nimport {\n  Dialog,\n  DialogContent,\n  DialogDescription,\n  DialogFooter,\n  DialogHeader,\n  DialogTitle,\n  DialogTrigger,\n} from '@/components/ui/dialog'\nimport {\n  DropdownMenu,\n  DropdownMenuContent,\n  DropdownMenuItem,\n  DropdownMenuLabel,\n  DropdownMenuSeparator,\n  DropdownMenuTrigger,\n} from '@/components/ui/dropdown-menu'\nimport { Input } from '@/components/ui/input'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\nimport { Textarea } from '@/components/ui/textarea'\n\nexport interface AccessRequest {\n  id: string\n  requester: {\n    name: string\n    email: string\n    team: string\n    avatar: string\n  }\n  targetRole: string\n  system: string\n  duration: string\n  timeLeftLabel: string\n  secondsLeft: number\n  justification: string\n  ticketId: string\n  approver: string\n  status: 'active' | 'pending' | 'expired' | 'rejected'\n  createdAt: string\n  expiresAt: string\n}\n\nexport interface AccessRequestWorkflowProps {\n  title?: string\n  subtitle?: string\n  className?: string\n}\n\nconst initialRequests: AccessRequest[] = [\n  {\n    id: 'req-1',\n    requester: {\n      name: 'Elena Rostova',\n      email: 'elena.rostova@acme.corp',\n      team: 'SecOps Team',\n      avatar: 'ER',\n    },\n    targetRole: 'AWS Production Admin',\n    system: 'AWS Cloud IAM (us-east-1)',\n    duration: '4 Hours',\n    timeLeftLabel: '2h 45m left',\n    secondsLeft: 9918,\n    justification: 'Investigating latency spike on payment gateway for incident #SEC-849',\n    ticketId: 'SEC-849',\n    approver: 'Marcus Vance',\n    status: 'active',\n    createdAt: '1h 15m ago',\n    expiresAt: 'Today at 16:30',\n  },\n  {\n    id: 'req-2',\n    requester: {\n      name: 'Marcus Vance',\n      email: 'marcus.vance@acme.corp',\n      team: 'DevOps & Infra',\n      avatar: 'MV',\n    },\n    targetRole: 'Production DB Read-Only',\n    system: 'PostgreSQL Aurora Primary',\n    duration: '1 Hour (Emergency)',\n    timeLeftLabel: '48m left',\n    secondsLeft: 2892,\n    justification: 'Emergency replica query check during PostgreSQL failover testing',\n    ticketId: 'INC-2044',\n    approver: 'Sarah Chen',\n    status: 'active',\n    createdAt: '12m ago',\n    expiresAt: 'Today at 14:15',\n  },\n  {\n    id: 'req-3',\n    requester: {\n      name: 'Sarah Chen',\n      email: 'sarah.chen@acme.corp',\n      team: 'Core Platform',\n      avatar: 'SC',\n    },\n    targetRole: 'Customer PII Decryption',\n    system: 'Customer Data Vault (KMS)',\n    duration: '8 Hours (1 Shift)',\n    timeLeftLabel: 'Pending Approval',\n    secondsLeft: 28800,\n    justification: 'GDPR user deletion verification request #COMP-1102',\n    ticketId: 'COMP-1102',\n    approver: 'Marcus Vance',\n    status: 'pending',\n    createdAt: '10m ago',\n    expiresAt: 'Awaiting approval',\n  },\n  {\n    id: 'req-4',\n    requester: {\n      name: 'David Kim',\n      email: 'david.kim@acme.corp',\n      team: 'Fintech Systems',\n      avatar: 'DK',\n    },\n    targetRole: 'Stripe Dashboard Full Access',\n    system: 'Stripe Merchant Gateway',\n    duration: '1 Hour (Emergency)',\n    timeLeftLabel: 'Pending Approval',\n    secondsLeft: 3600,\n    justification: 'Refunding disputed charges for compromised merchant accounts',\n    ticketId: 'FIN-582',\n    approver: 'Marcus Vance',\n    status: 'pending',\n    createdAt: '25m ago',\n    expiresAt: 'Awaiting approval',\n  },\n  {\n    id: 'req-5',\n    requester: {\n      name: 'Alex Morgan',\n      email: 'alex.m@acme.corp',\n      team: 'Data Platform',\n      avatar: 'AM',\n    },\n    targetRole: 'Production DB Read-Only',\n    system: 'Snowflake Core Analytics',\n    duration: '4 Hours',\n    timeLeftLabel: 'Expired',\n    secondsLeft: 0,\n    justification: 'Quarterly compliance metrics export and audit schema migration verification',\n    ticketId: 'AUD-309',\n    approver: 'Elena Rostova',\n    status: 'expired',\n    createdAt: 'Yesterday',\n    expiresAt: 'Expired at 18:00',\n  },\n]\n\nfunction formatSeconds(seconds: number): string {\n  if (seconds <= 0) return '00:00:00'\n  const h = Math.floor(seconds / 3600)\n  const m = Math.floor((seconds % 3600) / 60)\n  const s = seconds % 60\n  return `${h.toString().padStart(2, '0')}:${m.toString().padStart(2, '0')}:${s.toString().padStart(2, '0')}`\n}\n\nfunction getRoleBadgeVariant(role: string): BadgeVariants['variant'] {\n  if (role.includes('AWS') || role.includes('Admin')) return 'destructive'\n  if (role.includes('PII') || role.includes('Decryption')) return 'warning'\n  if (role.includes('DB') || role.includes('Read-Only')) return 'info'\n  if (role.includes('Stripe')) return 'secondary'\n  return 'default'\n}\n\nexport function AccessRequestWorkflow({\n  title = 'Access Requests & Privilege Elevation',\n  subtitle = 'Request temporary Just-In-Time production access with audit approval.',\n  className,\n}: AccessRequestWorkflowProps) {\n  const [requests, setRequests] = React.useState<AccessRequest[]>(initialRequests)\n\n  // Timer ticker for active sessions\n  React.useEffect(() => {\n    const timer = setInterval(() => {\n      setRequests((prev) =>\n        prev.map((req) => {\n          if (req.status === 'active' && req.secondsLeft > 0) {\n            const nextSec = req.secondsLeft - 1\n            if (nextSec <= 0) {\n              return {\n                ...req,\n                secondsLeft: 0,\n                status: 'expired',\n                timeLeftLabel: 'Expired',\n              }\n            }\n            const h = Math.floor(nextSec / 3600)\n            const m = Math.floor((nextSec % 3600) / 60)\n            return {\n              ...req,\n              secondsLeft: nextSec,\n              timeLeftLabel: h > 0 ? `${h}h ${m}m left` : `${m}m left`,\n            }\n          }\n          return req\n        }),\n      )\n    }, 1000)\n\n    return () => clearInterval(timer)\n  }, [])\n\n  // Governance KPI stats\n  const activeCount = React.useMemo(() => requests.filter((r) => r.status === 'active').length, [requests])\n  const pendingCount = React.useMemo(() => requests.filter((r) => r.status === 'pending').length, [requests])\n  const expiringCount = React.useMemo(\n    () => requests.filter((r) => r.status === 'active' && r.secondsLeft <= 3600 * 4).length,\n    [requests],\n  )\n  const total30Day = React.useMemo(() => 42 + requests.filter((r) => r.id.startsWith('req-custom')).length, [requests])\n\n  // Modal Form State\n  const [isDialogOpen, setIsDialogOpen] = React.useState(false)\n  const [formRole, setFormRole] = React.useState('AWS Production Admin')\n  const [formDuration, setFormDuration] = React.useState('4 Hours')\n  const [formApprover, setFormApprover] = React.useState('Security Lead: Marcus Vance')\n  const [formJustification, setFormJustification] = React.useState(\n    'Investigating latency spike on payment gateway for incident #SEC-849',\n  )\n\n  const handleCreateRequest = (e: React.FormEvent) => {\n    e.preventDefault()\n    if (!formJustification.trim()) return\n\n    let seconds = 3600 * 4\n    if (formDuration.includes('1 Hour')) seconds = 3600\n    else if (formDuration.includes('8 Hours')) seconds = 3600 * 8\n    else if (formDuration.includes('24 Hours')) seconds = 3600 * 24\n\n    let system = 'AWS Cloud IAM (us-east-1)'\n    if (formRole.includes('DB')) system = 'PostgreSQL Aurora Primary'\n    else if (formRole.includes('Stripe')) system = 'Stripe Merchant Gateway'\n    else if (formRole.includes('PII')) system = 'Customer Data Vault (KMS)'\n\n    const newReq: AccessRequest = {\n      id: `req-custom-${Date.now()}`,\n      requester: {\n        name: 'Current Operator (You)',\n        email: 'operator@acme.corp',\n        team: 'Platform Engineering',\n        avatar: 'OP',\n      },\n      targetRole: formRole,\n      system,\n      duration: formDuration,\n      timeLeftLabel: 'Pending Approval',\n      secondsLeft: seconds,\n      justification: formJustification,\n      ticketId: `SEC-${Math.floor(100 + Math.random() * 900)}`,\n      approver: formApprover,\n      status: 'pending',\n      createdAt: 'Just now',\n      expiresAt: 'Awaiting approval',\n    }\n\n    setRequests((prev) => [newReq, ...prev])\n    setIsDialogOpen(false)\n  }\n\n  // Table Filters\n  const [selectedTab, setSelectedTab] = React.useState<'all' | 'pending' | 'active' | 'expired'>('all')\n  const [searchQuery, setSearchQuery] = React.useState('')\n\n  const filteredRequests = React.useMemo(() => {\n    return requests.filter((req) => {\n      if (selectedTab !== 'all' && req.status !== selectedTab) {\n        return false\n      }\n      if (searchQuery.trim()) {\n        const q = searchQuery.toLowerCase()\n        const matchName = req.requester.name.toLowerCase().includes(q)\n        const matchRole = req.targetRole.toLowerCase().includes(q)\n        const matchTicket = req.ticketId.toLowerCase().includes(q)\n        const matchJust = req.justification.toLowerCase().includes(q)\n        const matchSys = req.system.toLowerCase().includes(q)\n        if (!matchName && !matchRole && !matchTicket && !matchJust && !matchSys) {\n          return false\n        }\n      }\n      return true\n    })\n  }, [requests, selectedTab, searchQuery])\n\n  // Manager Actions\n  const handleApprove = (id: string) => {\n    setRequests((prev) =>\n      prev.map((req) => {\n        if (req.id === id) {\n          const h = Math.floor(req.secondsLeft / 3600)\n          const m = Math.floor((req.secondsLeft % 3600) / 60)\n          return {\n            ...req,\n            status: 'active',\n            timeLeftLabel: h > 0 ? `${h}h ${m}m left` : `${m}m left`,\n          }\n        }\n        return req\n      }),\n    )\n  }\n\n  const handleReject = (id: string) => {\n    setRequests((prev) =>\n      prev.map((req) => {\n        if (req.id === id) {\n          return {\n            ...req,\n            status: 'rejected',\n            timeLeftLabel: 'Rejected',\n          }\n        }\n        return req\n      }),\n    )\n  }\n\n  const handleRevoke = (id: string) => {\n    setRequests((prev) =>\n      prev.map((req) => {\n        if (req.id === id) {\n          return {\n            ...req,\n            status: 'expired',\n            secondsLeft: 0,\n            timeLeftLabel: 'Revoked',\n          }\n        }\n        return req\n      }),\n    )\n  }\n\n  const handleExtend = (id: string) => {\n    setRequests((prev) =>\n      prev.map((req) => {\n        if (req.id === id && req.status === 'active') {\n          const nextSec = req.secondsLeft + 1800\n          const h = Math.floor(nextSec / 3600)\n          const m = Math.floor((nextSec % 3600) / 60)\n          return {\n            ...req,\n            secondsLeft: nextSec,\n            timeLeftLabel: h > 0 ? `${h}h ${m}m left` : `${m}m left`,\n          }\n        }\n        return req\n      }),\n    )\n  }\n\n  const handleReRequest = (id: string) => {\n    setRequests((prev) =>\n      prev.map((req) => {\n        if (req.id === id) {\n          return {\n            ...req,\n            status: 'pending',\n            timeLeftLabel: 'Pending Approval',\n            secondsLeft: 3600 * 4,\n          }\n        }\n        return req\n      }),\n    )\n  }\n\n  const [copiedId, setCopiedId] = React.useState<string | null>(null)\n  const handleCopyToken = (id: string) => {\n    setCopiedId(id)\n    setTimeout(() => {\n      setCopiedId((prev) => (prev === id ? null : prev))\n    }, 2000)\n  }\n\n  return (\n    <div data-slot=\"access-request-workflow\" className={cn('flex flex-col gap-6', className)}>\n      {/* Header */}\n      <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n        <div>\n          <div className=\"flex items-center gap-2\">\n            <div className=\"bg-primary/10 text-primary flex size-9 items-center justify-center rounded-lg\">\n              <KeyRound className=\"size-5\" />\n            </div>\n            <h1 className=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">{title}</h1>\n          </div>\n          <p className=\"text-muted-foreground mt-1 text-sm\">{subtitle}</p>\n        </div>\n\n        {/* Request New Access Modal Dialog */}\n        <Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>\n          <DialogTrigger asChild>\n            <Button className=\"shrink-0 gap-2 shadow-xs\">\n              <Plus className=\"size-4\" />\n              Request New Access\n            </Button>\n          </DialogTrigger>\n          <DialogContent className=\"sm:max-w-lg\">\n            <DialogHeader>\n              <DialogTitle className=\"flex items-center gap-2\">\n                <ShieldAlert className=\"text-primary size-5\" />\n                Request Temporary Access\n              </DialogTitle>\n              <DialogDescription>\n                Submit a Just-In-Time (JIT) access request with duration and business justification.\n              </DialogDescription>\n            </DialogHeader>\n\n            <form className=\"space-y-4 py-2\" onSubmit={handleCreateRequest}>\n              <div className=\"space-y-1.5\">\n                <label className=\"text-foreground text-xs font-medium\">Target System / Role</label>\n                <Select value={formRole} onValueChange={setFormRole}>\n                  <SelectTrigger className=\"w-full\">\n                    <SelectValue placeholder=\"Select target role\" />\n                  </SelectTrigger>\n                  <SelectContent>\n                    <SelectItem value=\"Production DB Read-Only\">Production DB Read-Only</SelectItem>\n                    <SelectItem value=\"AWS Production Admin\">AWS Production Admin</SelectItem>\n                    <SelectItem value=\"Stripe Dashboard Full Access\">Stripe Dashboard Full Access</SelectItem>\n                    <SelectItem value=\"Customer PII Decryption\">Customer PII Decryption</SelectItem>\n                  </SelectContent>\n                </Select>\n              </div>\n\n              <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n                <div className=\"space-y-1.5\">\n                  <label className=\"text-foreground text-xs font-medium\">Access Duration</label>\n                  <Select value={formDuration} onValueChange={setFormDuration}>\n                    <SelectTrigger className=\"w-full\">\n                      <SelectValue placeholder=\"Select duration\" />\n                    </SelectTrigger>\n                    <SelectContent>\n                      <SelectItem value=\"1 Hour (Emergency)\">1 Hour (Emergency)</SelectItem>\n                      <SelectItem value=\"4 Hours\">4 Hours</SelectItem>\n                      <SelectItem value=\"8 Hours (1 Shift)\">8 Hours (1 Shift)</SelectItem>\n                      <SelectItem value=\"24 Hours max\">24 Hours max</SelectItem>\n                    </SelectContent>\n                  </Select>\n                </div>\n\n                <div className=\"space-y-1.5\">\n                  <label className=\"text-foreground text-xs font-medium\">Approver / Team</label>\n                  <Select value={formApprover} onValueChange={setFormApprover}>\n                    <SelectTrigger className=\"w-full\">\n                      <SelectValue placeholder=\"Select approver\" />\n                    </SelectTrigger>\n                    <SelectContent>\n                      <SelectItem value=\"Security Lead: Marcus Vance\">Security Lead: Marcus Vance</SelectItem>\n                      <SelectItem value=\"Infrastructure Team: Sarah Chen\">Infrastructure Team: Sarah Chen</SelectItem>\n                      <SelectItem value=\"Compliance Officer: Elena Rostova\">\n                        Compliance Officer: Elena Rostova\n                      </SelectItem>\n                      <SelectItem value=\"On-Call Lead: David Kim\">On-Call Lead: David Kim</SelectItem>\n                    </SelectContent>\n                  </Select>\n                </div>\n              </div>\n\n              <div className=\"space-y-1.5\">\n                <label className=\"text-foreground text-xs font-medium\">Business Justification</label>\n                <Textarea\n                  value={formJustification}\n                  onValueChange={(v) => setFormJustification(v)}\n                  placeholder=\"Investigating latency spike on payment gateway for incident #SEC-849\"\n                  rows={3}\n                  className=\"resize-none text-xs\"\n                />\n                <p className=\"text-muted-foreground text-xs\">\n                  All elevated actions are recorded and signed in the immutable IAM audit stream.\n                </p>\n              </div>\n\n              <DialogFooter className=\"pt-2\">\n                <Button type=\"button\" variant=\"outline\" onClick={() => setIsDialogOpen(false)}>\n                  Cancel\n                </Button>\n                <Button type=\"submit\" className=\"gap-2\">\n                  <Send className=\"size-4\" />\n                  Submit Request\n                </Button>\n              </DialogFooter>\n            </form>\n          </DialogContent>\n        </Dialog>\n      </div>\n\n      {/* 4 Access Governance KPI Cards */}\n      <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n        <Card className=\"border-border/80 relative overflow-hidden shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Active Elevated Sessions</CardTitle>\n            <div className=\"bg-success/10 text-success rounded-md p-1.5\">\n              <ShieldAlert className=\"size-4\" />\n            </div>\n          </CardHeader>\n          <CardContent>\n            <div className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">{activeCount}</div>\n            <p className=\"text-muted-foreground mt-1 text-xs\">Expiring within 8h</p>\n          </CardContent>\n        </Card>\n\n        <Card className=\"border-border/80 relative overflow-hidden shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Pending Approvals</CardTitle>\n            <div className=\"bg-warning/10 text-warning rounded-md p-1.5\">\n              <Clock className=\"size-4\" />\n            </div>\n          </CardHeader>\n          <CardContent>\n            <div className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">{pendingCount}</div>\n            <p className=\"text-muted-foreground mt-1 text-xs\">Requires security lead review</p>\n          </CardContent>\n        </Card>\n\n        <Card className=\"border-border/80 relative overflow-hidden shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">Requests Expiring Today</CardTitle>\n            <div className=\"bg-chart-1/10 text-chart-1 rounded-md p-1.5\">\n              <Hourglass className=\"size-4\" />\n            </div>\n          </CardHeader>\n          <CardContent>\n            <div className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">{expiringCount}</div>\n            <p className=\"text-muted-foreground mt-1 text-xs\">Auto-revocation armed</p>\n          </CardContent>\n        </Card>\n\n        <Card className=\"border-border/80 relative overflow-hidden shadow-xs\">\n          <CardHeader className=\"flex flex-row items-center justify-between pb-2\">\n            <CardTitle className=\"text-muted-foreground text-xs font-medium\">30-Day Total Requests</CardTitle>\n            <div className=\"bg-primary/10 text-primary rounded-md p-1.5\">\n              <History className=\"size-4\" />\n            </div>\n          </CardHeader>\n          <CardContent>\n            <div className=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">{total30Day}</div>\n            <p className=\"text-muted-foreground mt-1 text-xs\">98.2% compliance audit pass</p>\n          </CardContent>\n        </Card>\n      </div>\n\n      {/* Pending & Active Requests Table Card */}\n      <Card className=\"border-border/80 shadow-xs\">\n        <CardHeader className=\"border-border/60 border-b pb-4\">\n          <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n            <div>\n              <CardTitle className=\"text-foreground text-base font-semibold\">Privilege Escalation Queue</CardTitle>\n              <CardDescription className=\"text-muted-foreground mt-0.5 text-xs\">\n                Review, approve, or reject active and pending privilege requests.\n              </CardDescription>\n            </div>\n\n            <div className=\"flex flex-col gap-2 sm:flex-row sm:items-center\">\n              {/* Search */}\n              <div className=\"relative w-full sm:w-60\">\n                <Search className=\"text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2\" />\n                <Input\n                  value={searchQuery}\n                  onChange={(e) => setSearchQuery(e.target.value)}\n                  placeholder=\"Search requester, role, ticket...\"\n                  className=\"h-8 pl-8 text-xs\"\n                />\n              </div>\n\n              {/* Filter Tabs */}\n              <div className=\"border-border bg-muted/40 flex items-center rounded-lg border p-0.5\">\n                <button\n                  type=\"button\"\n                  className={cn(\n                    'rounded-md px-2.5 py-1 text-xs font-medium transition-colors',\n                    selectedTab === 'all'\n                      ? 'bg-background text-foreground shadow-xs'\n                      : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setSelectedTab('all')}\n                >\n                  All ({requests.length})\n                </button>\n                <button\n                  type=\"button\"\n                  className={cn(\n                    'rounded-md px-2.5 py-1 text-xs font-medium transition-colors',\n                    selectedTab === 'pending'\n                      ? 'bg-background text-foreground shadow-xs'\n                      : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setSelectedTab('pending')}\n                >\n                  Pending ({pendingCount})\n                </button>\n                <button\n                  type=\"button\"\n                  className={cn(\n                    'rounded-md px-2.5 py-1 text-xs font-medium transition-colors',\n                    selectedTab === 'active'\n                      ? 'bg-background text-foreground shadow-xs'\n                      : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setSelectedTab('active')}\n                >\n                  Active ({activeCount})\n                </button>\n                <button\n                  type=\"button\"\n                  className={cn(\n                    'rounded-md px-2.5 py-1 text-xs font-medium transition-colors',\n                    selectedTab === 'expired'\n                      ? 'bg-background text-foreground shadow-xs'\n                      : 'text-muted-foreground hover:text-foreground',\n                  )}\n                  onClick={() => setSelectedTab('expired')}\n                >\n                  Expired ({requests.filter((r) => r.status === 'expired' || r.status === 'rejected').length})\n                </button>\n              </div>\n            </div>\n          </div>\n        </CardHeader>\n\n        <CardContent className=\"p-0\">\n          <div className=\"overflow-x-auto\">\n            <Table>\n              <TableHeader>\n                <TableRow className=\"hover:bg-transparent\">\n                  <TableHead className=\"w-[220px] text-xs font-medium\">Requester</TableHead>\n                  <TableHead className=\"w-[200px] text-xs font-medium\">Target Role & System</TableHead>\n                  <TableHead className=\"w-[170px] text-xs font-medium\">Duration & Timer</TableHead>\n                  <TableHead className=\"min-w-[260px] text-xs font-medium\">Business Justification</TableHead>\n                  <TableHead className=\"w-[180px] text-xs font-medium\">Status</TableHead>\n                  <TableHead className=\"w-[160px] text-right text-xs font-medium\">Actions</TableHead>\n                </TableRow>\n              </TableHeader>\n              <TableBody>\n                {filteredRequests.length === 0 ? (\n                  <TableRow>\n                    <TableCell colSpan={6} className=\"text-muted-foreground h-32 text-center text-xs\">\n                      No access requests match your filter.\n                    </TableCell>\n                  </TableRow>\n                ) : (\n                  filteredRequests.map((req) => (\n                    <TableRow key={req.id} className=\"hover:bg-muted/30 transition-colors\">\n                      {/* Requester */}\n                      <TableCell>\n                        <div className=\"flex items-center gap-3\">\n                          <Avatar className=\"border-border/60 size-8 border\">\n                            <AvatarFallback className=\"bg-muted text-foreground text-xs font-semibold\">\n                              {req.requester.avatar}\n                            </AvatarFallback>\n                          </Avatar>\n                          <div className=\"min-w-0\">\n                            <div className=\"text-foreground truncate text-xs font-medium\">{req.requester.name}</div>\n                            <div className=\"text-muted-foreground truncate text-xs\">{req.requester.email}</div>\n                          </div>\n                        </div>\n                      </TableCell>\n\n                      {/* Target Role & System */}\n                      <TableCell>\n                        <div className=\"flex flex-col gap-1\">\n                          <Badge variant={getRoleBadgeVariant(req.targetRole)} className=\"w-fit text-xs font-medium\">\n                            {req.targetRole}\n                          </Badge>\n                          <span className=\"text-muted-foreground truncate text-xs\">{req.system}</span>\n                        </div>\n                      </TableCell>\n\n                      {/* Duration & Timer */}\n                      <TableCell>\n                        <div className=\"flex flex-col gap-1\">\n                          <span className=\"text-foreground text-xs font-medium\">{req.duration}</span>\n                          {req.status === 'active' ? (\n                            <div className=\"text-success text-success flex items-center gap-1.5 font-mono text-xs tabular-nums\">\n                              <Clock className=\"size-3 shrink-0\" />\n                              <span>{formatSeconds(req.secondsLeft)}</span>\n                            </div>\n                          ) : req.status === 'pending' ? (\n                            <div className=\"text-muted-foreground flex items-center gap-1.5 font-mono text-xs tabular-nums\">\n                              <Clock className=\"size-3 shrink-0\" />\n                              <span>Awaiting start</span>\n                            </div>\n                          ) : (\n                            <div className=\"text-muted-foreground flex items-center gap-1.5 font-mono text-xs tabular-nums\">\n                              <Clock className=\"size-3 shrink-0\" />\n                              <span>Session ended</span>\n                            </div>\n                          )}\n                        </div>\n                      </TableCell>\n\n                      {/* Business Justification */}\n                      <TableCell>\n                        <div className=\"flex flex-col gap-1\">\n                          <div className=\"flex items-center gap-1.5\">\n                            <span className=\"border-border bg-muted/60 text-foreground inline-flex items-center rounded border px-1.5 py-0.5 font-mono text-xs font-medium\">\n                              #{req.ticketId}\n                            </span>\n                            <span className=\"text-muted-foreground text-xs\">\n                              Approver:{' '}\n                              {req.approver\n                                .replace('Security Lead: ', '')\n                                .replace('Infrastructure Team: ', '')\n                                .replace('Compliance Officer: ', '')\n                                .replace('On-Call Lead: ', '')}\n                            </span>\n                          </div>\n                          <p className=\"text-muted-foreground line-clamp-2 text-xs\" title={req.justification}>\n                            {req.justification}\n                          </p>\n                        </div>\n                      </TableCell>\n\n                      {/* Status Badge */}\n                      <TableCell>\n                        <div className=\"flex items-center\">\n                          {req.status === 'active' ? (\n                            <Badge variant=\"success\" className=\"gap-1.5 text-xs font-medium\">\n                              <span className=\"relative flex size-2\">\n                                <span className=\"bg-success absolute inline-flex h-full w-full rounded-full opacity-75\" />\n                                <span className=\"bg-success relative inline-flex size-2 rounded-full\" />\n                              </span>\n                              <span>Active - {req.timeLeftLabel}</span>\n                            </Badge>\n                          ) : req.status === 'pending' ? (\n                            <Badge variant=\"warning\" className=\"gap-1.5 text-xs font-medium\">\n                              <span className=\"bg-warning size-2 animate-pulse rounded-full\" />\n                              <span>Pending Approval</span>\n                            </Badge>\n                          ) : req.status === 'expired' ? (\n                            <Badge variant=\"secondary\" className=\"text-muted-foreground gap-1.5 text-xs font-normal\">\n                              <span className=\"bg-muted-foreground/50 size-2 rounded-full\" />\n                              <span>Expired</span>\n                            </Badge>\n                          ) : (\n                            <Badge variant=\"destructive\" className=\"gap-1.5 text-xs font-normal\">\n                              <span className=\"bg-destructive size-2 rounded-full\" />\n                              <span>Rejected</span>\n                            </Badge>\n                          )}\n                        </div>\n                      </TableCell>\n\n                      {/* Actions */}\n                      <TableCell className=\"text-right\">\n                        <div className=\"flex items-center justify-end gap-1.5\">\n                          {/* Pending Actions */}\n                          {req.status === 'pending' && (\n                            <>\n                              <Button\n                                size=\"sm\"\n                                className=\"h-7 gap-1 px-2.5 text-xs shadow-xs\"\n                                onClick={() => handleApprove(req.id)}\n                              >\n                                <Check className=\"size-3.5\" />\n                                Approve\n                              </Button>\n                              <Button\n                                size=\"sm\"\n                                variant=\"outline\"\n                                className=\"text-destructive hover:bg-destructive/10 hover:text-destructive h-7 gap-1 px-2 text-xs\"\n                                onClick={() => handleReject(req.id)}\n                              >\n                                <X className=\"size-3.5\" />\n                                Reject\n                              </Button>\n                            </>\n                          )}\n\n                          {/* Active Actions */}\n                          {req.status === 'active' && (\n                            <>\n                              <Button\n                                size=\"sm\"\n                                variant=\"outline\"\n                                className=\"text-destructive border-destructive/30 hover:bg-destructive/10 hover:text-destructive h-7 gap-1 px-2 text-xs\"\n                                onClick={() => handleRevoke(req.id)}\n                              >\n                                <Lock className=\"size-3.5\" />\n                                Revoke\n                              </Button>\n\n                              <DropdownMenu>\n                                <DropdownMenuTrigger asChild>\n                                  <Button variant=\"ghost\" size=\"icon\" className=\"size-7\">\n                                    <MoreHorizontal className=\"size-3.5\" />\n                                    <span className=\"sr-only\">More actions</span>\n                                  </Button>\n                                </DropdownMenuTrigger>\n                                <DropdownMenuContent align=\"end\" className=\"w-48\">\n                                  <DropdownMenuLabel className=\"text-xs\">Elevated Session</DropdownMenuLabel>\n                                  <DropdownMenuSeparator />\n                                  <DropdownMenuItem onClick={() => handleExtend(req.id)}>\n                                    <Clock className=\"mr-2 size-3.5\" />\n                                    Extend 30 Minutes\n                                  </DropdownMenuItem>\n                                  <DropdownMenuItem onClick={() => handleCopyToken(req.id)}>\n                                    <Copy className=\"mr-2 size-3.5\" />\n                                    {copiedId === req.id ? 'Copied Token!' : 'Copy Token'}\n                                  </DropdownMenuItem>\n                                  <DropdownMenuSeparator />\n                                  <DropdownMenuItem\n                                    className=\"text-destructive focus:text-destructive\"\n                                    onClick={() => handleRevoke(req.id)}\n                                  >\n                                    <ShieldAlert className=\"mr-2 size-3.5\" />\n                                    Revoke Immediately\n                                  </DropdownMenuItem>\n                                </DropdownMenuContent>\n                              </DropdownMenu>\n                            </>\n                          )}\n\n                          {/* Expired / Rejected Actions */}\n                          {req.status !== 'pending' && req.status !== 'active' && (\n                            <>\n                              <Button\n                                size=\"sm\"\n                                variant=\"ghost\"\n                                className=\"text-muted-foreground hover:text-foreground h-7 px-2 text-xs\"\n                                onClick={() => handleReRequest(req.id)}\n                              >\n                                Re-request\n                              </Button>\n\n                              <DropdownMenu>\n                                <DropdownMenuTrigger asChild>\n                                  <Button variant=\"ghost\" size=\"icon\" className=\"size-7\">\n                                    <MoreHorizontal className=\"size-3.5\" />\n                                    <span className=\"sr-only\">More actions</span>\n                                  </Button>\n                                </DropdownMenuTrigger>\n                                <DropdownMenuContent align=\"end\" className=\"w-44\">\n                                  <DropdownMenuItem onClick={() => handleReRequest(req.id)}>\n                                    <History className=\"mr-2 size-3.5\" />\n                                    Request Again\n                                  </DropdownMenuItem>\n                                  <DropdownMenuItem>\n                                    <FileText className=\"mr-2 size-3.5\" />\n                                    View Audit Log\n                                  </DropdownMenuItem>\n                                </DropdownMenuContent>\n                              </DropdownMenu>\n                            </>\n                          )}\n                        </div>\n                      </TableCell>\n                    </TableRow>\n                  ))\n                )}\n              </TableBody>\n            </Table>\n          </div>\n        </CardContent>\n      </Card>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/AccessRequestWorkflow.tsx"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/avatar.json",
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/dialog.json",
    "https://uipkge.dev/r/react/dropdown-menu.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/select.json",
    "https://uipkge.dev/r/react/table.json",
    "https://uipkge.dev/r/react/textarea.json"
  ],
  "description": "Just-In-Time (JIT) IAM temporary privilege escalation request modal and approval queue: governance metrics cards, elevated session countdown timers, approval form dialog, and active session manager with instant revoke and audit logging.",
  "categories": [
    "security",
    "iam",
    "dashboard"
  ]
}