Menu

Change language

GitHub repo

Return Merchandise Inspection

blocklogistics

Warehouse returns intake inspection station, RMA condition grading, and restock vs quarantine disposition workbench.

Installation

$npx uipkge-ng@latest add return-merchandise-inspection
Manifest:https://uipkge.dev/r/angular/return-merchandise-inspection.jsonInstalls to:src/app/components/blocks/return-merchandise-inspection/

Variants

Loading interactive previews…

Schema

Type aliases exported from this item's source. Use these to shape the data you pass in.

InspectionChecklist
interface InspectionChecklist {
  tagsAttached: boolean
  originalBox: boolean
  allAccessories: boolean
  odorStainFree: boolean
}
ReturnInspectionData
interface ReturnInspectionData {
  rmaNumber: string
  stationId: string
  inspectorName: string
  returnReason: string
  item: {
    name: string
    variant: string
    msrp: number
    sku: string
    upc: string
    verified: boolean
  }
  grade: ConditionGrade
  checklist: InspectionChecklist
  refundAction: RefundAction
  qcNotes: string
  dispositionOutcome: {
    route: string
    destinationBin: string
    lpnCode: string
    priority: string
  }
}
GradeDefinition
interface GradeDefinition {
  id: ConditionGrade
  code: string
  title: string
  conditionLabel: string
  summary: string
  route: string
  targetBin: string
  lpnCode: string
  priority: string
  badgeVariant: 'outline' | 'destructive'
  badgeClasses: string
  activeBorderBg: string
  indicatorColor: string
  statusText: string
}

