{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "store-pickup-curbside",
  "title": "Store Pickup Curbside",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/store-pickup-curbside/store-pickup-curbside.component.ts",
      "content": "import { Component, DestroyRef, Input, OnInit, computed, inject, signal, ChangeDetectionStrategy } from '@angular/core'\nimport {\n  Bell,\n  Car,\n  Check,\n  CheckCircle2,\n  Clock,\n  Eye,\n  Layers,\n  LucideAngularModule,\n  MapPin,\n  MessageSquare,\n  MoreHorizontal,\n  Navigation,\n  Package,\n  PackageCheck,\n  Phone,\n  Plus,\n  RefreshCw,\n  Search,\n  Store,\n  X,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiAvatarComponent, UiAvatarFallbackComponent } from '@/ui/avatar/avatar.component'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiCardComponent,\n  UiCardContentComponent,\n  UiCardDescriptionComponent,\n  UiCardFooterComponent,\n  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport {\n  UiDropdownMenuComponent,\n  UiDropdownMenuContentComponent,\n  UiDropdownMenuItemComponent,\n  UiDropdownMenuLabelComponent,\n  UiDropdownMenuSeparatorComponent,\n  UiDropdownMenuTriggerComponent,\n} from '@/ui/dropdown-menu/dropdown-menu.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\nimport {\n  UiSelectComponent,\n  UiSelectContentComponent,\n  UiSelectItemComponent,\n  UiSelectTriggerComponent,\n  UiSelectValueComponent,\n} from '@/ui/select/select.component'\nimport {\n  UiTableBodyComponent,\n  UiTableCellComponent,\n  UiTableComponent,\n  UiTableHeadComponent,\n  UiTableHeaderComponent,\n  UiTableRowComponent,\n} from '@/ui/table/table.component'\nimport { UiOrderDetailDialogComponent } from './order-detail-dialog.component'\nimport { UiStorePickupModalsComponent } from './store-pickup-modals.component'\nimport { INITIAL_ORDERS } from './store-pickup-data'\nimport type {\n  ConfirmArrivalPayload,\n  CreateOrderPayload,\n  NotifyChannel,\n  OrderItem,\n  OrderStatus,\n  PickupMode,\n  PickupModeFilter,\n  PickupOrder,\n  PickupStatusFilter,\n  StorePickupCurbsideProps,\n} from './store-pickup-types'\n\nexport type {\n  ConfirmArrivalPayload,\n  CreateOrderPayload,\n  NotifyChannel,\n  OrderItem,\n  OrderStatus,\n  PickupMode,\n  PickupModeFilter,\n  PickupOrder,\n  PickupStatusFilter,\n  StorePickupCurbsideProps,\n}\n\n/**\n * Buy Online Pick Up in Store (BOPIS) & curbside pickup coordination board (React\n * `StorePickupCurbside` 1:1): fulfillment health cards, a searchable / filterable active\n * pickup orders table with per-row fulfillment actions, the order detail dialog and the\n * check-in / notify / new-order dialogs, plus an inline feedback toast.\n */\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-store-pickup-curbside, [ui-store-pickup-curbside]',\n  standalone: true,\n  // React renders the root <div> itself: keep this wrapper out of the layout.\n  host: { class: 'contents' },\n  imports: [\n    LucideAngularModule,\n    UiAvatarComponent,\n    UiAvatarFallbackComponent,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardFooterComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiDropdownMenuComponent,\n    UiDropdownMenuContentComponent,\n    UiDropdownMenuItemComponent,\n    UiDropdownMenuLabelComponent,\n    UiDropdownMenuSeparatorComponent,\n    UiDropdownMenuTriggerComponent,\n    UiInputComponent,\n    UiSelectComponent,\n    UiSelectContentComponent,\n    UiSelectItemComponent,\n    UiSelectTriggerComponent,\n    UiSelectValueComponent,\n    UiTableBodyComponent,\n    UiTableCellComponent,\n    UiTableComponent,\n    UiTableHeadComponent,\n    UiTableHeaderComponent,\n    UiTableRowComponent,\n    UiOrderDetailDialogComponent,\n    UiStorePickupModalsComponent,\n  ],\n  template: `\n    <div data-slot=\"store-pickup-curbside\" [class]=\"rootClass\">\n      <!-- Live Toast Notification Banner -->\n      @if (actionFeedbackToast(); as toast) {\n        <div\n          class=\"border-success/30 bg-success/10 text-success flex items-center justify-between rounded-md border px-4 py-2.5 text-xs font-medium shadow-xs transition-colors duration-200\"\n        >\n          <div class=\"flex items-center gap-2\">\n            <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-4 shrink-0\" />\n            <span>{{ toast }}</span>\n          </div>\n          <button\n            aria-label=\"Dismiss notification\"\n            type=\"button\"\n            class=\"text-muted-foreground hover:text-foreground inline-flex size-4 items-center justify-center\"\n            (click)=\"actionFeedbackToast.set(null)\"\n          >\n            <lucide-icon [img]=\"X\" class=\"size-3.5\" />\n          </button>\n        </div>\n      }\n\n      <!-- Header Section -->\n      <div class=\"flex flex-col gap-4 md:flex-row md:items-center md:justify-between\">\n        <div>\n          <div class=\"flex flex-wrap items-center gap-2.5\">\n            <div\n              class=\"bg-primary/10 text-primary border-primary/20 flex size-8 items-center justify-center rounded-lg border\"\n            >\n              <lucide-icon [img]=\"Car\" class=\"size-4\" />\n            </div>\n            <h1 class=\"text-xl font-bold tracking-tight md:text-2xl\">Store Pickup &amp; Curbside Coordination</h1>\n            <span ui-badge wrap variant=\"outline\" class=\"gap-1.5 font-medium\">\n              <span class=\"bg-success size-1.5 animate-pulse rounded-full\"></span>\n              <span class=\"text-xs\">Live Staging Radar</span>\n            </span>\n          </div>\n          <div class=\"text-muted-foreground mt-1.5 flex flex-wrap items-center gap-2 text-xs\">\n            <span class=\"text-foreground flex items-center gap-1 font-medium\">\n              <lucide-icon [img]=\"MapPin\" class=\"text-muted-foreground size-3.5\" />\n              {{ storeName }}\n            </span>\n            <span class=\"font-mono text-xs\">{{ storeCode }}</span>\n            <span class=\"text-foreground font-medium tabular-nums\">\n              {{ readyInStagingCount() }} Ready · {{ enRouteCount() }} En Route · {{ completedCount() }} Completed\n            </span>\n          </div>\n        </div>\n\n        <div class=\"flex flex-wrap items-center gap-2\">\n          <button\n            ui-button\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"h-9 gap-1.5 text-xs shadow-xs\"\n            (click)=\"checkInModalOpen.set(true)\"\n          >\n            <lucide-icon [img]=\"Car\" class=\"text-warning size-3.5\" />\n            <span>Customer \"I'm Here\" Check-In</span>\n          </button>\n\n          <button ui-button size=\"sm\" class=\"h-9 gap-1.5 text-xs shadow-xs\" (click)=\"newOrderModalOpen.set(true)\">\n            <lucide-icon [img]=\"Plus\" class=\"size-3.5\" />\n            <span>New Pickup Order</span>\n          </button>\n        </div>\n      </div>\n\n      <!-- 4 Fulfillment Health Cards -->\n      <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n        <!-- Card 1: Ready in Staging -->\n        <div ui-card class=\"border-border shadow-xs\">\n          <div ui-card-header class=\"flex flex-row flex-wrap items-center justify-between gap-2 pb-2\">\n            <h3 ui-card-title class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n              Ready for Customer\n            </h3>\n            <div class=\"bg-muted text-muted-foreground flex size-7 items-center justify-center rounded-md\">\n              <lucide-icon [img]=\"PackageCheck\" class=\"text-foreground size-4\" />\n            </div>\n          </div>\n          <div ui-card-content class=\"space-y-1.5\">\n            <div class=\"text-2xl font-bold tracking-tight tabular-nums\">8 Orders in Staging</div>\n            <div class=\"text-muted-foreground flex flex-wrap items-center justify-between gap-x-2 gap-y-1 text-xs\">\n              <span>6 Bins · 2 Secured Lockers</span>\n              <span ui-badge wrap variant=\"success\" class=\"h-5 px-1.5 text-xs font-medium\">100% Pick Accuracy</span>\n            </div>\n          </div>\n        </div>\n\n        <!-- Card 2: Arrived in Curbside Bay (Amber Alert) -->\n        <div ui-card class=\"border-warning/30 bg-warning/5 shadow-xs\">\n          <div ui-card-header class=\"flex flex-row flex-wrap items-center justify-between gap-2 pb-2\">\n            <h3\n              ui-card-title\n              class=\"text-warning text-warning min-w-0 text-xs font-semibold tracking-wider break-words uppercase\"\n            >\n              Customers in Parking Bays\n            </h3>\n            <div class=\"bg-warning/15 text-warning flex size-7 items-center justify-center rounded-md\">\n              <lucide-icon [img]=\"Car\" class=\"text-warning size-4\" />\n            </div>\n          </div>\n          <div ui-card-content class=\"space-y-1.5\">\n            <div class=\"text-foreground dark:text-foreground text-2xl font-bold tracking-tight tabular-nums\">\n              {{ arrivedCustomersCount() }} Customers Arrived\n            </div>\n            <div class=\"text-muted-foreground flex flex-wrap items-center justify-between gap-x-2 gap-y-1 text-xs\">\n              <span class=\"text-warning/80 text-warning/80\">Bay #4 (2m) · Bay #2 (4m)</span>\n              <span ui-badge wrap variant=\"warning\" class=\"h-5 gap-1 px-1.5 text-xs font-medium\">\n                <span class=\"bg-warning bg-warning size-1.5 rounded-full\"></span>\n                Action Required\n              </span>\n            </div>\n          </div>\n        </div>\n\n        <!-- Card 3: Avg Fulfillment Time -->\n        <div ui-card class=\"border-border shadow-xs\">\n          <div ui-card-header class=\"flex flex-row flex-wrap items-center justify-between gap-2 pb-2\">\n            <h3 ui-card-title class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n              Avg Fulfillment Time\n            </h3>\n            <div class=\"bg-muted text-muted-foreground flex size-7 items-center justify-center rounded-md\">\n              <lucide-icon [img]=\"Clock\" class=\"text-foreground size-4\" />\n            </div>\n          </div>\n          <div ui-card-content class=\"space-y-1.5\">\n            <div class=\"text-2xl font-bold tracking-tight tabular-nums\">1m 45s</div>\n            <div class=\"text-muted-foreground flex flex-wrap items-center justify-between gap-x-2 gap-y-1 text-xs\">\n              <span>Goal &lt; 3m 00s (-18s vs target)</span>\n              <span ui-badge wrap variant=\"info\" class=\"h-5 px-1.5 text-xs font-medium\">Fastest: 52s</span>\n            </div>\n          </div>\n        </div>\n\n        <!-- Card 4: Today's Completed Pickups -->\n        <div ui-card class=\"border-border shadow-xs\">\n          <div ui-card-header class=\"flex flex-row flex-wrap items-center justify-between gap-2 pb-2\">\n            <h3 ui-card-title class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n              Today's Pickups\n            </h3>\n            <div class=\"bg-muted text-muted-foreground flex size-7 items-center justify-center rounded-md\">\n              <lucide-icon [img]=\"CheckCircle2\" class=\"text-foreground size-4\" />\n            </div>\n          </div>\n          <div ui-card-content class=\"space-y-1.5\">\n            <div class=\"text-2xl font-bold tracking-tight tabular-nums\">{{ completedCount() }} Orders</div>\n            <div class=\"text-muted-foreground flex flex-wrap items-center justify-between gap-x-2 gap-y-1 text-xs\">\n              <span>$5,240 Fulfilled Volume</span>\n              <span ui-badge wrap variant=\"success\" class=\"h-5 px-1.5 text-xs font-medium\">97.2% On-Time SLA</span>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <!-- Active Pickup Orders Board / Table Card -->\n      <div ui-card class=\"border-border shadow-xs\">\n        <div ui-card-header class=\"space-y-4 pb-4\">\n          <div class=\"flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between\">\n            <div>\n              <h3 ui-card-title class=\"text-base font-semibold\">Active Pickup Orders Board</h3>\n              <p ui-card-description class=\"text-xs\">\n                Live queue of customers arriving curbside and checking in at in-store fulfillment stations.\n              </p>\n            </div>\n            <div class=\"flex items-center gap-2\">\n              <button\n                ui-button\n                variant=\"outline\"\n                size=\"sm\"\n                class=\"h-8 gap-1.5 text-xs shadow-xs\"\n                (click)=\"handleRefresh()\"\n              >\n                <lucide-icon [img]=\"RefreshCw\" class=\"text-muted-foreground size-3\" />\n                <span>Refresh</span>\n              </button>\n            </div>\n          </div>\n\n          <!-- Filter & Search Controls -->\n          <div class=\"flex flex-col gap-2.5 sm:flex-row sm:items-center sm:justify-between\">\n            <div class=\"relative max-w-sm flex-1\">\n              <!-- [class], not class=: a static class lands on both lucide-icon's host and its svg,\n                   which would apply the absolute offset twice. -->\n              <lucide-icon\n                [img]=\"Search\"\n                [class]=\"'text-muted-foreground absolute top-1/2 left-2.5 size-3.5 -translate-y-1/2'\"\n              />\n              <ui-input\n                [value]=\"searchQuery()\"\n                (valueChange)=\"searchQuery.set($event)\"\n                placeholder=\"Search customer, order #, spot, or items...\"\n                class=\"h-8 pl-8 text-xs\"\n              />\n              @if (searchQuery()) {\n                <button\n                  type=\"button\"\n                  class=\"text-muted-foreground hover:text-foreground absolute top-1/2 right-2.5 -translate-y-1/2\"\n                  aria-label=\"Clear search\"\n                  (click)=\"searchQuery.set('')\"\n                >\n                  <lucide-icon [img]=\"X\" class=\"size-3\" />\n                </button>\n              }\n            </div>\n\n            <div class=\"flex flex-wrap items-center gap-2\">\n              <div class=\"flex items-center gap-1.5\">\n                <span class=\"text-muted-foreground text-xs\">Mode:</span>\n                <ui-select [value]=\"selectedModeFilter()\" (valueChange)=\"setModeFilter($event)\">\n                  <button ui-select-trigger class=\"h-8 w-32 text-xs\">\n                    <ui-select-value placeholder=\"Pickup Mode\" />\n                  </button>\n                  <ui-select-content>\n                    <ui-select-item value=\"all\">All Modes</ui-select-item>\n                    <ui-select-item value=\"curbside\">Curbside Bay</ui-select-item>\n                    <ui-select-item value=\"in_store\">In-Store Desk</ui-select-item>\n                  </ui-select-content>\n                </ui-select>\n              </div>\n\n              <div class=\"flex items-center gap-1.5\">\n                <span class=\"text-muted-foreground text-xs\">Status:</span>\n                <ui-select [value]=\"selectedStatusFilter()\" (valueChange)=\"setStatusFilter($event)\">\n                  <button ui-select-trigger class=\"h-8 w-36 text-xs\">\n                    <ui-select-value placeholder=\"Status\" />\n                  </button>\n                  <ui-select-content>\n                    <ui-select-item value=\"all\">All Statuses</ui-select-item>\n                    <ui-select-item value=\"arrived\">Customer Arrived</ui-select-item>\n                    <ui-select-item value=\"en_route\">En Route</ui-select-item>\n                    <ui-select-item value=\"ready_staging\">Ready in Staging</ui-select-item>\n                    <ui-select-item value=\"completed\">Completed</ui-select-item>\n                  </ui-select-content>\n                </ui-select>\n              </div>\n            </div>\n          </div>\n        </div>\n\n        <div ui-card-content class=\"p-0\">\n          <div class=\"overflow-x-auto\">\n            <div ui-table>\n              <thead ui-table-header class=\"bg-muted/40\">\n                <tr ui-table-row>\n                  <th ui-table-head class=\"w-[200px] text-xs font-semibold\">Customer &amp; Contact</th>\n                  <th ui-table-head class=\"w-[180px] text-xs font-semibold\">Order &amp; Items</th>\n                  <th ui-table-head class=\"w-[220px] text-xs font-semibold\">Pickup Mode &amp; Bay</th>\n                  <th ui-table-head class=\"w-[200px] text-xs font-semibold\">Customer Status</th>\n                  <th ui-table-head class=\"w-[160px] text-xs font-semibold\">Staging Location</th>\n                  <th ui-table-head class=\"w-[180px] text-right text-xs font-semibold\">Fulfillment Actions</th>\n                </tr>\n              </thead>\n              <tbody ui-table-body>\n                @for (order of filteredOrders(); track order.id) {\n                  <tr ui-table-row [class]=\"rowClass(order)\">\n                    <!-- Customer Name & Phone -->\n                    <td ui-table-cell class=\"py-3\">\n                      <div class=\"flex items-center gap-2.5\">\n                        <span ui-avatar class=\"border-border size-8 rounded-full border\">\n                          <span ui-avatar-fallback class=\"bg-muted text-xs font-medium\">{{\n                            order.customerInitials\n                          }}</span>\n                        </span>\n                        <div class=\"space-y-0.5\">\n                          <div class=\"text-foreground text-xs leading-tight font-semibold\">\n                            {{ order.customerName }}\n                          </div>\n                          <div class=\"text-muted-foreground flex items-center gap-1 font-mono text-xs tabular-nums\">\n                            <lucide-icon [img]=\"Phone\" class=\"text-muted-foreground/70 size-3\" />\n                            {{ order.customerPhone }}\n                          </div>\n                        </div>\n                      </div>\n                    </td>\n\n                    <!-- Order Number & Items Summary -->\n                    <td ui-table-cell class=\"py-3\">\n                      <div class=\"space-y-1\">\n                        <div class=\"flex items-center gap-1.5\">\n                          <span class=\"text-foreground font-mono text-xs font-bold\">#{{ order.orderNumber }}</span>\n                          <span class=\"text-muted-foreground text-xs tabular-nums\"\n                            >(\\${{ order.orderTotal.toFixed(2) }})</span\n                          >\n                        </div>\n                        <div\n                          class=\"text-muted-foreground max-w-[170px] min-w-0 truncate text-xs\"\n                          [title]=\"itemsTitle(order)\"\n                        >\n                          {{ order.items.length }} {{ order.items.length === 1 ? 'item' : 'items' }}:\n                          {{ itemNames(order) }}\n                        </div>\n                      </div>\n                    </td>\n\n                    <!-- Pickup Mode Badge -->\n                    <td ui-table-cell class=\"py-3\">\n                      <div class=\"space-y-1\">\n                        @if (order.pickupMode === 'curbside') {\n                          <span\n                            ui-badge\n                            wrap\n                            variant=\"outline\"\n                            class=\"border-success/30 bg-success/10 text-success gap-1 font-medium\"\n                          >\n                            <lucide-icon [img]=\"Car\" class=\"text-success size-3 shrink-0\" />\n                            <span>Curbside Spot #{{ order.spotNumber }}</span>\n                          </span>\n                          @if (order.vehicleDetails; as vehicle) {\n                            <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                              <span class=\"max-w-[180px] truncate\">{{ vehicle.makeModel }}</span>\n                              <span class=\"text-foreground font-mono font-medium\">· {{ vehicle.plate }}</span>\n                            </div>\n                          }\n                        } @else {\n                          <span\n                            ui-badge\n                            wrap\n                            variant=\"outline\"\n                            class=\"border-info/30 bg-info/10 text-info gap-1 font-medium\"\n                          >\n                            <lucide-icon [img]=\"Store\" class=\"text-info size-3 shrink-0\" />\n                            <span>In-Store Desk</span>\n                          </span>\n                          <div class=\"text-muted-foreground text-xs\">\n                            {{ order.pickupDeskBay || 'Front Pickup Counter' }}\n                          </div>\n                        }\n                      </div>\n                    </td>\n\n                    <!-- Customer Status -->\n                    <td ui-table-cell class=\"py-3\">\n                      <div class=\"space-y-1\">\n                        @switch (order.status) {\n                          @case ('arrived') {\n                            <span ui-badge wrap variant=\"warning\" class=\"gap-1.5 px-2 py-0.5 font-medium\">\n                              <span class=\"bg-warning size-1.5 rounded-full\"></span>\n                              <lucide-icon [img]=\"Clock\" class=\"size-3\" />\n                              <span class=\"tabular-nums\">Customer Arrived · Waiting {{ order.waitMinutes || 2 }}m</span>\n                            </span>\n                            <div class=\"text-muted-foreground flex items-center gap-1 text-xs\">\n                              <span>Check-in: {{ order.arrivedAt || '11:40 AM' }}</span>\n                              @if (order.vehicleDetails?.hazardsFlashing) {\n                                <span class=\"text-warning font-medium\">· Hazards On</span>\n                              }\n                            </div>\n                          }\n                          @case ('en_route') {\n                            <span ui-badge wrap variant=\"info\" class=\"gap-1.5 px-2 py-0.5 font-medium\">\n                              <lucide-icon [img]=\"Navigation\" class=\"text-info size-3\" />\n                              <span class=\"tabular-nums\">En Route · {{ order.etaMinutes }} min ETA</span>\n                            </span>\n                            <div class=\"text-muted-foreground text-xs\">\n                              <span class=\"tabular-nums\">{{ order.distanceMiles }} miles away</span>\n                            </div>\n                          }\n                          @case ('ready_staging') {\n                            <span ui-badge wrap variant=\"secondary\" class=\"gap-1.5 px-2 py-0.5 font-medium\">\n                              <lucide-icon [img]=\"Package\" class=\"size-3\" />\n                              <span>Ready in Staging</span>\n                            </span>\n                            <div class=\"text-muted-foreground text-xs\">Staged at {{ order.readyAt }}</div>\n                          }\n                          @default {\n                            <span ui-badge wrap variant=\"success\" class=\"gap-1.5 px-2 py-0.5 font-medium\">\n                              <lucide-icon [img]=\"CheckCircle2\" class=\"size-3\" />\n                              <span>Delivered</span>\n                            </span>\n                            <div class=\"text-muted-foreground text-xs\">Completed Handoff</div>\n                          }\n                        }\n                      </div>\n                    </td>\n\n                    <!-- Staging Location -->\n                    <td ui-table-cell class=\"py-3\">\n                      <div class=\"space-y-0.5\">\n                        <div class=\"text-foreground flex items-center gap-1.5 text-xs font-semibold\">\n                          <lucide-icon [img]=\"Layers\" class=\"text-muted-foreground size-3.5\" />\n                          <span>{{ order.stagingLocation.zone }}</span>\n                          <span class=\"text-primary font-mono font-bold\">{{ order.stagingLocation.bin }}</span>\n                        </div>\n                        @if (order.stagingLocation.lockerPin) {\n                          <div class=\"text-muted-foreground font-mono text-xs\">\n                            PIN Code:\n                            <span class=\"text-foreground font-bold\">{{ order.stagingLocation.lockerPin }}</span>\n                          </div>\n                        } @else {\n                          <div class=\"text-muted-foreground text-xs capitalize\">\n                            Type: {{ order.stagingLocation.type }} staging\n                          </div>\n                        }\n                      </div>\n                    </td>\n\n                    <!-- Fulfillment Actions -->\n                    <td ui-table-cell class=\"py-3 text-right\">\n                      <div class=\"flex items-center justify-end gap-1.5\">\n                        @if (order.status === 'arrived') {\n                          <button\n                            ui-button\n                            size=\"sm\"\n                            class=\"bg-success hover:bg-success/90 bg-success dark:hover:bg-success/90 h-8 gap-1 px-2.5 text-xs font-medium text-white shadow-xs\"\n                            (click)=\"handleMarkDelivered(order.id)\"\n                          >\n                            <lucide-icon [img]=\"Check\" class=\"size-3.5\" />\n                            <span>Mark Delivered</span>\n                          </button>\n                        } @else if (order.status !== 'completed') {\n                          <button\n                            ui-button\n                            variant=\"outline\"\n                            size=\"sm\"\n                            class=\"h-8 gap-1 px-2.5 text-xs shadow-xs\"\n                            (click)=\"handleNotify(order)\"\n                          >\n                            <lucide-icon [img]=\"Bell\" class=\"text-muted-foreground size-3\" />\n                            <span>Notify</span>\n                          </button>\n                        } @else {\n                          <button ui-button variant=\"outline\" size=\"sm\" disabled class=\"h-8 text-xs opacity-60\">\n                            <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-3\" />\n                            <span>Fulfilled</span>\n                          </button>\n                        }\n\n                        <ui-dropdown-menu>\n                          <button\n                            ui-button\n                            ui-dropdown-menu-trigger\n                            variant=\"ghost\"\n                            size=\"icon\"\n                            class=\"text-muted-foreground hover:text-foreground size-8\"\n                          >\n                            <lucide-icon [img]=\"MoreHorizontal\" class=\"size-4\" />\n                            <span class=\"sr-only\">Actions</span>\n                          </button>\n                          <ui-dropdown-menu-content align=\"end\" class=\"w-48 text-xs\">\n                            <ui-dropdown-menu-label>Order #{{ order.orderNumber }}</ui-dropdown-menu-label>\n                            <ui-dropdown-menu-separator />\n                            <ui-dropdown-menu-item class=\"cursor-pointer gap-2\" (select)=\"handleInspect(order)\">\n                              <lucide-icon [img]=\"Eye\" class=\"text-muted-foreground size-3.5\" />\n                              <span>Inspect Order Details</span>\n                            </ui-dropdown-menu-item>\n                            <ui-dropdown-menu-item class=\"cursor-pointer gap-2\" (select)=\"handleNotify(order)\">\n                              <lucide-icon [img]=\"MessageSquare\" class=\"text-muted-foreground size-3.5\" />\n                              <span>Send SMS / Push Alert</span>\n                            </ui-dropdown-menu-item>\n                            <ui-dropdown-menu-separator />\n                            @if (order.status !== 'completed') {\n                              <ui-dropdown-menu-item\n                                class=\"text-success cursor-pointer gap-2 font-medium\"\n                                (select)=\"handleMarkDelivered(order.id)\"\n                              >\n                                <lucide-icon [img]=\"CheckCircle2\" class=\"size-3.5\" />\n                                <span>Complete Handoff</span>\n                              </ui-dropdown-menu-item>\n                            }\n                          </ui-dropdown-menu-content>\n                        </ui-dropdown-menu>\n                      </div>\n                    </td>\n                  </tr>\n                }\n\n                @if (filteredOrders().length === 0) {\n                  <tr ui-table-row>\n                    <td ui-table-cell colspan=\"6\" class=\"text-muted-foreground h-32 text-center text-xs\">\n                      No pickup orders match your search or filter criteria.\n                    </td>\n                  </tr>\n                }\n              </tbody>\n            </div>\n          </div>\n        </div>\n        <div\n          ui-card-footer\n          class=\"border-border text-muted-foreground flex items-center justify-between border-t px-6 py-3 text-xs\"\n        >\n          <div>\n            Showing <span class=\"text-foreground font-medium tabular-nums\">{{ filteredOrders().length }}</span> of\n            <span class=\"text-foreground font-medium tabular-nums\">{{ orders().length }}</span> active pickup orders\n          </div>\n          <div class=\"flex items-center gap-3\">\n            <div class=\"flex items-center gap-1.5\">\n              <span class=\"bg-success size-2 rounded-full\"></span>\n              <span>Curbside Bays (Spots 1-6)</span>\n            </div>\n            <div class=\"flex items-center gap-1.5\">\n              <span class=\"bg-info size-2 rounded-full\"></span>\n              <span>In-Store Pickup Desk</span>\n            </div>\n          </div>\n        </div>\n      </div>\n    </div>\n\n    <!-- The dialogs portal to <body>. They sit outside the root so they are not space-y children: React renders nothing in place. -->\n    <!-- Modal 1: Inspect Order Details Dialog -->\n    <ui-order-detail-dialog\n      [open]=\"inspectModalOpen()\"\n      (openChange)=\"inspectModalOpen.set($event)\"\n      [selectedOrder]=\"selectedOrder()\"\n      (markDelivered)=\"handleMarkDelivered($event)\"\n    />\n\n    <!-- Action Modals (Check-In, Notify, New Order) -->\n    <ui-store-pickup-modals\n      [checkInModalOpen]=\"checkInModalOpen()\"\n      (checkInModalOpenChange)=\"checkInModalOpen.set($event)\"\n      [notifyModalOpen]=\"notifyModalOpen()\"\n      (notifyModalOpenChange)=\"notifyModalOpen.set($event)\"\n      [newOrderModalOpen]=\"newOrderModalOpen()\"\n      (newOrderModalOpenChange)=\"newOrderModalOpen.set($event)\"\n      [orders]=\"orders()\"\n      [selectedOrder]=\"selectedOrder()\"\n      [storeName]=\"storeName\"\n      (confirmArrival)=\"handleConfirmArrival($event)\"\n      (sendNotification)=\"handleSendNotification($event)\"\n      (createOrder)=\"handleCreateNewOrder($event)\"\n    />\n  `,\n})\nexport class UiStorePickupCurbsideComponent implements OnInit {\n  @Input() storeName = 'Pasadena Flagship Store #02'\n  @Input() storeCode = 'STORE-CA-02'\n  @Input() initialModeFilter: PickupModeFilter = 'all'\n  @Input('class') className?: string\n\n  readonly orders = signal<PickupOrder[]>(INITIAL_ORDERS)\n  readonly searchQuery = signal('')\n  readonly selectedModeFilter = signal<PickupModeFilter>('all')\n  readonly selectedStatusFilter = signal<PickupStatusFilter>('all')\n\n  // Modals\n  readonly checkInModalOpen = signal(false)\n  readonly inspectModalOpen = signal(false)\n  readonly notifyModalOpen = signal(false)\n  readonly newOrderModalOpen = signal(false)\n  readonly selectedOrder = signal<PickupOrder | null>(null)\n  readonly actionFeedbackToast = signal<string | null>(null)\n\n  // KPI calculations\n  readonly readyInStagingCount = computed(() => this.orders().filter((o) => o.status !== 'completed').length)\n  readonly arrivedCustomersCount = computed(() => this.orders().filter((o) => o.status === 'arrived').length)\n  readonly enRouteCount = computed(() => this.orders().filter((o) => o.status === 'en_route').length)\n  readonly completedCount = computed(() => this.orders().filter((o) => o.status === 'completed').length + 32)\n\n  // Filtered orders list\n  readonly filteredOrders = computed(() => {\n    const query = this.searchQuery().trim().toLowerCase()\n    const mode = this.selectedModeFilter()\n    const status = this.selectedStatusFilter()\n    return this.orders().filter((order) => {\n      const matchesSearch =\n        query === '' ||\n        order.customerName.toLowerCase().includes(query) ||\n        order.orderNumber.toLowerCase().includes(query) ||\n        order.customerPhone.includes(query) ||\n        order.stagingLocation.bin.toLowerCase().includes(query) ||\n        (order.vehicleDetails?.makeModel.toLowerCase().includes(query) ?? false) ||\n        (order.vehicleDetails?.plate.toLowerCase().includes(query) ?? false) ||\n        order.items.some((i) => i.name.toLowerCase().includes(query))\n\n      const matchesMode = mode === 'all' || order.pickupMode === mode\n      const matchesStatus = status === 'all' || order.status === status\n\n      return matchesSearch && matchesMode && matchesStatus\n    })\n  })\n\n  protected readonly Bell = Bell\n  protected readonly Car = Car\n  protected readonly Check = Check\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Clock = Clock\n  protected readonly Eye = Eye\n  protected readonly Layers = Layers\n  protected readonly MapPin = MapPin\n  protected readonly MessageSquare = MessageSquare\n  protected readonly MoreHorizontal = MoreHorizontal\n  protected readonly Navigation = Navigation\n  protected readonly Package = Package\n  protected readonly PackageCheck = PackageCheck\n  protected readonly Phone = Phone\n  protected readonly Plus = Plus\n  protected readonly RefreshCw = RefreshCw\n  protected readonly Search = Search\n  protected readonly Store = Store\n  protected readonly X = X\n\n  private readonly timers = new Set<ReturnType<typeof setTimeout>>()\n\n  constructor() {\n    inject(DestroyRef).onDestroy(() => this.timers.forEach((t) => clearTimeout(t)))\n  }\n\n  ngOnInit(): void {\n    // React: useState(initialModeFilter) -- the prop only seeds the filter.\n    this.selectedModeFilter.set(this.initialModeFilter)\n  }\n\n  protected get rootClass(): string {\n    return cn('text-foreground w-full space-y-6', this.className)\n  }\n\n  protected rowClass(order: PickupOrder): string {\n    return cn('transition-colors duration-150', order.status === 'arrived' && 'bg-warning/[0.04] bg-warning/[0.08]')\n  }\n\n  protected itemsTitle(order: PickupOrder): string {\n    return order.items.map((i) => `${i.quantity}x ${i.name}`).join(', ')\n  }\n\n  protected itemNames(order: PickupOrder): string {\n    return order.items.map((i) => i.name).join(', ')\n  }\n\n  protected setModeFilter(value: string): void {\n    if (value === 'all' || value === 'curbside' || value === 'in_store') this.selectedModeFilter.set(value)\n  }\n\n  protected setStatusFilter(value: string): void {\n    if (\n      value === 'all' ||\n      value === 'arrived' ||\n      value === 'en_route' ||\n      value === 'ready_staging' ||\n      value === 'completed'\n    )\n      this.selectedStatusFilter.set(value)\n  }\n\n  /** Toast feedback helper: shows `msg` for 3.5s unless a newer message replaced it. */\n  triggerToast(msg: string): void {\n    this.actionFeedbackToast.set(msg)\n    const t = setTimeout(() => {\n      this.timers.delete(t)\n      if (this.actionFeedbackToast() === msg) this.actionFeedbackToast.set(null)\n    }, 3500)\n    this.timers.add(t)\n  }\n\n  handleInspect(order: PickupOrder): void {\n    this.selectedOrder.set(order)\n    this.inspectModalOpen.set(true)\n  }\n\n  handleNotify(order: PickupOrder): void {\n    this.selectedOrder.set(order)\n    this.notifyModalOpen.set(true)\n  }\n\n  handleSendNotification(channel: NotifyChannel): void {\n    const selected = this.selectedOrder()\n    if (!selected) return\n    this.notifyModalOpen.set(false)\n    this.triggerToast(`Sent arrival notification to ${selected.customerName} via ${channel.toUpperCase()}`)\n  }\n\n  handleMarkDelivered(orderId: string): void {\n    const target = this.orders().find((o) => o.id === orderId)\n    this.orders.update((prev) =>\n      prev.map((o) => (o.id === orderId ? { ...o, status: 'completed', statusLabel: 'Delivered & Handed Over' } : o)),\n    )\n    if (target) this.triggerToast(`Order #${target.orderNumber} successfully delivered to ${target.customerName}!`)\n    this.inspectModalOpen.set(false)\n  }\n\n  handleConfirmArrival(payload: ConfirmArrivalPayload): void {\n    const target = this.orders().find((o) => o.id === payload.orderId)\n    if (!target) return\n    this.orders.update((prev) =>\n      prev.map((o) =>\n        o.id === payload.orderId\n          ? {\n              ...o,\n              status: 'arrived',\n              pickupMode: 'curbside',\n              spotNumber: parseInt(payload.spot, 10) || 4,\n              waitMinutes: 1,\n              statusLabel: 'Customer Arrived · Waiting 1m',\n              vehicleDetails: {\n                makeModel: payload.vehicleModel || 'Vehicle Unspecified',\n                plate: payload.plate || 'N/A',\n                hazardsFlashing: payload.hazards,\n              },\n              arrivedAt: 'Just now',\n            }\n          : o,\n      ),\n    )\n    this.checkInModalOpen.set(false)\n    this.triggerToast(`Customer ${target.customerName} checked into Spot #${payload.spot}! Runner alerted.`)\n  }\n\n  handleCreateNewOrder(payload: CreateOrderPayload): void {\n    const idNum = Math.floor(10000 + Math.random() * 90000)\n    const newOrder: PickupOrder = {\n      id: `order-${Date.now()}`,\n      orderNumber: `BOPIS-${idNum}`,\n      customerName: payload.customerName,\n      customerPhone: payload.customerPhone || '(415) 555-0100',\n      customerInitials: payload.customerName\n        .split(' ')\n        .map((n) => n[0])\n        .join('')\n        .toUpperCase()\n        .slice(0, 2),\n      pickupMode: payload.pickupMode,\n      spotNumber: payload.pickupMode === 'curbside' ? parseInt(payload.spotNumber, 10) || 3 : undefined,\n      pickupDeskBay: payload.pickupMode === 'in_store' ? 'Pickup Desk Bay 02' : undefined,\n      vehicleDetails:\n        payload.pickupMode === 'curbside'\n          ? {\n              makeModel: 'Customer Vehicle',\n              plate: 'PENDING',\n              hazardsFlashing: false,\n            }\n          : undefined,\n      status: 'ready_staging',\n      statusLabel: `Ready in ${payload.stagingAisle}`,\n      stagingLocation: {\n        zone: payload.stagingAisle,\n        bin: payload.stagingBin,\n        type: payload.pickupMode === 'in_store' ? 'locker' : 'shelf',\n      },\n      items: [\n        {\n          id: `item-${Date.now()}`,\n          name: payload.itemSummary || 'Selected Retail Merchandise',\n          sku: `SKU-${Math.floor(100 + Math.random() * 900)}`,\n          quantity: 1,\n          price: parseFloat(payload.orderTotal) || 99.0,\n          staged: true,\n          category: 'General',\n        },\n      ],\n      orderTotal: parseFloat(payload.orderTotal) || 99.0,\n      placedAt: '11:45 AM',\n      readyAt: 'Just now',\n      verificationCode: `${Math.floor(1000 + Math.random() * 9000)}`,\n      assignedRunner: 'Pending Handoff',\n    }\n\n    this.orders.update((prev) => [newOrder, ...prev])\n    this.newOrderModalOpen.set(false)\n    this.triggerToast(`New Order #${newOrder.orderNumber} staged in ${newOrder.stagingLocation.bin}!`)\n  }\n\n  handleRefresh(): void {\n    this.triggerToast('Refreshed pickup staging queue & curbside telemetry')\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/store-pickup-curbside/store-pickup-curbside.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/store-pickup-curbside/order-detail-dialog.component.ts",
      "content": "import { Component, EventEmitter, Input, Output, ChangeDetectionStrategy } from '@angular/core'\nimport { Car, Check, CheckCircle2, Layers, LucideAngularModule } from 'lucide-angular'\nimport { UiAvatarComponent, UiAvatarFallbackComponent } from '@/ui/avatar/avatar.component'\nimport { UiBadgeComponent } from '@/ui/badge/badge.component'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiDialogComponent,\n  UiDialogContentComponent,\n  UiDialogDescriptionComponent,\n  UiDialogFooterComponent,\n  UiDialogHeaderComponent,\n  UiDialogTitleComponent,\n} from '@/ui/dialog/dialog.component'\nimport type { OrderItem, PickupOrder } from './store-pickup-types'\n\n/**\n * \"Inspect Order Details\" dialog of the store-pickup-curbside block (React `OrderDetailDialog`):\n * customer + verification PIN strip, staging bin and vehicle / bay cards, the staged items\n * checklist, and a \"Mark Delivered & Close\" action for orders not yet handed over.\n */\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-order-detail-dialog, [ui-order-detail-dialog]',\n  standalone: true,\n  host: { class: 'contents' },\n  imports: [\n    LucideAngularModule,\n    UiAvatarComponent,\n    UiAvatarFallbackComponent,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiDialogComponent,\n    UiDialogContentComponent,\n    UiDialogDescriptionComponent,\n    UiDialogFooterComponent,\n    UiDialogHeaderComponent,\n    UiDialogTitleComponent,\n  ],\n  template: `\n    <ui-dialog [open]=\"open\" (openChange)=\"openChange.emit($event)\">\n      <ui-dialog-content class=\"sm:max-w-lg\">\n        @if (selectedOrder; as order) {\n          <div ui-dialog-header>\n            <div class=\"flex items-start justify-between\">\n              <div>\n                <div class=\"flex items-center gap-2\">\n                  <h2 ui-dialog-title class=\"text-base font-bold\">Order #{{ order.orderNumber }}</h2>\n                  <span\n                    ui-badge\n                    wrap\n                    [variant]=\"order.pickupMode === 'curbside' ? 'success' : 'info'\"\n                    class=\"text-xs font-medium\"\n                  >\n                    {{ order.pickupMode === 'curbside' ? 'Curbside Bay #' + order.spotNumber : 'In-Store Desk' }}\n                  </span>\n                </div>\n                <p ui-dialog-description class=\"mt-1 text-xs\">\n                  Placed at {{ order.placedAt }} · Staged at {{ order.readyAt }}\n                </p>\n              </div>\n            </div>\n          </div>\n\n          <div class=\"space-y-4 py-2 text-xs\">\n            <!-- Customer & Contact Strip -->\n            <div class=\"border-border bg-muted/30 flex items-center justify-between rounded-lg border p-3\">\n              <div class=\"flex items-center gap-2.5\">\n                <span ui-avatar class=\"border-border size-9 border\">\n                  <span ui-avatar-fallback class=\"text-xs font-bold\">{{ order.customerInitials }}</span>\n                </span>\n                <div>\n                  <div class=\"text-foreground text-xs font-semibold\">{{ order.customerName }}</div>\n                  <div class=\"text-muted-foreground font-mono text-xs\">{{ order.customerPhone }}</div>\n                </div>\n              </div>\n              <div class=\"text-right\">\n                <div class=\"text-muted-foreground text-xs\">Pickup Verification PIN</div>\n                <div class=\"text-primary font-mono text-sm font-bold tracking-widest\">\n                  {{ order.verificationCode }}\n                </div>\n              </div>\n            </div>\n\n            <!-- Staging & Bay Location Details -->\n            <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n              <div class=\"border-border space-y-1 rounded-md border p-2.5\">\n                <div class=\"text-muted-foreground flex items-center gap-1 text-xs font-medium\">\n                  <lucide-icon [img]=\"Layers\" class=\"size-3.5\" />\n                  <span>Staging Bin Location</span>\n                </div>\n                <div class=\"text-foreground text-xs font-bold\">\n                  {{ order.stagingLocation.zone }} ·\n                  <span class=\"text-primary font-mono\">{{ order.stagingLocation.bin }}</span>\n                </div>\n                <div class=\"text-muted-foreground text-xs capitalize\">\n                  {{ order.stagingLocation.type }} unit storage\n                </div>\n              </div>\n\n              <div class=\"border-border space-y-1 rounded-md border p-2.5\">\n                <div class=\"text-muted-foreground flex items-center gap-1 text-xs font-medium\">\n                  <lucide-icon [img]=\"Car\" class=\"size-3.5\" />\n                  <span>Vehicle &amp; Bay</span>\n                </div>\n                @if (order.pickupMode === 'curbside' && order.vehicleDetails) {\n                  <div class=\"text-foreground truncate text-xs font-bold\">\n                    Spot #{{ order.spotNumber }} · {{ order.vehicleDetails.makeModel }}\n                  </div>\n                  <div class=\"text-muted-foreground font-mono text-xs\">Plate: {{ order.vehicleDetails.plate }}</div>\n                } @else {\n                  <div class=\"text-foreground text-xs font-bold\">{{ order.pickupDeskBay || 'Pickup Counter' }}</div>\n                  <div class=\"text-muted-foreground text-xs\">\n                    Locker PIN: {{ order.stagingLocation.lockerPin || 'N/A' }}\n                  </div>\n                }\n              </div>\n            </div>\n\n            <!-- Staged Items Checklist -->\n            <div class=\"space-y-2\">\n              <div class=\"text-foreground flex items-center justify-between text-xs font-medium\">\n                <span>Order Items Checklist ({{ order.items.length }} items)</span>\n                <span class=\"text-muted-foreground\">Total: \\${{ order.orderTotal.toFixed(2) }}</span>\n              </div>\n              <div class=\"border-border max-h-40 space-y-1.5 overflow-y-auto rounded-md border p-2\">\n                @for (item of order.items; track item.id) {\n                  <div class=\"bg-muted/40 flex items-center justify-between rounded p-2 text-xs\">\n                    <div class=\"flex items-center gap-2\">\n                      <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-3.5 shrink-0\" />\n                      <div>\n                        <div class=\"text-foreground font-medium\">{{ item.name }}</div>\n                        <div class=\"text-muted-foreground font-mono text-xs\">\n                          SKU: {{ item.sku }} · Qty: {{ item.quantity }}\n                        </div>\n                      </div>\n                    </div>\n                    <div class=\"text-foreground font-mono text-xs font-medium\">\\${{ lineTotal(item) }}</div>\n                  </div>\n                }\n              </div>\n            </div>\n          </div>\n\n          <div ui-dialog-footer class=\"gap-2 sm:gap-0\">\n            <button ui-button variant=\"outline\" size=\"sm\" class=\"text-xs\" (click)=\"openChange.emit(false)\">\n              Close\n            </button>\n            @if (order.status !== 'completed') {\n              <button\n                ui-button\n                size=\"sm\"\n                class=\"bg-success hover:bg-success/90 gap-1.5 text-xs text-white\"\n                (click)=\"markDelivered.emit(order.id)\"\n              >\n                <lucide-icon [img]=\"Check\" class=\"size-3.5\" />\n                <span>Mark Delivered &amp; Close</span>\n              </button>\n            }\n          </div>\n        }\n      </ui-dialog-content>\n    </ui-dialog>\n  `,\n})\nexport class UiOrderDetailDialogComponent {\n  @Input() open = false\n  @Input() selectedOrder: PickupOrder | null = null\n  @Output() openChange = new EventEmitter<boolean>()\n  @Output() markDelivered = new EventEmitter<string>()\n\n  protected readonly Car = Car\n  protected readonly Check = Check\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Layers = Layers\n\n  protected lineTotal(item: OrderItem): string {\n    return (item.price * item.quantity).toFixed(2)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/store-pickup-curbside/order-detail-dialog.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/store-pickup-curbside/store-pickup-modals.component.ts",
      "content": "import {\n  Component,\n  DestroyRef,\n  EventEmitter,\n  Input,\n  Output,\n  inject,\n  signal,\n  ChangeDetectionStrategy,\n} from '@angular/core'\nimport { Bell, Car, CheckCircle2, LucideAngularModule, MessageSquare, Send } from 'lucide-angular'\nimport { cn } from '@/lib/utils'\nimport { UiButtonComponent } from '@/ui/button/button.component'\nimport {\n  UiDialogCloseComponent,\n  UiDialogComponent,\n  UiDialogContentComponent,\n  UiDialogDescriptionComponent,\n  UiDialogFooterComponent,\n  UiDialogHeaderComponent,\n  UiDialogTitleComponent,\n} from '@/ui/dialog/dialog.component'\nimport { UiInputComponent } from '@/ui/input/input.component'\nimport {\n  UiSelectComponent,\n  UiSelectContentComponent,\n  UiSelectItemComponent,\n  UiSelectTriggerComponent,\n  UiSelectValueComponent,\n} from '@/ui/select/select.component'\nimport type {\n  ConfirmArrivalPayload,\n  CreateOrderPayload,\n  NotifyChannel,\n  PickupMode,\n  PickupOrder,\n} from './store-pickup-types'\n\n/**\n * The store-pickup-curbside action dialogs (React `StorePickupModals`): the customer\n * \"I'm Here\" parking check-in, the notify-customer (SMS / push) dialog and the\n * stage-new-pickup-order form. Each dialog keeps its own form state; the parent owns the\n * open flags and applies the emitted payloads to the order list.\n */\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-store-pickup-modals, [ui-store-pickup-modals]',\n  standalone: true,\n  host: { class: 'contents' },\n  imports: [\n    LucideAngularModule,\n    UiButtonComponent,\n    UiDialogCloseComponent,\n    UiDialogComponent,\n    UiDialogContentComponent,\n    UiDialogDescriptionComponent,\n    UiDialogFooterComponent,\n    UiDialogHeaderComponent,\n    UiDialogTitleComponent,\n    UiInputComponent,\n    UiSelectComponent,\n    UiSelectContentComponent,\n    UiSelectItemComponent,\n    UiSelectTriggerComponent,\n    UiSelectValueComponent,\n  ],\n  template: `\n    <!-- Modal 1: Customer \"I'm Here\" Parking Spot Check-in Dialog -->\n    <ui-dialog [open]=\"checkInModalOpen\" (openChange)=\"checkInModalOpenChange.emit($event)\">\n      <ui-dialog-content class=\"sm:max-w-md\">\n        <div ui-dialog-header>\n          <div class=\"flex items-center gap-2\">\n            <div\n              class=\"border-warning/20 bg-warning/10 text-warning flex size-8 items-center justify-center rounded-lg border\"\n            >\n              <lucide-icon [img]=\"Car\" class=\"size-4\" />\n            </div>\n            <div>\n              <h2 ui-dialog-title class=\"text-base font-bold\">Customer Parking Arrival Check-In</h2>\n              <p ui-dialog-description class=\"text-xs\">\n                Check in customer arriving at the curbside pickup bay or simulate customer mobile app check-in.\n              </p>\n            </div>\n          </div>\n        </div>\n\n        <div class=\"space-y-4 py-2 text-xs\">\n          <!-- Select Order to Check In -->\n          <div class=\"space-y-1.5\">\n            <label class=\"text-foreground font-medium\">Select Customer Order</label>\n            <ui-select [value]=\"checkInOrderId()\" (valueChange)=\"checkInOrderId.set($event)\">\n              <button ui-select-trigger class=\"h-9 text-xs\">\n                <ui-select-value placeholder=\"Select active order\" />\n              </button>\n              <ui-select-content>\n                @for (o of activeOrders(); track o.id) {\n                  <ui-select-item [value]=\"o.id\">\n                    {{ o.customerName }} · #{{ o.orderNumber }} ({{ o.items.length }} items)\n                  </ui-select-item>\n                }\n              </ui-select-content>\n            </ui-select>\n          </div>\n\n          <!-- Select Parking Spot -->\n          <div class=\"space-y-1.5\">\n            <label class=\"text-foreground font-medium\">Curbside Parking Bay</label>\n            <div class=\"grid grid-cols-6 gap-1.5\">\n              @for (spot of spots; track spot) {\n                <button type=\"button\" [class]=\"spotClass(spot)\" (click)=\"checkInSpot.set(spot)\">\n                  <span>Bay</span>\n                  <span class=\"text-sm font-bold\">#{{ spot }}</span>\n                </button>\n              }\n            </div>\n          </div>\n\n          <!-- Vehicle Information -->\n          <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n            <div class=\"space-y-1.5\">\n              <label class=\"text-foreground font-medium\">Vehicle Make &amp; Model</label>\n              <ui-input\n                [value]=\"checkInVehicleModel()\"\n                (valueChange)=\"checkInVehicleModel.set($event)\"\n                placeholder=\"e.g. Silver Tesla Model 3\"\n                class=\"h-8 text-xs\"\n              />\n            </div>\n            <div class=\"space-y-1.5\">\n              <label class=\"text-foreground font-medium\">License Plate</label>\n              <ui-input\n                [value]=\"checkInPlate()\"\n                (valueChange)=\"checkInPlate.set($event)\"\n                placeholder=\"e.g. 7XYZ892\"\n                class=\"h-8 font-mono text-xs uppercase\"\n              />\n            </div>\n          </div>\n\n          <!-- Arrival Notes -->\n          <div class=\"space-y-1.5\">\n            <label class=\"text-foreground font-medium\">Arrival Instructions &amp; Bay Notes</label>\n            <ui-input\n              [value]=\"checkInNotes()\"\n              (valueChange)=\"checkInNotes.set($event)\"\n              placeholder=\"e.g. Trunk unlocked, hazard lights on\"\n              class=\"h-8 text-xs\"\n            />\n          </div>\n\n          <!-- Hazard Lights Checkbox Simulation -->\n          <div class=\"border-border bg-muted/40 flex items-center gap-2 rounded-md border p-2.5\">\n            <input\n              id=\"hazards-checkbox\"\n              [checked]=\"checkInHazards()\"\n              (change)=\"onHazardsChange($event)\"\n              type=\"checkbox\"\n              class=\"border-border text-primary focus:ring-primary size-4 rounded\"\n            />\n            <label for=\"hazards-checkbox\" class=\"text-foreground cursor-pointer text-xs\">\n              Vehicle hazard lights are actively flashing for runner identification\n            </label>\n          </div>\n        </div>\n\n        <div ui-dialog-footer class=\"gap-2 sm:gap-0\">\n          <button ui-button ui-dialog-close variant=\"outline\" size=\"sm\" class=\"text-xs\">Cancel</button>\n          <button\n            ui-button\n            size=\"sm\"\n            class=\"bg-success hover:bg-success/90 gap-1.5 text-xs text-white\"\n            (click)=\"handleCheckInSubmit()\"\n          >\n            <lucide-icon [img]=\"CheckCircle2\" class=\"size-3.5\" />\n            <span>Confirm Arrival &amp; Alert Runner</span>\n          </button>\n        </div>\n      </ui-dialog-content>\n    </ui-dialog>\n\n    <!-- Modal 2: Notify Customer Dialog -->\n    <ui-dialog [open]=\"notifyModalOpen\" (openChange)=\"notifyModalOpenChange.emit($event)\">\n      <ui-dialog-content class=\"sm:max-w-md\">\n        @if (selectedOrder; as order) {\n          <div ui-dialog-header>\n            <h2 ui-dialog-title class=\"text-base font-bold\">Notify Customer</h2>\n            <p ui-dialog-description class=\"text-xs\">\n              Send real-time pickup status alert to {{ order.customerName }} ({{ order.customerPhone }}).\n            </p>\n          </div>\n\n          <div class=\"space-y-4 py-2 text-xs\">\n            <div class=\"space-y-1.5\">\n              <label class=\"text-foreground font-medium\">Notification Channel</label>\n              <div class=\"grid grid-cols-1 gap-2 sm:grid-cols-2\">\n                <button type=\"button\" [class]=\"channelClass('sms')\" (click)=\"notifyChannel.set('sms')\">\n                  <lucide-icon [img]=\"MessageSquare\" class=\"size-3.5\" />\n                  <span>SMS Text Message</span>\n                </button>\n                <button type=\"button\" [class]=\"channelClass('push')\" (click)=\"notifyChannel.set('push')\">\n                  <lucide-icon [img]=\"Bell\" class=\"size-3.5\" />\n                  <span>Mobile App Push</span>\n                </button>\n              </div>\n            </div>\n\n            <div class=\"border-border bg-muted/40 space-y-1.5 rounded-md border p-3 text-xs\">\n              <div class=\"text-foreground flex items-center justify-between font-medium\">\n                <span>Message Preview</span>\n                <span class=\"text-muted-foreground font-mono\">160 chars</span>\n              </div>\n              <p class=\"text-muted-foreground text-xs leading-relaxed\">\n                \"Hi {{ order.customerName }}, your Order #{{ order.orderNumber }} is ready at {{ storeName }}! Pull into\n                Curbside Spot #{{ order.spotNumber || '1-6' }} and tap 'I'm Here' for runner delivery.\"\n              </p>\n            </div>\n          </div>\n        }\n\n        <div ui-dialog-footer class=\"gap-2 sm:gap-0\">\n          <button ui-button ui-dialog-close variant=\"outline\" size=\"sm\" class=\"text-xs\">Cancel</button>\n          <button\n            ui-button\n            size=\"sm\"\n            class=\"gap-1.5 text-xs\"\n            [disabled]=\"notifyMessageSent()\"\n            (click)=\"handleSendNotification()\"\n          >\n            <lucide-icon [img]=\"Send\" class=\"size-3.5\" />\n            <span>{{ notifyMessageSent() ? 'Notification Sent!' : 'Send Alert' }}</span>\n          </button>\n        </div>\n      </ui-dialog-content>\n    </ui-dialog>\n\n    <!-- Modal 3: New Pickup Order Staging Dialog -->\n    <ui-dialog [open]=\"newOrderModalOpen\" (openChange)=\"newOrderModalOpenChange.emit($event)\">\n      <ui-dialog-content class=\"sm:max-w-md\">\n        <div ui-dialog-header>\n          <h2 ui-dialog-title class=\"text-base font-bold\">Stage New Pickup Order</h2>\n          <p ui-dialog-description class=\"text-xs\">\n            Register an incoming online BOPIS order into retail staging shelves or lockers.\n          </p>\n        </div>\n\n        <div class=\"space-y-3.5 py-2 text-xs\">\n          <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n            <div class=\"space-y-1.5\">\n              <label class=\"text-foreground font-medium\">Customer Name</label>\n              <ui-input\n                [value]=\"newCustomerName()\"\n                (valueChange)=\"newCustomerName.set($event)\"\n                placeholder=\"e.g. Alex Morgan\"\n                class=\"h-8 text-xs\"\n              />\n            </div>\n            <div class=\"space-y-1.5\">\n              <label class=\"text-foreground font-medium\">Customer Phone</label>\n              <ui-input\n                [value]=\"newCustomerPhone()\"\n                (valueChange)=\"newCustomerPhone.set($event)\"\n                placeholder=\"e.g. (415) 555-0199\"\n                class=\"h-8 font-mono text-xs\"\n              />\n            </div>\n          </div>\n\n          <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n            <div class=\"space-y-1.5\">\n              <label class=\"text-foreground font-medium\">Pickup Mode</label>\n              <ui-select [value]=\"newPickupMode()\" (valueChange)=\"setNewPickupMode($event)\">\n                <button ui-select-trigger class=\"h-8 text-xs\">\n                  <ui-select-value />\n                </button>\n                <ui-select-content>\n                  <ui-select-item value=\"curbside\">Curbside Bay</ui-select-item>\n                  <ui-select-item value=\"in_store\">In-Store Desk</ui-select-item>\n                </ui-select-content>\n              </ui-select>\n            </div>\n            <div class=\"space-y-1.5\">\n              <label class=\"text-foreground font-medium\">Preferred Bay / Desk</label>\n              <ui-select [value]=\"newSpotNumber()\" (valueChange)=\"newSpotNumber.set($event)\">\n                <button ui-select-trigger class=\"h-8 text-xs\">\n                  <ui-select-value />\n                </button>\n                <ui-select-content>\n                  @for (spot of spots; track spot) {\n                    <ui-select-item [value]=\"spot\">Bay #{{ spot }}</ui-select-item>\n                  }\n                </ui-select-content>\n              </ui-select>\n            </div>\n          </div>\n\n          <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n            <div class=\"space-y-1.5\">\n              <label class=\"text-foreground font-medium\">Staging Aisle</label>\n              <ui-input\n                [value]=\"newStagingAisle()\"\n                (valueChange)=\"newStagingAisle.set($event)\"\n                placeholder=\"e.g. Aisle 01\"\n                class=\"h-8 text-xs\"\n              />\n            </div>\n            <div class=\"space-y-1.5\">\n              <label class=\"text-foreground font-medium\">Staging Bin</label>\n              <ui-input\n                [value]=\"newStagingBin()\"\n                (valueChange)=\"newStagingBin.set($event)\"\n                placeholder=\"e.g. Bin B-05\"\n                class=\"h-8 text-xs\"\n              />\n            </div>\n          </div>\n\n          <div class=\"space-y-1.5\">\n            <label class=\"text-foreground font-medium\">Items Summary</label>\n            <ui-input\n              [value]=\"newItemSummary()\"\n              (valueChange)=\"newItemSummary.set($event)\"\n              placeholder=\"e.g. Noise Cancelling Earbuds, Travel Case\"\n              class=\"h-8 text-xs\"\n            />\n          </div>\n\n          <div class=\"space-y-1.5\">\n            <label class=\"text-foreground font-medium\">Order Total ($)</label>\n            <ui-input\n              [value]=\"newOrderTotal()\"\n              (valueChange)=\"newOrderTotal.set($event)\"\n              placeholder=\"120.00\"\n              class=\"h-8 font-mono text-xs\"\n            />\n          </div>\n        </div>\n\n        <div ui-dialog-footer class=\"gap-2 sm:gap-0\">\n          <button ui-button ui-dialog-close variant=\"outline\" size=\"sm\" class=\"text-xs\">Cancel</button>\n          <button ui-button size=\"sm\" class=\"text-xs\" [disabled]=\"!newCustomerName()\" (click)=\"handleCreateOrder()\">\n            <span>Stage &amp; Assign Bin</span>\n          </button>\n        </div>\n      </ui-dialog-content>\n    </ui-dialog>\n  `,\n})\nexport class UiStorePickupModalsComponent {\n  @Input() checkInModalOpen = false\n  @Output() checkInModalOpenChange = new EventEmitter<boolean>()\n  @Input() notifyModalOpen = false\n  @Output() notifyModalOpenChange = new EventEmitter<boolean>()\n  @Input() newOrderModalOpen = false\n  @Output() newOrderModalOpenChange = new EventEmitter<boolean>()\n  @Input()\n  set orders(value: PickupOrder[]) {\n    this.activeOrders.set(value.filter((x) => x.status !== 'completed'))\n  }\n  @Input() selectedOrder: PickupOrder | null = null\n  @Input() storeName = ''\n  @Output() confirmArrival = new EventEmitter<ConfirmArrivalPayload>()\n  @Output() sendNotification = new EventEmitter<NotifyChannel>()\n  @Output() createOrder = new EventEmitter<CreateOrderPayload>()\n\n  protected readonly Bell = Bell\n  protected readonly Car = Car\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly MessageSquare = MessageSquare\n  protected readonly Send = Send\n\n  protected readonly spots = ['1', '2', '3', '4', '5', '6']\n  /** Orders offered in the check-in select (everything not yet handed over). */\n  protected readonly activeOrders = signal<PickupOrder[]>([])\n\n  // Check-in state\n  readonly checkInOrderId = signal('order-3')\n  readonly checkInSpot = signal('4')\n  readonly checkInVehicleModel = signal('Silver Tesla Model 3')\n  readonly checkInPlate = signal('7XYZ892')\n  readonly checkInHazards = signal(true)\n  readonly checkInNotes = signal('Parked in bay 4, trunk unlocked for contactless placement.')\n\n  // Notify state\n  readonly notifyChannel = signal<NotifyChannel>('sms')\n  readonly notifyMessageSent = signal(false)\n\n  // New Order state\n  readonly newCustomerName = signal('')\n  readonly newCustomerPhone = signal('')\n  readonly newPickupMode = signal<PickupMode>('curbside')\n  readonly newSpotNumber = signal('3')\n  readonly newStagingAisle = signal('Aisle 01')\n  readonly newStagingBin = signal('Bin A-12')\n  readonly newItemSummary = signal('')\n  readonly newOrderTotal = signal('120.00')\n\n  private readonly timers = new Set<ReturnType<typeof setTimeout>>()\n\n  constructor() {\n    inject(DestroyRef).onDestroy(() => this.timers.forEach((t) => clearTimeout(t)))\n  }\n\n  protected spotClass(spot: string): string {\n    return cn(\n      'flex flex-col items-center justify-center rounded-md border py-2 text-xs font-semibold transition-colors duration-150',\n      this.checkInSpot() === spot\n        ? 'border-success bg-success/10 text-success ring-success/30 text-success ring-2'\n        : 'border-border bg-card text-muted-foreground hover:border-foreground/20 hover:text-foreground',\n    )\n  }\n\n  protected channelClass(channel: NotifyChannel): string {\n    return cn(\n      'flex items-center justify-center gap-1.5 rounded-md border py-2 text-xs font-semibold transition-colors',\n      this.notifyChannel() === channel\n        ? 'border-primary bg-primary/10 text-primary'\n        : 'border-border bg-card text-muted-foreground',\n    )\n  }\n\n  protected onHazardsChange(event: Event): void {\n    this.checkInHazards.set((event.target as HTMLInputElement).checked)\n  }\n\n  protected setNewPickupMode(value: string): void {\n    if (value === 'curbside' || value === 'in_store') this.newPickupMode.set(value)\n  }\n\n  handleCheckInSubmit(): void {\n    this.confirmArrival.emit({\n      orderId: this.checkInOrderId(),\n      spot: this.checkInSpot(),\n      vehicleModel: this.checkInVehicleModel(),\n      plate: this.checkInPlate(),\n      hazards: this.checkInHazards(),\n      notes: this.checkInNotes(),\n    })\n  }\n\n  handleSendNotification(): void {\n    if (!this.selectedOrder) return\n    this.notifyMessageSent.set(true)\n    const channel = this.notifyChannel()\n    const t = setTimeout(() => {\n      this.timers.delete(t)\n      this.sendNotification.emit(channel)\n      this.notifyMessageSent.set(false)\n    }, 1000)\n    this.timers.add(t)\n  }\n\n  handleCreateOrder(): void {\n    if (!this.newCustomerName()) return\n    this.createOrder.emit({\n      customerName: this.newCustomerName(),\n      customerPhone: this.newCustomerPhone(),\n      pickupMode: this.newPickupMode(),\n      spotNumber: this.newSpotNumber(),\n      stagingAisle: this.newStagingAisle(),\n      stagingBin: this.newStagingBin(),\n      itemSummary: this.newItemSummary(),\n      orderTotal: this.newOrderTotal(),\n    })\n    this.newCustomerName.set('')\n    this.newCustomerPhone.set('')\n    this.newItemSummary.set('')\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/store-pickup-curbside/store-pickup-modals.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/store-pickup-curbside/store-pickup-types.ts",
      "content": "export type PickupMode = 'curbside' | 'in_store'\nexport type OrderStatus = 'arrived' | 'en_route' | 'ready_staging' | 'completed'\n\nexport interface OrderItem {\n  id: string\n  name: string\n  sku: string\n  quantity: number\n  price: number\n  staged: boolean\n  category: string\n}\n\nexport interface PickupOrder {\n  id: string\n  orderNumber: string\n  customerName: string\n  customerPhone: string\n  customerInitials: string\n  avatar?: string\n  pickupMode: PickupMode\n  spotNumber?: number\n  vehicleDetails?: {\n    makeModel: string\n    plate: string\n    hazardsFlashing?: boolean\n  }\n  pickupDeskBay?: string\n  status: OrderStatus\n  statusLabel: string\n  etaMinutes?: number\n  distanceMiles?: number\n  waitMinutes?: number\n  stagingLocation: {\n    zone: string\n    bin: string\n    lockerPin?: string\n    type: 'shelf' | 'locker' | 'bulky'\n  }\n  items: OrderItem[]\n  orderTotal: number\n  placedAt: string\n  readyAt: string\n  arrivedAt?: string\n  verificationCode: string\n  assignedRunner?: string\n}\n\nexport type PickupModeFilter = 'all' | 'curbside' | 'in_store'\nexport type PickupStatusFilter = 'all' | 'arrived' | 'en_route' | 'ready_staging' | 'completed'\nexport type NotifyChannel = 'sms' | 'push'\n\n/** Inputs of `ui-store-pickup-curbside` (React `StorePickupCurbsideProps`). */\nexport interface StorePickupCurbsideProps {\n  storeName?: string\n  storeCode?: string\n  initialModeFilter?: PickupModeFilter\n  class?: string\n}\n\n/** Emitted by the check-in dialog's \"Confirm Arrival & Alert Runner\". */\nexport interface ConfirmArrivalPayload {\n  orderId: string\n  spot: string\n  vehicleModel: string\n  plate: string\n  hazards: boolean\n  notes: string\n}\n\n/** Emitted by the new-order dialog's \"Stage & Assign Bin\". */\nexport interface CreateOrderPayload {\n  customerName: string\n  customerPhone: string\n  pickupMode: PickupMode\n  spotNumber: string\n  stagingAisle: string\n  stagingBin: string\n  itemSummary: string\n  orderTotal: string\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/store-pickup-curbside/store-pickup-types.ts"
    },
    {
      "path": "packages/registry-angular/blocks/store-pickup-curbside/store-pickup-data.ts",
      "content": "import type { PickupOrder } from './store-pickup-types'\n\nexport const INITIAL_ORDERS: PickupOrder[] = [\n  {\n    id: 'order-1',\n    orderNumber: 'BOPIS-84920',\n    customerName: 'Elena Rostova',\n    customerPhone: '(415) 555-0192',\n    customerInitials: 'ER',\n    pickupMode: 'curbside',\n    spotNumber: 4,\n    vehicleDetails: {\n      makeModel: 'Silver Tesla Model 3',\n      plate: '7XYZ892',\n      hazardsFlashing: true,\n    },\n    status: 'arrived',\n    statusLabel: 'Customer Arrived · Waiting 2m',\n    waitMinutes: 2,\n    stagingLocation: {\n      zone: 'Aisle 02',\n      bin: 'Bin B-14',\n      type: 'shelf',\n    },\n    items: [\n      {\n        id: 'item-1',\n        name: 'Studio Pro Wireless Headphones',\n        sku: 'AUD-902-BLK',\n        quantity: 1,\n        price: 249.0,\n        staged: true,\n        category: 'Audio',\n      },\n      {\n        id: 'item-2',\n        name: 'Carbon Runner Wind Jacket',\n        sku: 'APP-410-MED',\n        quantity: 1,\n        price: 100.0,\n        staged: true,\n        category: 'Apparel',\n      },\n    ],\n    orderTotal: 349.0,\n    placedAt: '11:20 AM',\n    readyAt: '11:35 AM',\n    arrivedAt: '11:42 AM',\n    verificationCode: '4920',\n    assignedRunner: 'Jordan Miller',\n  },\n  {\n    id: 'order-2',\n    orderNumber: 'BOPIS-84919',\n    customerName: 'David Chen',\n    customerPhone: '(415) 555-0841',\n    customerInitials: 'DC',\n    pickupMode: 'curbside',\n    spotNumber: 2,\n    vehicleDetails: {\n      makeModel: 'Midnight Blue Rivian R1T',\n      plate: '8ABC104',\n      hazardsFlashing: true,\n    },\n    status: 'arrived',\n    statusLabel: 'Customer Arrived · Waiting 4m',\n    waitMinutes: 4,\n    stagingLocation: {\n      zone: 'Aisle 01',\n      bin: 'Bin A-08',\n      type: 'bulky',\n    },\n    items: [\n      {\n        id: 'item-3',\n        name: '4K Ultra HD Smart Monitor 27\"',\n        sku: 'DIS-270-4K',\n        quantity: 1,\n        price: 380.0,\n        staged: true,\n        category: 'Displays',\n      },\n      {\n        id: 'item-4',\n        name: 'Ergonomic Desk Stand',\n        sku: 'ACC-110-SLV',\n        quantity: 1,\n        price: 110.0,\n        staged: true,\n        category: 'Accessories',\n      },\n      {\n        id: 'item-5',\n        name: '100W USB-C Thunderbolt Dock',\n        sku: 'DOK-090-BLK',\n        quantity: 1,\n        price: 90.0,\n        staged: true,\n        category: 'Power',\n      },\n    ],\n    orderTotal: 580.0,\n    placedAt: '10:45 AM',\n    readyAt: '11:10 AM',\n    arrivedAt: '11:40 AM',\n    verificationCode: '8419',\n    assignedRunner: 'Marcus Lee',\n  },\n  {\n    id: 'order-3',\n    orderNumber: 'BOPIS-84918',\n    customerName: 'Marcus Vance',\n    customerPhone: '(415) 555-0329',\n    customerInitials: 'MV',\n    pickupMode: 'in_store',\n    pickupDeskBay: 'Pickup Desk Bay 01',\n    status: 'en_route',\n    statusLabel: 'En Route · 6 min ETA',\n    etaMinutes: 6,\n    distanceMiles: 1.4,\n    stagingLocation: {\n      zone: 'Locker #12',\n      bin: 'Bin L-12',\n      lockerPin: '8491',\n      type: 'locker',\n    },\n    items: [\n      {\n        id: 'item-6',\n        name: 'Pro Max Mirrorless Camera Kit',\n        sku: 'CAM-800-PRO',\n        quantity: 1,\n        price: 1299.0,\n        staged: true,\n        category: 'Photography',\n      },\n    ],\n    orderTotal: 1299.0,\n    placedAt: '11:05 AM',\n    readyAt: '11:28 AM',\n    verificationCode: '9182',\n    assignedRunner: 'Staging Auto-Lock',\n  },\n  {\n    id: 'order-4',\n    orderNumber: 'BOPIS-84917',\n    customerName: 'Aisha Patel',\n    customerPhone: '(415) 555-0782',\n    customerInitials: 'AP',\n    pickupMode: 'in_store',\n    pickupDeskBay: 'Pickup Desk Bay 03',\n    status: 'ready_staging',\n    statusLabel: 'Ready in Staging Locker #04',\n    stagingLocation: {\n      zone: 'Aisle 03',\n      bin: 'Bin C-02',\n      lockerPin: '3719',\n      type: 'locker',\n    },\n    items: [\n      {\n        id: 'item-7',\n        name: 'Organic Single-Origin Espresso Blend',\n        sku: 'COF-012-ESP',\n        quantity: 2,\n        price: 38.0,\n        staged: true,\n        category: 'Beverage',\n      },\n      {\n        id: 'item-8',\n        name: 'Precision Gooseneck Pour-Over Kettle',\n        sku: 'KET-044-SS',\n        quantity: 1,\n        price: 74.5,\n        staged: true,\n        category: 'Kitchen',\n      },\n      {\n        id: 'item-9',\n        name: 'Digital Barista Gram Scale',\n        sku: 'SCL-019-DIG',\n        quantity: 1,\n        price: 30.0,\n        staged: true,\n        category: 'Kitchen',\n      },\n    ],\n    orderTotal: 142.5,\n    placedAt: '10:15 AM',\n    readyAt: '10:50 AM',\n    verificationCode: '1742',\n    assignedRunner: 'Desk Associate',\n  },\n  {\n    id: 'order-5',\n    orderNumber: 'BOPIS-84916',\n    customerName: 'Sarah Jenkins',\n    customerPhone: '(415) 555-0453',\n    customerInitials: 'SJ',\n    pickupMode: 'curbside',\n    spotNumber: 1,\n    vehicleDetails: {\n      makeModel: 'White Toyota RAV4',\n      plate: '6MNO451',\n      hazardsFlashing: false,\n    },\n    status: 'en_route',\n    statusLabel: 'En Route · 12 min ETA',\n    etaMinutes: 12,\n    distanceMiles: 3.8,\n    stagingLocation: {\n      zone: 'Aisle 02',\n      bin: 'Bin B-03',\n      type: 'shelf',\n    },\n    items: [\n      {\n        id: 'item-10',\n        name: 'Ultra Hydration 20L Trail Backpack',\n        sku: 'OUT-220-BLU',\n        quantity: 1,\n        price: 130.0,\n        staged: true,\n        category: 'Outdoors',\n      },\n      {\n        id: 'item-11',\n        name: 'Carbon Composite Trekking Poles (Pair)',\n        sku: 'OUT-771-CAR',\n        quantity: 1,\n        price: 80.0,\n        staged: true,\n        category: 'Outdoors',\n      },\n    ],\n    orderTotal: 210.0,\n    placedAt: '11:15 AM',\n    readyAt: '11:38 AM',\n    verificationCode: '9160',\n    assignedRunner: 'Unassigned',\n  },\n]\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/store-pickup-curbside/store-pickup-data.ts"
    },
    {
      "path": "packages/registry-angular/blocks/store-pickup-curbside/index.ts",
      "content": "export {\n  UiStorePickupCurbsideComponent,\n  type ConfirmArrivalPayload,\n  type CreateOrderPayload,\n  type NotifyChannel,\n  type OrderItem,\n  type OrderStatus,\n  type PickupMode,\n  type PickupModeFilter,\n  type PickupOrder,\n  type PickupStatusFilter,\n  type StorePickupCurbsideProps,\n} from './store-pickup-curbside.component'\nexport { UiOrderDetailDialogComponent } from './order-detail-dialog.component'\nexport { UiStorePickupModalsComponent } from './store-pickup-modals.component'\nexport { INITIAL_ORDERS } from './store-pickup-data'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/store-pickup-curbside/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/angular/avatar.json",
    "https://uipkge.dev/r/angular/badge.json",
    "https://uipkge.dev/r/angular/button.json",
    "https://uipkge.dev/r/angular/card.json",
    "https://uipkge.dev/r/angular/dialog.json",
    "https://uipkge.dev/r/angular/dropdown-menu.json",
    "https://uipkge.dev/r/angular/input.json",
    "https://uipkge.dev/r/angular/select.json",
    "https://uipkge.dev/r/angular/table.json"
  ],
  "description": "Buy Online Pick Up in Store (BOPIS) & curbside pickup coordination board with customer arrival parking check-in, real-time staging bin tracking, runner fulfillment dispatch, and SLA monitoring.",
  "categories": [
    "commerce",
    "app",
    "ecommerce",
    "logistics"
  ]
}