{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "purchase-order-receiving",
  "title": "Purchase Order Receiving",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-react/blocks/purchase-order-receiving/PurchaseOrderReceiving.tsx",
      "content": "'use client'\n\nimport * as React from 'react'\nimport { AlertTriangle, Clock, PackageCheck, Printer, ShieldCheck, Warehouse } from 'lucide-react'\nimport { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card'\nimport { Button } from '@/components/ui/button'\nimport { Input } from '@/components/ui/input'\nimport { Badge } from '@/components/ui/badge'\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'\nimport { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table'\n\nexport interface POLineItem {\n  id: string\n  sku: string\n  title: string\n  orderedQty: number\n  receivedQty: number\n  rejectedQty: number\n  rejectionReason: 'none' | 'damaged_packaging' | 'expired_lot' | 'wrong_specification' | 'temperature_excursion'\n  lotNumber: string\n  expiryDate: string\n  stagingLocation: string\n}\n\nexport interface PurchaseOrderReceivingProps {\n  poNumber?: string\n  vendorName?: string\n  deliveryDocket?: string\n  className?: string\n}\n\nexport function PurchaseOrderReceiving({\n  poNumber = 'PO-2026-4409',\n  vendorName = 'Apex Precision Engineering Ltd',\n  deliveryDocket = 'BOL-APX-98214',\n  className,\n}: PurchaseOrderReceivingProps) {\n  const [isCompleted, setIsCompleted] = React.useState(false)\n  const [receivingDock, setReceivingDock] = React.useState('dock-03')\n  const [inspectionStatus, setInspectionStatus] = React.useState<'pending' | 'passed' | 'discrepancy'>('pending')\n\n  const [lines, setLines] = React.useState<POLineItem[]>([\n    {\n      id: 'po-1',\n      sku: 'SKU-VALVE-99',\n      title: 'High-Pressure Hydraulic Valve 3/8\"',\n      orderedQty: 100,\n      receivedQty: 100,\n      rejectedQty: 0,\n      rejectionReason: 'none',\n      lotNumber: 'LOT-HYD-998',\n      expiryDate: '2029-12-31',\n      stagingLocation: 'ZONE-A-RACK-04',\n    },\n    {\n      id: 'po-2',\n      sku: 'SKU-SEAL-04',\n      title: 'Fluorocarbon O-Ring Flange Kit (Pack of 50)',\n      orderedQty: 250,\n      receivedQty: 245,\n      rejectedQty: 5,\n      rejectionReason: 'damaged_packaging',\n      lotNumber: 'LOT-O-7712',\n      expiryDate: '2028-06-30',\n      stagingLocation: 'ZONE-A-RACK-01',\n    },\n    {\n      id: 'po-3',\n      sku: 'SKU-GAUGE-12',\n      title: 'Digital Calibration Pressure Gauge 0-600 PSI',\n      orderedQty: 40,\n      receivedQty: 40,\n      rejectedQty: 0,\n      rejectionReason: 'none',\n      lotNumber: 'LOT-CAL-002',\n      expiryDate: '2031-01-15',\n      stagingLocation: 'ZONE-B-RACK-09',\n    },\n  ])\n\n  const totalOrdered = lines.reduce((acc, item) => acc + item.orderedQty, 0)\n  const totalAccepted = lines.reduce((acc, item) => acc + item.receivedQty, 0)\n  const totalRejected = lines.reduce((acc, item) => acc + item.rejectedQty, 0)\n\n  function updateLine(id: string, updates: Partial<POLineItem>) {\n    setLines((prev) => prev.map((line) => (line.id === id ? { ...line, ...updates } : line)))\n  }\n\n  function finalizeReceipt() {\n    if (totalRejected > 0 || totalAccepted < totalOrdered) {\n      setInspectionStatus('discrepancy')\n    } else {\n      setInspectionStatus('passed')\n    }\n    setIsCompleted(true)\n  }\n\n  function resetReceipt() {\n    setIsCompleted(false)\n    setInspectionStatus('pending')\n  }\n\n  return (\n    <div data-slot=\"purchase-order-receiving\" className={`w-full space-y-6 ${className ?? ''}`}>\n      {/* Top PO Header Info */}\n      <Card>\n        <CardHeader className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n          <div className=\"space-y-1\">\n            <div className=\"flex items-center gap-2\">\n              <span className=\"text-foreground font-mono text-sm font-semibold\">{poNumber}</span>\n              <Badge variant=\"outline\" className=\"font-mono text-xs\">\n                {deliveryDocket}\n              </Badge>\n              <Badge\n                variant={\n                  inspectionStatus === 'passed'\n                    ? 'default'\n                    : inspectionStatus === 'discrepancy'\n                      ? 'destructive'\n                      : 'secondary'\n                }\n                className=\"capitalize\"\n              >\n                {isCompleted ? `GRN ${inspectionStatus}` : 'Receiving in Progress'}\n              </Badge>\n            </div>\n            <CardTitle className=\"text-xl\">Inbound Goods Receipt & QA Inspection</CardTitle>\n            <CardDescription>\n              Supplier: <strong className=\"text-foreground font-medium\">{vendorName}</strong> · Inbound Dock\n              Verification\n            </CardDescription>\n          </div>\n\n          <div className=\"flex items-center gap-2\">\n            <Button variant=\"outline\" size=\"sm\" className=\"gap-1.5\">\n              <Printer className=\"size-4\" />\n              Print Putaway Labels\n            </Button>\n            {!isCompleted ? (\n              <Button variant=\"default\" size=\"sm\" className=\"gap-1.5\" onClick={finalizeReceipt}>\n                <PackageCheck className=\"size-4\" />\n                Generate GRN\n              </Button>\n            ) : (\n              <Button variant=\"secondary\" size=\"sm\" className=\"gap-1.5\" onClick={resetReceipt}>\n                Edit Receipt\n              </Button>\n            )}\n          </div>\n        </CardHeader>\n\n        <CardContent className=\"border-border grid grid-cols-1 gap-4 border-t pt-4 sm:grid-cols-3\">\n          {/* Receiving Dock */}\n          <div className=\"border-border space-y-1.5 rounded-lg border p-3\">\n            <div className=\"text-muted-foreground flex items-center gap-1.5 text-xs font-medium\">\n              <Warehouse className=\"size-3.5\" />\n              <span>RECEIVING BAY</span>\n            </div>\n            <Select value={receivingDock} onValueChange={setReceivingDock} disabled={isCompleted}>\n              <SelectTrigger className=\"w-full\">\n                <SelectValue />\n              </SelectTrigger>\n              <SelectContent>\n                <SelectItem value=\"dock-01\">Inbound Dock Bay 01 (Heavy Freight)</SelectItem>\n                <SelectItem value=\"dock-02\">Inbound Dock Bay 02 (Cross-Dock)</SelectItem>\n                <SelectItem value=\"dock-03\">Inbound Dock Bay 03 (Standard Freight)</SelectItem>\n                <SelectItem value=\"dock-04\">Inbound Cold Storage Quarantine Bay</SelectItem>\n              </SelectContent>\n            </Select>\n          </div>\n\n          {/* Discrepancy Summary */}\n          <div className=\"border-border space-y-1 rounded-lg border p-3\">\n            <div className=\"text-muted-foreground text-xs font-medium\">RECEIPT SUMMARY</div>\n            <div className=\"flex items-baseline justify-between pt-1\">\n              <div className=\"font-mono text-xl font-semibold\">\n                {totalAccepted} / {totalOrdered}\n              </div>\n              {totalRejected > 0 ? (\n                <Badge variant=\"destructive\" className=\"font-mono text-xs\">\n                  {totalRejected} Rejected\n                </Badge>\n              ) : (\n                <Badge variant=\"outline\" className=\"text-muted-foreground font-mono text-xs\">\n                  100% Match\n                </Badge>\n              )}\n            </div>\n          </div>\n\n          {/* QA Verification Badge */}\n          <div className=\"border-border space-y-1 rounded-lg border p-3\">\n            <div className=\"text-muted-foreground text-xs font-medium\">QA AUDIT DISPOSITION</div>\n            <div className=\"flex items-center gap-2 pt-1\">\n              {inspectionStatus === 'passed' && <ShieldCheck className=\"text-foreground size-5\" />}\n              {inspectionStatus === 'discrepancy' && <AlertTriangle className=\"text-destructive size-5\" />}\n              {inspectionStatus === 'pending' && <Clock className=\"text-muted-foreground size-5\" />}\n              <span className=\"text-sm font-medium\">\n                {inspectionStatus === 'passed'\n                  ? 'All lines cleared for putaway'\n                  : inspectionStatus === 'discrepancy'\n                    ? 'Discrepancy logged for vendor credit'\n                    : 'Awaiting line verification'}\n              </span>\n            </div>\n          </div>\n        </CardContent>\n      </Card>\n\n      {/* PO Line Item Matching Table */}\n      <Card>\n        <CardHeader className=\"pb-3\">\n          <CardTitle className=\"text-base font-semibold\">Purchase Order Line Verification</CardTitle>\n          <CardDescription>\n            Verify quantities received against vendor packing list and assign warehouse staging zones.\n          </CardDescription>\n        </CardHeader>\n\n        <CardContent className=\"p-0\">\n          <Table>\n            <TableHeader>\n              <TableRow>\n                <TableHead className=\"w-[280px]\">Item / Description</TableHead>\n                <TableHead className=\"text-right\">Ordered</TableHead>\n                <TableHead className=\"w-[110px] text-right\">Received</TableHead>\n                <TableHead className=\"w-[110px] text-right\">Rejected</TableHead>\n                <TableHead>Rejection Reason</TableHead>\n                <TableHead>Lot Number</TableHead>\n                <TableHead>Staging Target</TableHead>\n              </TableRow>\n            </TableHeader>\n            <TableBody>\n              {lines.map((line) => (\n                <TableRow key={line.id}>\n                  {/* Item Details */}\n                  <TableCell>\n                    <div className=\"font-medium\">{line.title}</div>\n                    <div className=\"text-muted-foreground font-mono text-xs\">{line.sku}</div>\n                  </TableCell>\n\n                  {/* Ordered Qty */}\n                  <TableCell className=\"text-muted-foreground text-right font-mono text-sm\">\n                    {line.orderedQty}\n                  </TableCell>\n\n                  {/* Received Qty */}\n                  <TableCell className=\"text-right\">\n                    <Input\n                      type=\"number\"\n                      min={0}\n                      value={line.receivedQty}\n                      onChange={(e) => updateLine(line.id, { receivedQty: Number(e.target.value) })}\n                      className=\"h-8 text-right font-mono\"\n                      disabled={isCompleted}\n                    />\n                  </TableCell>\n\n                  {/* Rejected Qty */}\n                  <TableCell className=\"text-right\">\n                    <Input\n                      type=\"number\"\n                      min={0}\n                      value={line.rejectedQty}\n                      onChange={(e) => updateLine(line.id, { rejectedQty: Number(e.target.value) })}\n                      className=\"h-8 text-right font-mono\"\n                      disabled={isCompleted}\n                    />\n                  </TableCell>\n\n                  {/* Reason */}\n                  <TableCell>\n                    <Select\n                      value={line.rejectionReason}\n                      onValueChange={(val: POLineItem['rejectionReason']) =>\n                        updateLine(line.id, { rejectionReason: val })\n                      }\n                      disabled={isCompleted || line.rejectedQty === 0}\n                    >\n                      <SelectTrigger className=\"h-8 w-[160px] text-xs\">\n                        <SelectValue />\n                      </SelectTrigger>\n                      <SelectContent>\n                        <SelectItem value=\"none\">None (Accepted)</SelectItem>\n                        <SelectItem value=\"damaged_packaging\">Damaged Packaging</SelectItem>\n                        <SelectItem value=\"expired_lot\">Short Shelf Life</SelectItem>\n                        <SelectItem value=\"wrong_specification\">Incorrect Spec</SelectItem>\n                        <SelectItem value=\"temperature_excursion\">Temp Excursion</SelectItem>\n                      </SelectContent>\n                    </Select>\n                  </TableCell>\n\n                  {/* Lot Number Input */}\n                  <TableCell>\n                    <Input\n                      value={line.lotNumber}\n                      onChange={(e) => updateLine(line.id, { lotNumber: e.target.value })}\n                      placeholder=\"Lot #\"\n                      className=\"h-8 w-28 font-mono text-xs\"\n                      disabled={isCompleted}\n                    />\n                  </TableCell>\n\n                  {/* Staging Target */}\n                  <TableCell>\n                    <span className=\"bg-muted text-foreground rounded px-2 py-1 font-mono text-xs font-medium\">\n                      {line.stagingLocation}\n                    </span>\n                  </TableCell>\n                </TableRow>\n              ))}\n            </TableBody>\n          </Table>\n        </CardContent>\n\n        <CardFooter className=\"border-border text-muted-foreground flex items-center justify-between border-t py-3 text-xs\">\n          <div>Official GRN generates supplier debit note automatically for any non-zero rejection.</div>\n          <div className=\"text-foreground font-medium\">\n            Accepted: <span className=\"font-mono font-semibold\">{totalAccepted}</span> units · Rejected:{' '}\n            <span className=\"text-destructive font-mono font-semibold\">{totalRejected}</span> units\n          </div>\n        </CardFooter>\n      </Card>\n    </div>\n  )\n}\n",
      "type": "registry:block",
      "target": "~/components/blocks/purchase-order-receiving/PurchaseOrderReceiving.tsx"
    },
    {
      "path": "packages/registry-react/blocks/purchase-order-receiving/index.ts",
      "content": "export { PurchaseOrderReceiving } from './PurchaseOrderReceiving'\nexport type { POLineItem, PurchaseOrderReceivingProps } from './PurchaseOrderReceiving'\n",
      "type": "registry:block",
      "target": "~/components/blocks/purchase-order-receiving/index.ts"
    }
  ],
  "dependencies": [
    "lucide-react"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/react/card.json",
    "https://uipkge.dev/r/react/button.json",
    "https://uipkge.dev/r/react/input.json",
    "https://uipkge.dev/r/react/badge.json",
    "https://uipkge.dev/r/react/select.json",
    "https://uipkge.dev/r/react/table.json"
  ],
  "description": "Inbound dock receiving workbench with PO matching, QA discrepancy logging, lot registration, and GRN generation.",
  "categories": [
    "dashboard",
    "data-display"
  ]
}