Files installed (2)

  • src/app/components/blocks/return-merchandise-inspection/return-merchandise-inspection.component.ts57.1 kB
    // Warehouse returns intake inspection station: RMA condition grading, restock vs
    // quarantine disposition routing, and customer refund action workbench with a post-submission
    // disposition receipt. Port of the React block 1:1.
    import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, computed, signal } from '@angular/core'
    import {
      AlertTriangle,
      ArrowRight,
      Barcode,
      Box,
      CheckCircle2,
      Clock,
      CornerDownLeft,
      CreditCard,
      Download,
      FileCheck,
      Gift,
      LucideAngularModule,
      Package,
      PackageCheck,
      Printer,
      Radio,
      RotateCcw,
      ScanLine,
      Tag,
      UserCheck,
      Warehouse,
    } from 'lucide-angular'
    import { cn } from '@/lib/utils'
    import { UiBadgeComponent } from '@/ui/badge/badge.component'
    import { UiButtonComponent } from '@/ui/button/button.component'
    import {
      UiCardComponent,
      UiCardContentComponent,
      UiCardDescriptionComponent,
      UiCardFooterComponent,
      UiCardHeaderComponent,
      UiCardTitleComponent,
    } from '@/ui/card/card.component'
    import { UiCheckboxComponent, type CheckedState } from '@/ui/checkbox/checkbox.component'
    import { UiRadioGroupComponent, UiRadioGroupItemComponent } from '@/ui/radio-group/radio-group.component'
    import { UiSeparatorComponent } from '@/ui/separator/separator.component'
    import { UiTextareaComponent } from '@/ui/textarea/textarea.component'
    
    export type ConditionGrade = 'grade-a' | 'grade-b' | 'grade-c' | 'grade-d'
    export type RefundAction = 'full-refund' | 'store-credit' | 'restock-fee'
    
    export interface InspectionChecklist {
      tagsAttached: boolean
      originalBox: boolean
      allAccessories: boolean
      odorStainFree: boolean
    }
    
    export interface ReturnInspectionData {
      rmaNumber: string
      stationId: string
      inspectorName: string
      returnReason: string
      item: {
        name: string
        variant: string
        msrp: number
        sku: string
        upc: string
        verified: boolean
      }
      grade: ConditionGrade
      checklist: InspectionChecklist
      refundAction: RefundAction
      qcNotes: string
      dispositionOutcome: {
        route: string
        destinationBin: string
        lpnCode: string
        priority: string
      }
    }
    
    interface GradeDefinition {
      id: ConditionGrade
      code: string
      title: string
      conditionLabel: string
      summary: string
      route: string
      targetBin: string
      lpnCode: string
      priority: string
      badgeVariant: 'outline' | 'destructive'
      badgeClasses: string
      activeBorderBg: string
      indicatorColor: string
      statusText: string
    }
    
    const gradeDefinitions: Record<ConditionGrade, GradeDefinition> = {
      'grade-a': {
        id: 'grade-a',
        code: 'Grade A',
        title: 'Grade A: Brand New / Unopened',
        conditionLabel: 'Brand New / Pristine',
        summary: 'Original tags & packaging intact',
        route: 'Restock to Primary Inventory',
        targetBin: 'Aisle 04-B · Bin #04-B-12',
        lpnCode: 'LPN-849201-RESTOCK-A',
        priority: 'High · Inventory Replenishment',
        badgeVariant: 'outline',
        badgeClasses: 'border-success/30 bg-success/10 text-success font-semibold',
        activeBorderBg: 'border-success/40 bg-success/5 shadow-xs ring-1 ring-success/20',
        indicatorColor: 'bg-success',
        statusText: 'Primary Inventory Restock Approved',
      },
      'grade-b': {
        id: 'grade-b',
        code: 'Grade B',
        title: 'Grade B: Open Box / Minor Cosmetic',
        conditionLabel: 'Open Box / Inspected',
        summary: 'No functional damage, packaging opened',
        route: 'Route to Outlet / Refurbished Store',
        targetBin: 'Secondary Channel · Pallet #03',
        lpnCode: 'LPN-849201-OUTLET-B',
        priority: 'Standard · Secondary Routing',
        badgeVariant: 'outline',
        badgeClasses: 'border-warning/30 bg-warning/10 text-warning font-semibold',
        activeBorderBg: 'border-warning/40 bg-warning/5 shadow-xs ring-1 ring-warning/20',
        indicatorColor: 'bg-warning',
        statusText: 'Secondary Channel Re-routing',
      },
      'grade-c': {
        id: 'grade-c',
        code: 'Grade C',
        title: 'Grade C: Worn / Used',
        conditionLabel: 'Worn / Blemished',
        summary: 'Minor wear on soles, visible creasing',
        route: 'Liquidation Batch #LQ-409',
        targetBin: 'Bulk Liquidation Pallet #C-88',
        lpnCode: 'LPN-849201-LIQUIDATE-C',
        priority: 'Batch Weekly Dispatch',
        badgeVariant: 'outline',
        badgeClasses: 'border-orange-500/30 bg-orange-500/10 text-orange-700 dark:text-orange-400 font-semibold',
        activeBorderBg: 'border-orange-500/40 bg-orange-500/5 dark:bg-orange-950/20 shadow-xs ring-1 ring-orange-500/20',
        indicatorColor: 'bg-orange-500',
        statusText: 'Wholesale Liquidation Staging',
      },
      'grade-d': {
        id: 'grade-d',
        code: 'Grade D',
        title: 'Grade D: Damaged / Defective',
        conditionLabel: 'Defective / Damaged',
        summary: 'Torn fabric, seam defect, structural flaw',
        route: 'Quarantine / Return to Vendor (RTV)',
        targetBin: 'Quarantine Bay Q-08 (Vendor Claims)',
        lpnCode: 'LPN-849201-QUARANTINE-D',
        priority: 'Urgent · Vendor RTV Credit Hold',
        badgeVariant: 'destructive',
        badgeClasses: 'border-destructive/30 bg-destructive/10 text-destructive font-semibold',
        activeBorderBg: 'border-destructive/40 bg-destructive/5 shadow-xs ring-1 ring-destructive/20',
        indicatorColor: 'bg-destructive',
        statusText: 'Quarantine Hold & Vendor Credit Claim',
      },
    }
    
    const itemData = {
      name: 'Aero Minimalist Runner · Size 10.5 · Matte Black',
      variant: 'Matte Black / US 10.5 M',
      sku: 'AMR-BLK-105',
      upc: 'UPC-018249',
      msrp: 145.0,
      orderRef: '#ORD-98421',
      carrier: 'FedEx Return Express',
      trackingNumber: '7946 1102 9842',
      returnReason: 'Customer reported wrong size ordered',
    }
    
    const defaultQcNotes =
      'Outer packaging opened by customer. All interior packaging materials, extra shoelaces, and brand care card verified in pristine condition. Zero sole wear detected.'
    
    @Component({
      changeDetection: ChangeDetectionStrategy.Eager,
      selector: 'ui-return-merchandise-inspection, [ui-return-merchandise-inspection]',
      standalone: true,
      // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.
      host: { '[attr.class]': '"contents"' },
      imports: [
        LucideAngularModule,
        UiBadgeComponent,
        UiButtonComponent,
        UiCardComponent,
        UiCardContentComponent,
        UiCardDescriptionComponent,
        UiCardFooterComponent,
        UiCardHeaderComponent,
        UiCardTitleComponent,
        UiCheckboxComponent,
        UiRadioGroupComponent,
        UiRadioGroupItemComponent,
        UiSeparatorComponent,
        UiTextareaComponent,
      ],
      template: `
        <div data-slot="return-merchandise-inspection" [class]="rootClass">
          @if (submitted()) {
            <!-- POST-SUBMISSION CONFIRMATION RECEIPT VIEW -->
            <div class="space-y-6">
              <div ui-card class="border-border overflow-hidden shadow-xs">
                <div [class]="receiptBannerClass">
                  <div class="relative mx-auto mb-4 size-16">
                    <span [class]="receiptGlowClass" aria-hidden="true"></span>
                    <span [class]="receiptIconWrapClass">
                      @if (selectedGrade() !== 'grade-d') {
                        <lucide-icon [img]="PackageCheck" class="size-8" />
                      } @else {
                        <lucide-icon [img]="AlertTriangle" class="size-8" />
                      }
                    </span>
                  </div>
    
                  <span
                    ui-badge
                    [variant]="selectedGrade() === 'grade-d' ? 'destructive' : 'outline'"
                    [class]="receiptBadgeClass"
                  >
                    RMA Disposition Manifest Dispatched
                  </span>
    
                  <h2 class="text-foreground text-2xl font-bold tracking-tight sm:text-3xl">
                    {{
                      selectedGrade() === 'grade-d'
                        ? 'RMA Inspection Flagged · Quarantine RTV Initiated'
                        : 'Inspection Complete · Automated Routing Logged'
                    }}
                  </h2>
                  <p class="text-muted-foreground mx-auto mt-1.5 max-w-2xl text-xs sm:text-sm">
                    Disposition for <span class="text-foreground font-medium">{{ item.name }}</span> has been recorded.
                    Warehouse routing slip and automated customer refund authorization have been queued.
                  </p>
    
                  <div
                    class="border-border bg-muted/60 mt-4 inline-flex flex-wrap items-center gap-2 rounded-full border px-3.5 py-1 text-xs"
                  >
                    <span class="text-muted-foreground font-medium">RMA Reference:</span>
                    <span class="text-foreground font-mono font-bold">{{ rmaNumber() }}</span>
                    <span class="text-muted-foreground font-medium">LPN:</span>
                    <span class="text-foreground font-mono font-bold">{{ currentGrade().lpnCode }}</span>
                  </div>
                </div>
    
                <div ui-card-content class="space-y-6 p-6">
                  <!-- Disposition Summary Meta Grid -->
                  <div class="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
                    <div class="border-border bg-muted/20 space-y-1 rounded-lg border p-3.5">
                      <span class="text-muted-foreground block text-xs font-medium">Condition Grade</span>
                      <span class="text-foreground block text-sm font-semibold">{{ currentGrade().title }}</span>
                      <span class="text-muted-foreground text-xs">{{ currentGrade().summary }}</span>
                    </div>
    
                    <div class="border-border bg-muted/20 space-y-1 rounded-lg border p-3.5">
                      <span class="text-muted-foreground block text-xs font-medium">Warehouse Destination</span>
                      <span class="text-foreground block text-sm font-semibold">{{ currentGrade().targetBin }}</span>
                      <span class="text-muted-foreground text-xs">{{ currentGrade().route }}</span>
                    </div>
    
                    <div class="border-border bg-muted/20 space-y-1 rounded-lg border p-3.5">
                      <span class="text-muted-foreground block text-xs font-medium">Customer Resolution</span>
                      <span class="text-foreground block text-sm font-semibold tabular-nums">
                        {{ formatCurrency(refundCalculations().totalRefund) }}
                      </span>
                      <span class="text-muted-foreground block truncate text-xs">{{
                        refundCalculations().methodLabel
                      }}</span>
                    </div>
    
                    <div class="border-border bg-muted/20 space-y-1 rounded-lg border p-3.5">
                      <span class="text-muted-foreground block text-xs font-medium">QC Inspector</span>
                      <span class="text-foreground block text-sm font-semibold">{{ inspectorName }}</span>
                      <span class="text-muted-foreground text-xs">Station #02 · Timestamped</span>
                    </div>
                  </div>
    
                  <!-- LPN Barcode & Routing Pass Box -->
                  <div class="border-border bg-muted/15 space-y-3 rounded-xl border p-4 sm:p-5">
                    <div class="flex flex-wrap items-center justify-between gap-2">
                      <div class="flex flex-wrap items-center gap-2">
                        <lucide-icon [img]="Barcode" class="text-primary size-4" />
                        <span class="text-foreground text-xs font-semibold tracking-wide uppercase">
                          Pallet / Tote License Plate Number (LPN)
                        </span>
                      </div>
                      <span ui-badge variant="outline" class="font-mono text-xs">READY FOR PUTAWAY</span>
                    </div>
    
                    <div
                      class="border-border bg-card flex flex-col items-center justify-center space-y-2 rounded-lg border p-4 text-center"
                    >
                      <!-- Barcode SVG visualization -->
                      <svg
                        class="text-foreground h-12 w-full max-w-sm"
                        viewBox="0 0 280 48"
                        fill="currentColor"
                        aria-label="LPN Warehouse Barcode"
                      >
                        <rect x="0" y="0" width="4" height="48" />
                        <rect x="7" y="0" width="2" height="48" />
                        <rect x="12" y="0" width="5" height="48" />
                        <rect x="20" y="0" width="2" height="48" />
                        <rect x="25" y="0" width="6" height="48" />
                        <rect x="34" y="0" width="3" height="48" />
                        <rect x="40" y="0" width="2" height="48" />
                        <rect x="45" y="0" width="5" height="48" />
                        <rect x="53" y="0" width="3" height="48" />
                        <rect x="60" y="0" width="6" height="48" />
                        <rect x="69" y="0" width="2" height="48" />
                        <rect x="74" y="0" width="4" height="48" />
                        <rect x="81" y="0" width="3" height="48" />
                        <rect x="88" y="0" width="5" height="48" />
                        <rect x="96" y="0" width="2" height="48" />
                        <rect x="101" y="0" width="6" height="48" />
                        <rect x="110" y="0" width="3" height="48" />
                        <rect x="116" y="0" width="4" height="48" />
                        <rect x="123" y="0" width="2" height="48" />
                        <rect x="128" y="0" width="5" height="48" />
                        <rect x="136" y="0" width="3" height="48" />
                        <rect x="142" y="0" width="6" height="48" />
                        <rect x="151" y="0" width="2" height="48" />
                        <rect x="156" y="0" width="4" height="48" />
                        <rect x="163" y="0" width="3" height="48" />
                        <rect x="170" y="0" width="5" height="48" />
                        <rect x="178" y="0" width="2" height="48" />
                        <rect x="183" y="0" width="6" height="48" />
                        <rect x="192" y="0" width="4" height="48" />
                        <rect x="199" y="0" width="2" height="48" />
                        <rect x="204" y="0" width="5" height="48" />
                        <rect x="212" y="0" width="3" height="48" />
                        <rect x="218" y="0" width="6" height="48" />
                        <rect x="227" y="0" width="2" height="48" />
                        <rect x="232" y="0" width="4" height="48" />
                        <rect x="239" y="0" width="3" height="48" />
                        <rect x="245" y="0" width="5" height="48" />
                        <rect x="253" y="0" width="2" height="48" />
                        <rect x="258" y="0" width="6" height="48" />
                        <rect x="267" y="0" width="3" height="48" />
                        <rect x="273" y="0" width="4" height="48" />
                      </svg>
                      <div class="flex items-center gap-3 font-mono text-xs font-bold">
                        <span class="text-foreground tracking-wider">{{ currentGrade().lpnCode }}</span>
                        <span class="text-muted-foreground font-normal">{{ currentGrade().targetBin }}</span>
                      </div>
                    </div>
    
                    <!-- Inspector Notes Display -->
                    @if (qcNotes()) {
                      <div class="space-y-1 pt-1 text-xs">
                        <span class="text-muted-foreground font-medium">Logged Inspector Notes:</span>
                        <p class="border-border bg-card text-foreground rounded-md border p-3 leading-relaxed italic">
                          “{{ qcNotes() }}”
                        </p>
                      </div>
                    }
                  </div>
    
                  <!-- Actions Strip -->
                  <div class="flex flex-wrap items-center justify-between gap-3 pt-2">
                    <button
                      ui-button
                      variant="outline"
                      size="sm"
                      class="gap-1.5 text-xs font-medium"
                      (click)="handleReset()"
                    >
                      <lucide-icon [img]="RotateCcw" class="size-3.5" />
                      Start Next RMA Inspection
                    </button>
    
                    <div class="flex flex-wrap items-center gap-2">
                      <button ui-button variant="outline" size="sm" class="gap-1.5 text-xs font-medium">
                        <lucide-icon [img]="Printer" class="size-3.5" />
                        Print LPN Tote Label
                      </button>
                      <button ui-button aria-label="Download attachment" size="sm" class="gap-1.5 text-xs font-medium">
                        <lucide-icon [img]="Download" class="size-3.5" />
                        Download Disposition PDF
                      </button>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          } @else {
            <!-- ACTIVE INSPECTION WORKBENCH VIEW -->
            <div class="space-y-6">
              <!-- Top Station Header Card -->
              <div ui-card class="border-border shadow-xs">
                <div ui-card-header class="pb-4">
                  <div class="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
                    <div class="space-y-2">
                      <div class="flex flex-wrap items-center gap-2">
                        <span
                          ui-badge
                          variant="outline"
                          class="border-primary/30 bg-primary/10 text-primary gap-1.5 py-0.5 text-xs"
                        >
                          <lucide-icon [img]="Warehouse" class="size-3.5" />
                          Station #02 · Returns Intake & Grading
                        </span>
                        <span ui-badge variant="outline" class="gap-1.5 py-0.5 font-mono text-xs">
                          <lucide-icon [img]="Tag" class="size-3" />
                          {{ rmaNumber() }}
                        </span>
                        <span
                          ui-badge
                          variant="outline"
                          class="border-success/30 bg-success/10 text-success gap-1.5 py-0.5 text-xs"
                        >
                          <lucide-icon [img]="Radio" class="text-success size-3" />
                          Scanner Online
                        </span>
                      </div>
    
                      <div>
                        <h3 ui-card-title class="text-xl font-bold tracking-tight sm:text-2xl">
                          Warehouse Returns Intake & Grading Station #02
                        </h3>
                        <p ui-card-description class="text-xs sm:text-sm">
                          RMA intake verification, physical condition evaluation, restock/quarantine disposition routing,
                          and customer refund action.
                        </p>
                      </div>
                    </div>
    
                    <!-- Primary Header CTA -->
                    <div class="flex shrink-0 items-center gap-2">
                      <button
                        ui-button
                        type="button"
                        size="default"
                        class="gap-2 text-xs font-semibold sm:text-sm"
                        (click)="handleCompleteInspection()"
                      >
                        <lucide-icon [img]="FileCheck" class="size-4" />
                        Complete Inspection & Disposition
                      </button>
                    </div>
                  </div>
                </div>
    
                <!-- Metadata Ribbon Bar -->
                <div ui-card-content class="pt-0 pb-4">
                  <div class="border-border bg-muted/20 grid gap-3 rounded-lg border p-3.5 sm:grid-cols-2 lg:grid-cols-4">
                    <div class="space-y-0.5">
                      <div class="text-muted-foreground flex items-center gap-1.5 text-xs font-medium">
                        <lucide-icon [img]="Tag" class="text-primary size-3.5" />
                        <span>RMA Reference</span>
                      </div>
                      <p class="text-foreground font-mono text-xs font-semibold">{{ rmaNumber() }}</p>
                      <p class="text-muted-foreground text-xs">Order: {{ item.orderRef }}</p>
                    </div>
    
                    <div class="space-y-0.5">
                      <div class="text-muted-foreground flex items-center gap-1.5 text-xs font-medium">
                        <lucide-icon [img]="UserCheck" class="text-primary size-3.5" />
                        <span>Inspector / Station</span>
                      </div>
                      <p class="text-foreground text-xs font-semibold">{{ inspectorName }}</p>
                      <p class="text-muted-foreground text-xs">Terminal Station #02</p>
                    </div>
    
                    <div class="space-y-0.5">
                      <div class="text-muted-foreground flex items-center gap-1.5 text-xs font-medium">
                        <lucide-icon [img]="CornerDownLeft" class="text-primary size-3.5" />
                        <span>Customer Return Reason</span>
                      </div>
                      <p class="text-foreground truncate text-xs font-semibold">{{ item.returnReason }}</p>
                      <p class="text-muted-foreground text-xs">Carrier: {{ item.carrier }}</p>
                    </div>
    
                    <div class="space-y-0.5">
                      <div class="text-muted-foreground flex items-center gap-1.5 text-xs font-medium">
                        <lucide-icon [img]="Clock" class="text-primary size-3.5" />
                        <span>Intake Status</span>
                      </div>
                      <p class="text-foreground text-xs font-semibold">In Progress · Pending Disposition</p>
                      <p class="text-muted-foreground font-mono text-xs">{{ item.trackingNumber }}</p>
                    </div>
                  </div>
                </div>
              </div>
    
              <!-- 2-COLUMN INSPECTION WORKBENCH -->
              <div class="grid grid-cols-1 items-start gap-6 lg:grid-cols-12">
                <!-- LEFT COLUMN: Item Verification & Condition Grading (7 Cols) -->
                <div class="space-y-6 lg:col-span-7">
                  <!-- 1. Scanned Item Verification Card -->
                  <div ui-card class="border-border shadow-xs">
                    <div ui-card-header class="pb-3">
                      <div class="flex items-center justify-between">
                        <div class="flex flex-wrap items-center gap-2">
                          <lucide-icon [img]="ScanLine" class="text-primary size-4" />
                          <h3 ui-card-title class="text-sm font-semibold">Intake Item Scanned</h3>
                        </div>
                        <span ui-badge variant="outline" class="border-success/30 bg-success/10 text-success gap-1 text-xs">
                          <lucide-icon [img]="CheckCircle2" class="size-3" />
                          Match Verified
                        </span>
                      </div>
                    </div>
    
                    <div ui-card-content class="space-y-4">
                      <div
                        class="border-border bg-card flex flex-col gap-3 rounded-lg border p-3.5 sm:flex-row sm:items-center"
                      >
                        <div
                          class="border-border bg-muted/60 text-muted-foreground flex size-14 shrink-0 items-center justify-center rounded-lg border"
                        >
                          <lucide-icon [img]="Package" class="text-primary size-7" />
                        </div>
    
                        <div class="min-w-0 flex-1 space-y-1">
                          <div class="flex flex-wrap items-start justify-between gap-2">
                            <div>
                              <h4 class="text-foreground text-sm leading-tight font-semibold">
                                {{ item.name }}
                              </h4>
                              <p class="text-muted-foreground text-xs">
                                {{ item.variant }} · SKU: <span class="font-mono font-medium">{{ item.sku }}</span>
                              </p>
                            </div>
                            <div class="text-right">
                              <span class="text-foreground text-base font-bold tabular-nums">
                                {{ formatCurrency(item.msrp) }}
                              </span>
                              <span class="text-muted-foreground block text-xs">MSRP</span>
                            </div>
                          </div>
    
                          <div class="flex flex-wrap items-center gap-3 pt-1 text-xs">
                            <div class="text-muted-foreground flex items-center gap-1.5 font-mono">
                              <lucide-icon [img]="Barcode" class="text-success size-3.5" />
                              <span class="text-foreground font-semibold">{{ item.upc }}</span>
                              <span ui-badge variant="outline" class="text-success h-4 px-1.5 py-0 text-xs">UPC OK</span>
                            </div>
                            <ui-separator orientation="vertical" class="h-3.5" />
                            <span class="text-muted-foreground">Order: {{ item.orderRef }}</span>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
    
                  <!-- 2. Condition Grading Radio Cards -->
                  <div ui-card class="border-border shadow-xs">
                    <div ui-card-header class="pb-3">
                      <div class="flex items-center justify-between">
                        <div class="space-y-0.5">
                          <h3 ui-card-title class="text-sm font-semibold">Condition Grading Assessment</h3>
                          <p ui-card-description class="text-xs">
                            Select physical grading level to trigger automated warehouse routing rules.
                          </p>
                        </div>
                        <span ui-badge [class]="currentGrade().badgeClasses">
                          {{ currentGrade().code }}
                        </span>
                      </div>
                    </div>
    
                    <div ui-card-content>
                      <ui-radio-group
                        [value]="selectedGrade()"
                        (valueChange)="setGrade($event)"
                        class="grid grid-cols-1 gap-2.5"
                      >
                        <!-- Grade A -->
                        <div [class]="gradeCardClass('grade-a')" (click)="selectedGrade.set('grade-a')">
                          <ui-radio-group-item id="grade-a" value="grade-a" class="mt-0.5" />
                          <div class="flex-1 space-y-1">
                            <div class="flex flex-wrap items-center justify-between gap-2">
                              <label for="grade-a" class="text-foreground cursor-pointer text-xs font-semibold sm:text-sm">
                                Grade A: Brand New / Unopened
                              </label>
                              <span ui-badge variant="outline" class="border-success/30 bg-success/10 text-success text-xs">
                                Primary Restock
                              </span>
                            </div>
                            <p class="text-muted-foreground text-xs leading-relaxed">
                              Original factory tags & packaging intact. No cosmetic or functional flaws.
                            </p>
                            <div class="text-muted-foreground flex items-center gap-1.5 pt-1 text-xs">
                              <lucide-icon [img]="ArrowRight" class="text-primary size-3" />
                              <span
                                >Target:
                                <strong class="text-foreground font-medium"
                                  >Restock to Primary Inventory (Aisle 04-B)</strong
                                ></span
                              >
                            </div>
                          </div>
                        </div>
    
                        <!-- Grade B -->
                        <div [class]="gradeCardClass('grade-b')" (click)="selectedGrade.set('grade-b')">
                          <ui-radio-group-item id="grade-b" value="grade-b" class="mt-0.5" />
                          <div class="flex-1 space-y-1">
                            <div class="flex flex-wrap items-center justify-between gap-2">
                              <label for="grade-b" class="text-foreground cursor-pointer text-xs font-semibold sm:text-sm">
                                Grade B: Open Box / Minor Cosmetic
                              </label>
                              <span ui-badge variant="outline" class="border-warning/30 bg-warning/10 text-warning text-xs">
                                Outlet Store
                              </span>
                            </div>
                            <p class="text-muted-foreground text-xs leading-relaxed">
                              Box opened or minor package scuffs, but product is 100% unworn and fully functional.
                            </p>
                            <div class="text-muted-foreground flex items-center gap-1.5 pt-1 text-xs">
                              <lucide-icon [img]="ArrowRight" class="text-primary size-3" />
                              <span
                                >Target:
                                <strong class="text-foreground font-medium"
                                  >Route to Outlet / Refurbished Store</strong
                                ></span
                              >
                            </div>
                          </div>
                        </div>
    
                        <!-- Grade C -->
                        <div [class]="gradeCardClass('grade-c')" (click)="selectedGrade.set('grade-c')">
                          <ui-radio-group-item id="grade-c" value="grade-c" class="mt-0.5" />
                          <div class="flex-1 space-y-1">
                            <div class="flex flex-wrap items-center justify-between gap-2">
                              <label for="grade-c" class="text-foreground cursor-pointer text-xs font-semibold sm:text-sm">
                                Grade C: Worn / Used
                              </label>
                              <span
                                ui-badge
                                variant="outline"
                                class="border-orange-500/30 bg-orange-500/10 text-xs text-orange-700 dark:text-orange-400"
                              >
                                Liquidation
                              </span>
                            </div>
                            <p class="text-muted-foreground text-xs leading-relaxed">
                              Visible wear on soles, minor creasing or cosmetic stains. Not suitable for retail shelves.
                            </p>
                            <div class="text-muted-foreground flex items-center gap-1.5 pt-1 text-xs">
                              <lucide-icon [img]="ArrowRight" class="text-primary size-3" />
                              <span
                                >Target:
                                <strong class="text-foreground font-medium"
                                  >Liquidation Batch #LQ-409 (Wholesale Lot)</strong
                                ></span
                              >
                            </div>
                          </div>
                        </div>
    
                        <!-- Grade D -->
                        <div [class]="gradeCardClass('grade-d')" (click)="selectedGrade.set('grade-d')">
                          <ui-radio-group-item id="grade-d" value="grade-d" class="mt-0.5" />
                          <div class="flex-1 space-y-1">
                            <div class="flex flex-wrap items-center justify-between gap-2">
                              <label for="grade-d" class="text-foreground cursor-pointer text-xs font-semibold sm:text-sm">
                                Grade D: Damaged / Defective
                              </label>
                              <span ui-badge variant="destructive" class="text-xs">Quarantine RTV</span>
                            </div>
                            <p class="text-muted-foreground text-xs leading-relaxed">
                              Torn fabric, broken seam, outsole separation, or manufacturing defect.
                            </p>
                            <div class="text-muted-foreground flex items-center gap-1.5 pt-1 text-xs">
                              <lucide-icon [img]="ArrowRight" class="text-primary size-3" />
                              <span
                                >Target:
                                <strong class="text-foreground font-medium"
                                  >Quarantine Bay Q-08 / Return to Vendor (RTV)</strong
                                ></span
                              >
                            </div>
                          </div>
                        </div>
                      </ui-radio-group>
                    </div>
                  </div>
    
                  <!-- 3. Physical Inspection Checklist -->
                  <div ui-card class="border-border shadow-xs">
                    <div ui-card-header class="pb-3">
                      <div class="flex items-center justify-between">
                        <div class="space-y-0.5">
                          <h3 ui-card-title class="text-sm font-semibold">Physical Inspection Checklist</h3>
                          <p ui-card-description class="text-xs">
                            Verify all physical criteria before approving final warehouse putaway.
                          </p>
                        </div>
                        <div class="flex flex-wrap items-center gap-2">
                          <span ui-badge variant="secondary" class="font-mono text-xs">
                            {{ checkedChecklistCount() }}/{{ totalChecklistCount }} Passed
                          </span>
                          <button
                            ui-button
                            type="button"
                            variant="ghost"
                            size="sm"
                            class="text-muted-foreground hover:text-foreground h-7 text-xs"
                            (click)="selectAllChecklist(!allChecksPassed())"
                          >
                            {{ allChecksPassed() ? 'Uncheck All' : 'Pass All' }}
                          </button>
                        </div>
                      </div>
                    </div>
    
                    <div ui-card-content class="space-y-2.5">
                      <!-- Item 1: Tags Attached -->
                      <div [class]="checkRowClass(checklist().tagsAttached)">
                        <ui-checkbox
                          id="chk-tags"
                          [checked]="checklist().tagsAttached"
                          (checkedChange)="setCheck('tagsAttached', $event)"
                          class="mt-0.5"
                        />
                        <div class="flex-1 space-y-0.5">
                          <label for="chk-tags" class="text-foreground cursor-pointer text-xs font-semibold select-none">
                            Tags attached
                          </label>
                          <p class="text-muted-foreground text-xs">
                            Factory hangtags, barcode UPC stickers, and care labels intact.
                          </p>
                        </div>
                      </div>
    
                      <!-- Item 2: Original Box Present -->
                      <div [class]="checkRowClass(checklist().originalBox)">
                        <ui-checkbox
                          id="chk-box"
                          [checked]="checklist().originalBox"
                          (checkedChange)="setCheck('originalBox', $event)"
                          class="mt-0.5"
                        />
                        <div class="flex-1 space-y-0.5">
                          <label for="chk-box" class="text-foreground cursor-pointer text-xs font-semibold select-none">
                            Original box present
                          </label>
                          <p class="text-muted-foreground text-xs">
                            Manufacturer shoebox present with readable SKU and size label.
                          </p>
                        </div>
                      </div>
    
                      <!-- Item 3: Accessories in Box -->
                      <div [class]="checkRowClass(checklist().allAccessories)">
                        <ui-checkbox
                          id="chk-acc"
                          [checked]="checklist().allAccessories"
                          (checkedChange)="setCheck('allAccessories', $event)"
                          class="mt-0.5"
                        />
                        <div class="flex-1 space-y-0.5">
                          <label for="chk-acc" class="text-foreground cursor-pointer text-xs font-semibold select-none">
                            All accessories in box
                          </label>
                          <p class="text-muted-foreground text-xs">
                            Extra pair of laces, dust bag, and product manual verified.
                          </p>
                        </div>
                      </div>
    
                      <!-- Item 4: Odor and Stain Free -->
                      <div [class]="checkRowClass(checklist().odorStainFree)">
                        <ui-checkbox
                          id="chk-odor"
                          [checked]="checklist().odorStainFree"
                          (checkedChange)="setCheck('odorStainFree', $event)"
                          class="mt-0.5"
                        />
                        <div class="flex-1 space-y-0.5">
                          <label for="chk-odor" class="text-foreground cursor-pointer text-xs font-semibold select-none">
                            Odor & stain free
                          </label>
                          <p class="text-muted-foreground text-xs">
                            Free from perfume scent, tobacco smoke, pet hair, dirt, or cosmetic scuffs.
                          </p>
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
    
                <!-- RIGHT COLUMN: Disposition & Customer Refund Action Card (5 Cols) -->
                <div class="space-y-6 lg:col-span-5">
                  <!-- 1. Selected Automated Warehouse Disposition Card -->
                  <div ui-card class="border-border overflow-hidden shadow-xs">
                    <div ui-card-header class="bg-muted/15 border-border border-b pb-3">
                      <div class="flex items-center justify-between">
                        <div class="flex flex-wrap items-center gap-2">
                          <lucide-icon [img]="Warehouse" class="text-primary size-4" />
                          <h3 ui-card-title class="text-sm font-semibold">Warehouse Routing Outcome</h3>
                        </div>
                        <span ui-badge [class]="currentGrade().badgeClasses">
                          {{ currentGrade().code }}
                        </span>
                      </div>
                    </div>
    
                    <div ui-card-content class="space-y-4 p-4">
                      <!-- Active Outcome Card Banner -->
                      <div [class]="outcomeBannerClass">
                        <div class="flex items-start gap-3">
                          <div
                            class="border-border bg-background/80 text-foreground flex size-9 shrink-0 items-center justify-center rounded-md border"
                          >
                            <lucide-icon [img]="Box" class="text-primary size-5" />
                          </div>
                          <div class="min-w-0 flex-1 space-y-1">
                            <div class="flex flex-wrap items-center gap-2">
                              <span class="text-foreground text-xs font-bold sm:text-sm">
                                {{ currentGrade().route }}
                              </span>
                            </div>
                            <p class="text-muted-foreground text-xs">
                              Destination Bin:
                              <strong class="text-foreground font-mono font-semibold">{{
                                currentGrade().targetBin
                              }}</strong>
                            </p>
                            <p class="text-muted-foreground text-xs">
                              Priority: <span class="text-foreground font-medium">{{ currentGrade().priority }}</span>
                            </p>
                          </div>
                        </div>
    
                        <div class="border-border/60 mt-3.5 flex items-center justify-between border-t pt-3 text-xs">
                          <span class="text-muted-foreground font-mono">LPN: {{ currentGrade().lpnCode }}</span>
                          <span ui-badge variant="outline" class="font-mono text-xs">READY FOR SCAN</span>
                        </div>
                      </div>
                    </div>
                  </div>
    
                  <!-- 2. Customer Refund Action Card -->
                  <div ui-card class="border-border shadow-xs">
                    <div ui-card-header class="pb-3">
                      <div class="flex items-center justify-between">
                        <div class="space-y-0.5">
                          <h3 ui-card-title class="text-sm font-semibold">Customer Refund Action</h3>
                          <p ui-card-description class="text-xs">Choose financial settlement for RMA {{ rmaNumber() }}.</p>
                        </div>
                        <lucide-icon [img]="CreditCard" class="text-muted-foreground size-4" />
                      </div>
                    </div>
    
                    <div ui-card-content class="space-y-4">
                      <ui-radio-group
                        [value]="selectedRefundAction()"
                        (valueChange)="setRefundAction($event)"
                        class="grid grid-cols-1 gap-2.5"
                      >
                        <!-- Option 1: Full Refund -->
                        <div [class]="refundCardClass('full-refund')" (click)="selectedRefundAction.set('full-refund')">
                          <ui-radio-group-item id="ref-full" value="full-refund" class="mt-0.5" />
                          <div class="flex-1 space-y-0.5">
                            <div class="flex items-center justify-between">
                              <label for="ref-full" class="text-foreground cursor-pointer text-xs font-semibold">
                                Authorize Full Refund
                              </label>
                              <span class="text-foreground text-xs font-semibold tabular-nums">
                                {{ formatCurrency(item.msrp) }}
                              </span>
                            </div>
                            <p class="text-muted-foreground text-xs">
                              100% refund to <span class="text-foreground font-medium">Visa •••• 4242</span>. 3–5 business
                              days.
                            </p>
                          </div>
                        </div>
    
                        <!-- Option 2: Store Credit (+10% Bonus) -->
                        <div [class]="refundCardClass('store-credit')" (click)="selectedRefundAction.set('store-credit')">
                          <ui-radio-group-item id="ref-credit" value="store-credit" class="mt-0.5" />
                          <div class="flex-1 space-y-0.5">
                            <div class="flex items-center justify-between">
                              <div class="flex items-center gap-1.5">
                                <lucide-icon [img]="Gift" class="text-success size-3" />
                                <label for="ref-credit" class="text-foreground cursor-pointer text-xs font-semibold">
                                  Issue Store Credit (+10%)
                                </label>
                              </div>
                              <span class="text-success text-success text-xs font-semibold tabular-nums">
                                {{ formatCurrency(item.msrp * 1.1) }}
                              </span>
                            </div>
                            <p class="text-muted-foreground text-xs">
                              Includes
                              <span class="text-foreground font-medium">+{{ formatCurrency(item.msrp * 0.1) }}</span> bonus
                              credit. Delivered instantly by email.
                            </p>
                          </div>
                        </div>
    
                        <!-- Option 3: Charge Restocking Fee -->
                        <div [class]="refundCardClass('restock-fee')" (click)="selectedRefundAction.set('restock-fee')">
                          <ui-radio-group-item id="ref-fee" value="restock-fee" class="mt-0.5" />
                          <div class="flex-1 space-y-0.5">
                            <div class="flex items-center justify-between">
                              <label for="ref-fee" class="text-foreground cursor-pointer text-xs font-semibold">
                                Charge Restocking Fee (-$15)
                              </label>
                              <span class="text-foreground text-xs font-semibold tabular-nums">
                                {{ formatCurrency(item.msrp - 15) }}
                              </span>
                            </div>
                            <p class="text-muted-foreground text-xs">
                              $15.00 repackaging & inspection deduction. Net to
                              <span class="text-foreground font-medium">Visa •••• 4242</span>.
                            </p>
                          </div>
                        </div>
                      </ui-radio-group>
    
                      <!-- Settlement Calculation Summary Box -->
                      <div class="border-border bg-muted/30 space-y-1.5 rounded-lg border p-3 text-xs">
                        <div class="text-muted-foreground flex items-center justify-between">
                          <span>Item MSRP</span>
                          <span class="text-foreground font-mono font-medium">{{
                            formatCurrency(refundCalculations().subtotal)
                          }}</span>
                        </div>
                        @if (selectedRefundAction() === 'store-credit') {
                          <div class="text-success flex items-center justify-between">
                            <span>{{ refundCalculations().adjustmentLabel }}</span>
                            <span class="font-mono font-medium"
                              >+{{ formatCurrency(refundCalculations().adjustmentAmount) }}</span
                            >
                          </div>
                        } @else if (selectedRefundAction() === 'restock-fee') {
                          <div class="text-destructive flex items-center justify-between">
                            <span>{{ refundCalculations().adjustmentLabel }}</span>
                            <span class="font-mono font-medium"
                              >-{{ formatCurrency(refundCalculations().adjustmentAmount) }}</span
                            >
                          </div>
                        }
                        <div
                          class="border-border text-foreground flex items-center justify-between border-t pt-1.5 font-bold"
                        >
                          <span>Authorized Net Settlement</span>
                          <span
                            class="font-mono text-sm font-bold tabular-nums"
                            [class.text-success]="selectedRefundAction() === 'store-credit'"
                          >
                            {{ formatCurrency(refundCalculations().totalRefund) }}
                          </span>
                        </div>
                      </div>
                    </div>
                  </div>
    
                  <!-- 3. Internal QC Inspection Notes -->
                  <div ui-card class="border-border shadow-xs">
                    <div ui-card-header class="pb-3">
                      <div class="flex items-center justify-between">
                        <div class="space-y-0.5">
                          <h3 ui-card-title class="text-sm font-semibold">Internal QC Inspection Notes</h3>
                          <p ui-card-description class="text-xs">Station audit log appended to inventory history.</p>
                        </div>
                      </div>
                    </div>
    
                    <div ui-card-content class="space-y-3">
                      <ui-textarea
                        [value]="qcNotes()"
                        (valueChange)="qcNotes.set($event)"
                        [rows]="3"
                        placeholder="Enter internal inspection notes, physical defect description, or warehouse packaging details..."
                        class="text-xs"
                      />
    
                      <!-- Quick Tag Helpers -->
                      <div class="space-y-1.5">
                        <span class="text-muted-foreground block text-xs font-medium">Quick Preset Tags:</span>
                        <div class="flex flex-wrap gap-1.5">
                          <button
                            type="button"
                            class="border-border bg-muted/40 hover:bg-muted text-muted-foreground hover:text-foreground min-h-6 cursor-pointer rounded-md border px-2 py-0.5 text-xs transition-colors"
                            (click)="applyPresetNote('Pristine unworn condition.')"
                          >
                            + Pristine Condition
                          </button>
                          <button
                            type="button"
                            class="border-border bg-muted/40 hover:bg-muted text-muted-foreground hover:text-foreground min-h-6 cursor-pointer rounded-md border px-2 py-0.5 text-xs transition-colors"
                            (click)="applyPresetNote('Minor outer box scuff; shoes mint.')"
                          >
                            + Box Scuffed
                          </button>
                          <button
                            type="button"
                            class="border-border bg-muted/40 hover:bg-muted text-muted-foreground hover:text-foreground min-h-6 cursor-pointer rounded-md border px-2 py-0.5 text-xs transition-colors"
                            (click)="applyPresetNote('Slight sole friction detected.')"
                          >
                            + Sole Friction
                          </button>
                          <button
                            type="button"
                            class="border-border bg-muted/40 hover:bg-muted text-muted-foreground hover:text-foreground min-h-6 cursor-pointer rounded-md border px-2 py-0.5 text-xs transition-colors"
                            (click)="applyPresetNote('Factory seam defect identified - Flagged RTV.')"
                          >
                            + Flagged RTV
                          </button>
                        </div>
                      </div>
                    </div>
    
                    <div ui-card-footer class="border-border bg-muted/15 flex items-center justify-between border-t p-4">
                      <span class="text-muted-foreground text-xs">
                        Audit sign-off: <strong class="text-foreground font-medium">{{ inspectorName }}</strong>
                      </span>
                      <button
                        ui-button
                        size="sm"
                        class="gap-1.5 text-xs font-semibold"
                        (click)="handleCompleteInspection()"
                      >
                        <lucide-icon [img]="FileCheck" class="size-3.5" />
                        Complete Inspection
                      </button>
                    </div>
                  </div>
                </div>
              </div>
            </div>
          }
        </div>
      `,
    })
    export class UiReturnMerchandiseInspectionComponent {
      protected readonly AlertTriangle = AlertTriangle
      protected readonly ArrowRight = ArrowRight
      protected readonly Barcode = Barcode
      protected readonly Box = Box
      protected readonly CheckCircle2 = CheckCircle2
      protected readonly Clock = Clock
      protected readonly CornerDownLeft = CornerDownLeft
      protected readonly CreditCard = CreditCard
      protected readonly Download = Download
      protected readonly FileCheck = FileCheck
      protected readonly Gift = Gift
      protected readonly Package = Package
      protected readonly PackageCheck = PackageCheck
      protected readonly Printer = Printer
      protected readonly Radio = Radio
      protected readonly RotateCcw = RotateCcw
      protected readonly ScanLine = ScanLine
      protected readonly Tag = Tag
      protected readonly UserCheck = UserCheck
      protected readonly Warehouse = Warehouse
    
      protected readonly item = itemData
      protected readonly totalChecklistCount = 4
    
      @Input() set initialRma(v: string | undefined) {
        if (v !== undefined) this.rmaNumber.set(v)
      }
      @Input() set initialGrade(v: ConditionGrade | undefined) {
        if (v !== undefined) this.selectedGrade.set(v)
      }
      @Input() set initialRefundAction(v: RefundAction | undefined) {
        if (v !== undefined) this.selectedRefundAction.set(v)
      }
      @Input() set initialSubmitted(v: boolean | undefined) {
        if (v !== undefined) this.submitted.set(!!v)
      }
      @Input() inspectorName = 'Alex Rivera · QC Lead'
      @Input() stationName = 'Warehouse Returns Intake & Grading Station #02'
      @Input('class') className?: string
      @Output() complete = new EventEmitter<ReturnInspectionData>()
    
      readonly rmaNumber = signal('#RMA-849201')
      readonly selectedGrade = signal<ConditionGrade>('grade-a')
      readonly selectedRefundAction = signal<RefundAction>('full-refund')
      readonly submitted = signal(false)
      readonly qcNotes = signal(defaultQcNotes)
      readonly checklist = signal<InspectionChecklist>({
        tagsAttached: true,
        originalBox: true,
        allAccessories: true,
        odorStainFree: true,
      })
    
      readonly currentGrade = computed(() => gradeDefinitions[this.selectedGrade()])
    
      readonly checkedChecklistCount = computed(() => {
        const c = this.checklist()
        return [c.tagsAttached, c.originalBox, c.allAccessories, c.odorStainFree].filter(Boolean).length
      })
    
      readonly allChecksPassed = computed(() => this.checkedChecklistCount() === this.totalChecklistCount)
    
      readonly refundCalculations = computed(() => {
        const msrp = itemData.msrp
        if (this.selectedRefundAction() === 'store-credit') {
          const bonus = msrp * 0.1
          return {
            subtotal: msrp,
            adjustmentLabel: 'Store Credit Bonus (+10%)',
            adjustmentAmount: bonus,
            isBonus: true,
            totalRefund: msrp + bonus,
            methodLabel: 'Digital Gift Card ([email protected])',
            payoutSpeed: 'Instant email delivery upon grading',
          }
        }
    
        if (this.selectedRefundAction() === 'restock-fee') {
          const fee = 15.0
          return {
            subtotal: msrp,
            adjustmentLabel: 'Restocking & Repacking Fee',
            adjustmentAmount: fee,
            isBonus: false,
            totalRefund: msrp - fee,
            methodLabel: 'Net Credit to Visa •••• 4242',
            payoutSpeed: '3–5 business days to card',
          }
        }
    
        return {
          subtotal: msrp,
          adjustmentLabel: 'Restocking Fee Waived',
          adjustmentAmount: 0,
          isBonus: false,
          totalRefund: msrp,
          methodLabel: 'Full Refund to Visa •••• 4242',
          payoutSpeed: '3–5 business days to card',
        }
      })
    
      get rootClass(): string {
        return cn('text-foreground mx-auto w-full max-w-6xl space-y-6', this.className)
      }
    
      get receiptBannerClass(): string {
        return cn(
          'border-b p-6 text-center sm:p-8',
          this.selectedGrade() === 'grade-d'
            ? 'border-destructive/30 bg-destructive/10'
            : 'border-success/30 bg-success/10',
        )
      }
    
      get receiptGlowClass(): string {
        return cn(
          'absolute inset-0 rounded-full blur-xl',
          this.selectedGrade() === 'grade-d' ? 'bg-destructive/30' : 'bg-success/30',
        )
      }
    
      get receiptIconWrapClass(): string {
        return cn(
          'relative flex size-16 items-center justify-center rounded-full border shadow-xs',
          this.selectedGrade() === 'grade-d'
            ? 'border-destructive/40 bg-destructive/20 text-destructive'
            : 'border-success/40 bg-success/20 text-success',
        )
      }
    
      get receiptBadgeClass(): string {
        return cn(
          'mb-2 font-mono text-xs tracking-wider uppercase',
          this.selectedGrade() !== 'grade-d' && 'border-success/30 bg-success/10 text-success',
        )
      }
    
      get outcomeBannerClass(): string {
        return cn('rounded-lg border p-4 transition-colors', this.currentGrade().activeBorderBg)
      }
    
      gradeCardClass(grade: ConditionGrade): string {
        return cn(
          'flex cursor-pointer items-start gap-3 rounded-lg border p-3.5 transition-colors select-none',
          this.selectedGrade() === grade
            ? gradeDefinitions[grade].activeBorderBg
            : 'border-border bg-card hover:bg-muted/30',
        )
      }
    
      refundCardClass(action: RefundAction): string {
        const active =
          action === 'store-credit'
            ? 'border-success/50 bg-success/5 ring-success/20 dark:bg-success/10 shadow-xs ring-1'
            : 'border-primary bg-primary/[0.03] dark:bg-primary/10 shadow-xs'
        return cn(
          'flex cursor-pointer items-start gap-3 rounded-lg border p-3 transition-colors select-none',
          this.selectedRefundAction() === action ? active : 'border-border bg-card hover:bg-muted/30',
        )
      }
    
      checkRowClass(passed: boolean): string {
        return cn(
          'flex items-start gap-3 rounded-lg border p-3 transition-colors',
          passed ? 'border-border bg-card' : 'border-warning/30 bg-warning/5',
        )
      }
    
      setGrade(value: string): void {
        this.selectedGrade.set(value as ConditionGrade)
      }
    
      setRefundAction(value: string): void {
        this.selectedRefundAction.set(value as RefundAction)
      }
    
      setCheck(key: keyof InspectionChecklist, value: CheckedState): void {
        const checked = value === true
        this.checklist.update((prev) => ({ ...prev, [key]: checked }))
      }
    
      formatCurrency(val: number): string {
        return new Intl.NumberFormat('en-US', {
          style: 'currency',
          currency: 'USD',
          minimumFractionDigits: 2,
        }).format(val)
      }
    
      selectAllChecklist(pass: boolean): void {
        this.checklist.set({ tagsAttached: pass, originalBox: pass, allAccessories: pass, odorStainFree: pass })
      }
    
      applyPresetNote(note: string): void {
        const current = this.qcNotes()
        if (!current.includes(note)) this.qcNotes.set(current ? `${current} ${note}` : note)
      }
    
      handleCompleteInspection(): void {
        this.submitted.set(true)
        const grade = this.currentGrade()
        this.complete.emit({
          rmaNumber: this.rmaNumber(),
          stationId: 'STATION-02-B',
          inspectorName: this.inspectorName,
          returnReason: itemData.returnReason,
          item: {
            name: itemData.name,
            variant: itemData.variant,
            msrp: itemData.msrp,
            sku: itemData.sku,
            upc: itemData.upc,
            verified: true,
          },
          grade: this.selectedGrade(),
          checklist: { ...this.checklist() },
          refundAction: this.selectedRefundAction(),
          qcNotes: this.qcNotes(),
          dispositionOutcome: {
            route: grade.route,
            destinationBin: grade.targetBin,
            lpnCode: grade.lpnCode,
            priority: grade.priority,
          },
        })
      }
    
      handleReset(): void {
        this.submitted.set(false)
        this.selectedGrade.set('grade-a')
        this.selectedRefundAction.set('full-refund')
        this.selectAllChecklist(true)
        this.qcNotes.set(defaultQcNotes)
      }
    }
    
  • src/app/components/blocks/return-merchandise-inspection/index.ts0.2 kB

Raw manifest:https://uipkge.dev/r/angular/return-merchandise-inspection.json