{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "price-drop-alert-card",
  "title": "Price Drop Alert Card",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/price-drop-alert-card/price-drop-alert-card.component.ts",
      "content": "import { Component, Input, OnDestroy, computed, signal, ChangeDetectionStrategy } from '@angular/core'\nimport {\n  BellRing,\n  Check,\n  History,\n  LucideAngularModule,\n  Mail,\n  RefreshCw,\n  ShieldCheck,\n  Smartphone,\n  Tag,\n  Trash2,\n  TrendingDown,\n  Zap,\n} from 'lucide-angular'\nimport { cn } from '@/lib/utils'\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 { UiRadioGroupComponent, UiRadioGroupItemComponent } from '@/ui/radio-group/radio-group.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.component'\nimport { UiSliderComponent } from '@/ui/slider/slider.component'\nimport { UiSwitchComponent } from '@/ui/switch/switch.component'\nimport {\n  UiTableBodyComponent,\n  UiTableCellComponent,\n  UiTableComponent,\n  UiTableHeadComponent,\n  UiTableHeaderComponent,\n  UiTableRowComponent,\n} from '@/ui/table/table.component'\n\nexport type PriceAlertChannel = 'email' | 'sms'\n\nexport interface TrackedProduct {\n  id: string\n  name: string\n  variant: string\n  category: string\n  sku: string\n  image: string\n  currentPrice: number\n  targetPrice: number\n  lowest90d: number\n  channel: PriceAlertChannel\n  status: 'monitoring' | 'reached'\n  active: boolean\n}\n\nconst initialTrackedProducts: TrackedProduct[] = [\n  {\n    id: 'prod-1',\n    name: 'Pro Studio Wireless Headphones',\n    variant: 'Space Black',\n    category: 'Audio',\n    sku: 'SKU-8842',\n    image: 'https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=300&auto=format&fit=crop&q=80',\n    currentPrice: 299.0,\n    targetPrice: 280.0,\n    lowest90d: 279.0,\n    channel: 'email',\n    status: 'monitoring',\n    active: true,\n  },\n  {\n    id: 'prod-2',\n    name: 'Ergonomic Mechanical Keyboard',\n    variant: 'RGB / Cherry MX Brown',\n    category: 'Peripherals',\n    sku: 'SKU-4109',\n    image: 'https://images.unsplash.com/photo-1587829741301-dc798b83add3?w=300&auto=format&fit=crop&q=80',\n    currentPrice: 119.0,\n    targetPrice: 120.0,\n    lowest90d: 119.0,\n    channel: 'sms',\n    status: 'reached',\n    active: true,\n  },\n  {\n    id: 'prod-3',\n    name: 'Ultra-Wide Curved Monitor 34\"',\n    variant: 'WQHD 144Hz IPS',\n    category: 'Displays',\n    sku: 'SKU-9011',\n    image: 'https://images.unsplash.com/photo-1527443224154-c4a3942d3acf?w=300&auto=format&fit=crop&q=80',\n    currentPrice: 679.0,\n    targetPrice: 599.0,\n    lowest90d: 629.0,\n    channel: 'email',\n    status: 'monitoring',\n    active: true,\n  },\n]\n\n/**\n * E-commerce wishlist price tracker: product hero, a 90-day price history SVG chart whose\n * amber threshold line follows the target slider, the alert configurator (delivery channel\n * radio, target price slider with quick presets, in-stock switch, confirmation banner) and\n * the active tracked items table. Angular port of the React `PriceDropAlertCard` block\n * (same markup, classes, copy and sample data).\n */\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-price-drop-alert-card, [ui-price-drop-alert-card]',\n  standalone: true,\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardFooterComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiRadioGroupComponent,\n    UiRadioGroupItemComponent,\n    UiSeparatorComponent,\n    UiSliderComponent,\n    UiSwitchComponent,\n    UiTableBodyComponent,\n    UiTableCellComponent,\n    UiTableComponent,\n    UiTableHeadComponent,\n    UiTableHeaderComponent,\n    UiTableRowComponent,\n  ],\n  host: {\n    '[attr.data-slot]': '\"price-drop-alert-card\"',\n    '[class]': 'hostClass',\n  },\n  template: `\n    <!-- Header bar -->\n    <div class=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n      <div class=\"space-y-1\">\n        <div class=\"flex items-center gap-2\">\n          <h2 class=\"text-foreground text-2xl font-semibold tracking-tight sm:text-3xl\">Price Drop Tracker</h2>\n          <span\n            ui-badge\n            variant=\"outline\"\n            class=\"border-success/30 bg-success/10 text-success gap-1.5 text-xs font-semibold\"\n          >\n            <span class=\"bg-success size-1.5 animate-pulse rounded-full\"></span>\n            Live Sync\n          </span>\n        </div>\n        <p class=\"text-muted-foreground text-sm\">\n          Monitor historical market fluctuations, set custom discount thresholds, and receive real-time notifications.\n        </p>\n      </div>\n\n      <div class=\"flex items-center gap-2\">\n        <button\n          ui-button\n          variant=\"outline\"\n          size=\"sm\"\n          class=\"gap-1.5 text-xs\"\n          [disabled]=\"isRefreshing()\"\n          (click)=\"triggerRefresh()\"\n        >\n          <lucide-icon [img]=\"RefreshCw\" [class]=\"cn('size-3.5', isRefreshing() && 'text-primary animate-spin')\" />\n          <span>{{ isRefreshing() ? 'Checking prices…' : 'Check All Prices' }}</span>\n        </button>\n      </div>\n    </div>\n\n    <!-- 1. Product Wishlist Hero -->\n    <ui-card class=\"border-border bg-card overflow-hidden shadow-xs\">\n      <div class=\"grid grid-cols-1 gap-6 p-6 lg:grid-cols-12 lg:gap-8\">\n        <!-- Thumbnail column -->\n        <div class=\"relative flex flex-col items-center justify-center lg:col-span-4\">\n          <div\n            class=\"border-border/80 bg-muted/30 relative aspect-square w-full max-w-72 overflow-hidden rounded-xl border\"\n          >\n            <img\n              src=\"https://images.unsplash.com/photo-1505740420928-5e560c06d30e?w=800&auto=format&fit=crop&q=80\"\n              alt=\"Pro Studio Wireless Headphones - Space Black\"\n              class=\"size-full object-cover object-center transition-transform duration-300 hover:scale-105\"\n            />\n            <div class=\"absolute top-3 left-3 flex flex-col gap-1.5\">\n              <span\n                ui-badge\n                variant=\"secondary\"\n                class=\"bg-background/90 text-foreground border-border/40 border text-xs font-medium backdrop-blur-xs\"\n              >\n                Audio · SKU-8842\n              </span>\n            </div>\n            <div class=\"absolute right-3 bottom-3\">\n              <span ui-badge class=\"bg-success bg-success text-xs font-semibold text-white shadow-xs\">\n                Lowest in 90 Days\n              </span>\n            </div>\n          </div>\n        </div>\n\n        <!-- Product detail column -->\n        <div class=\"flex flex-col justify-between space-y-4 lg:col-span-8\">\n          <div class=\"space-y-2\">\n            <div class=\"text-muted-foreground flex flex-wrap items-center gap-2 text-xs\">\n              <span class=\"text-foreground font-medium\">Sony Acoustic Systems</span>\n              <span>•</span>\n              <span>Model WH-1000XM-Pro</span>\n              <span>•</span>\n              <span class=\"text-warning inline-flex items-center gap-1 font-medium\">\n                ★ 4.8 <span class=\"text-muted-foreground\">(1,420 reviews)</span>\n              </span>\n            </div>\n\n            <h3 class=\"text-foreground text-xl font-semibold tracking-tight sm:text-2xl\">\n              Pro Studio Wireless Headphones - Space Black\n            </h3>\n\n            <p class=\"text-muted-foreground text-sm leading-relaxed\">\n              Flagship hybrid active noise cancelling with beryllium dynamic drivers, 38-hour battery longevity,\n              lossless LDAC codec support, and ultra-plush memory foam acoustic isolation cushions.\n            </p>\n          </div>\n\n          <!-- Price breakdown strip -->\n          <div class=\"border-border/60 bg-muted/20 rounded-xl border p-4\">\n            <div class=\"flex flex-wrap items-baseline gap-3 sm:gap-4\">\n              <div class=\"flex items-baseline gap-1.5\">\n                <span class=\"text-foreground text-3xl font-semibold tracking-tight tabular-nums sm:text-4xl\">\n                  \\${{ currentPrice.toFixed(2) }}\n                </span>\n                <span class=\"text-muted-foreground text-sm tabular-nums line-through\">\n                  \\${{ msrpPrice.toFixed(2) }}\n                </span>\n              </div>\n\n              <div class=\"flex flex-wrap items-center gap-2\">\n                <span\n                  class=\"border-success/25 bg-success/10 text-success inline-flex items-center gap-1 rounded-full border px-2.5 py-1 text-xs font-semibold\"\n                >\n                  <lucide-icon [img]=\"TrendingDown\" class=\"size-3.5\" />\n                  Save $50.00 (-14.3%)\n                </span>\n\n                <span\n                  class=\"border-border bg-background text-muted-foreground inline-flex items-center gap-1 rounded-full border px-2.5 py-1 text-xs font-medium\"\n                >\n                  <lucide-icon [img]=\"Tag\" class=\"text-warning size-3\" />\n                  90-Day Low:\n                  <span class=\"text-foreground font-semibold tabular-nums\">\\${{ lowest90dPrice.toFixed(2) }}</span>\n                </span>\n              </div>\n            </div>\n\n            <div\n              class=\"text-muted-foreground border-border/40 mt-3 flex flex-wrap items-center gap-4 border-t pt-3 text-xs\"\n            >\n              <span class=\"text-success inline-flex items-center gap-1.5 font-medium\">\n                <lucide-icon [img]=\"Check\" class=\"size-3.5\" /> In Stock (14 left)\n              </span>\n              <span>•</span>\n              <span class=\"inline-flex items-center gap-1.5\">\n                <lucide-icon [img]=\"ShieldCheck\" class=\"text-muted-foreground size-3.5\" /> 30-Day Price Match Guarantee\n              </span>\n              <span>•</span>\n              <span>Free 2-Day Priority Delivery</span>\n            </div>\n          </div>\n        </div>\n      </div>\n    </ui-card>\n\n    <!-- 2. 90-Day Price History SVG Trend Chart -->\n    <ui-card class=\"border-border bg-card shadow-xs\">\n      <ui-card-header class=\"pb-3\">\n        <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n          <div class=\"space-y-1\">\n            <ui-card-title class=\"flex items-center gap-2 text-base font-semibold sm:text-lg\">\n              <lucide-icon [img]=\"History\" class=\"text-primary size-4\" />\n              90-Day Price History &amp; Target Threshold\n            </ui-card-title>\n            <ui-card-description class=\"text-xs sm:text-sm\">\n              Retail price trajectory from May through August with real-time target price alert line.\n            </ui-card-description>\n          </div>\n\n          <!-- Quick trend stats pills -->\n          <div class=\"flex flex-wrap items-center gap-2 text-xs\">\n            <div class=\"border-border/80 bg-muted/40 rounded-md border px-2.5 py-1\">\n              <span class=\"text-muted-foreground\">High: </span>\n              <span class=\"text-foreground font-semibold tabular-nums\">$349.00</span>\n            </div>\n            <div class=\"border-border/80 bg-muted/40 rounded-md border px-2.5 py-1\">\n              <span class=\"text-muted-foreground\">Avg: </span>\n              <span class=\"text-foreground font-semibold tabular-nums\">$324.50</span>\n            </div>\n            <div class=\"border-success/30 bg-success/10 text-success rounded-md border px-2.5 py-1\">\n              <span class=\"opacity-80\">90d Low: </span>\n              <span class=\"font-bold tabular-nums\">$279.00</span>\n            </div>\n          </div>\n        </div>\n      </ui-card-header>\n\n      <ui-card-content class=\"pt-2\">\n        <div class=\"border-border/60 bg-muted/10 relative w-full overflow-x-auto rounded-lg border p-2 sm:p-4\">\n          <svg\n            viewBox=\"0 0 600 180\"\n            class=\"h-auto w-full max-w-[560px] min-w-full overflow-visible select-none\"\n            preserveAspectRatio=\"xMidYMid meet\"\n          >\n            <defs>\n              <linearGradient id=\"angular-price-gradient\" x1=\"0\" y1=\"0\" x2=\"0\" y2=\"1\">\n                <stop offset=\"0%\" stop-color=\"var(--primary)\" stop-opacity=\"0.28\" />\n                <stop offset=\"100%\" stop-color=\"var(--primary)\" stop-opacity=\"0.0\" />\n              </linearGradient>\n            </defs>\n\n            <!-- Y-Axis Grid Lines & Labels -->\n            <line x1=\"50\" y1=\"20\" x2=\"575\" y2=\"20\" class=\"stroke-border/40 stroke-1\" stroke-dasharray=\"3 3\" />\n            <text x=\"42\" y=\"24\" text-anchor=\"end\" class=\"fill-muted-foreground font-mono text-xs tabular-nums\">\n              $360\n            </text>\n\n            <line x1=\"50\" y1=\"63.3\" x2=\"575\" y2=\"63.3\" class=\"stroke-border/40 stroke-1\" stroke-dasharray=\"3 3\" />\n            <text x=\"42\" y=\"67\" text-anchor=\"end\" class=\"fill-muted-foreground font-mono text-xs tabular-nums\">\n              $320\n            </text>\n\n            <line x1=\"50\" y1=\"106.6\" x2=\"575\" y2=\"106.6\" class=\"stroke-border/40 stroke-1\" stroke-dasharray=\"3 3\" />\n            <text x=\"42\" y=\"110\" text-anchor=\"end\" class=\"fill-muted-foreground font-mono text-xs tabular-nums\">\n              $280\n            </text>\n\n            <line x1=\"50\" y1=\"150\" x2=\"575\" y2=\"150\" class=\"stroke-border/40 stroke-1\" />\n            <text x=\"42\" y=\"154\" text-anchor=\"end\" class=\"fill-muted-foreground font-mono text-xs tabular-nums\">\n              $240\n            </text>\n\n            <!-- Price Area Fill -->\n            <path\n              d=\"M 60,31.9 C 105,31.9 105,53.6 150,53.6 C 200,53.6 200,31.9 250,31.9 C 300,31.9 300,107.8 350,107.8 C 405,107.8 405,64.4 460,64.4 C 510,64.4 510,86.1 560,86.1 L 560,150 L 60,150 Z\"\n              fill=\"url(#angular-price-gradient)\"\n            />\n\n            <!-- Price Trajectory Line -->\n            <path\n              d=\"M 60,31.9 C 105,31.9 105,53.6 150,53.6 C 200,53.6 200,31.9 250,31.9 C 300,31.9 300,107.8 350,107.8 C 405,107.8 405,64.4 460,64.4 C 510,64.4 510,86.1 560,86.1\"\n              fill=\"none\"\n              class=\"stroke-primary stroke-2\"\n              stroke-linecap=\"round\"\n              stroke-linejoin=\"round\"\n            />\n\n            <!-- Target Price Dynamic Threshold Line (Amber Dashed) -->\n            <line\n              x1=\"50\"\n              [attr.y1]=\"targetY()\"\n              x2=\"575\"\n              [attr.y2]=\"targetY()\"\n              class=\"stroke-amber-500 stroke-2 transition-colors duration-150 ease-out\"\n              stroke-dasharray=\"4 4\"\n            />\n\n            <!-- Dynamic Target Label Tag -->\n            <g [attr.transform]=\"targetTransform()\" class=\"transition-colors duration-150 ease-out\">\n              <rect x=\"-96\" y=\"-18\" width=\"96\" height=\"18\" rx=\"4\" class=\"fill-warning dark:fill-amber-600\" />\n              <text x=\"-48\" y=\"-5\" text-anchor=\"middle\" class=\"fill-white font-mono text-xs font-bold tracking-tight\">\n                Alert: \\${{ targetPrice().toFixed(0) }}.00\n              </text>\n            </g>\n\n            <!-- Historical Data Points & Annotations -->\n            <circle cx=\"60\" cy=\"31.9\" r=\"3.5\" class=\"fill-background stroke-primary stroke-2\" />\n            <circle cx=\"150\" cy=\"53.6\" r=\"3.5\" class=\"fill-background stroke-primary stroke-2\" />\n            <circle cx=\"250\" cy=\"31.9\" r=\"3.5\" class=\"fill-background stroke-primary stroke-2\" />\n\n            <!-- Pt 4: Jul 26 ($279 - 90d Low) -->\n            <circle cx=\"350\" cy=\"107.8\" r=\"5\" class=\"stroke-background fill-success stroke-2\" />\n            <rect\n              x=\"306\"\n              y=\"117\"\n              width=\"88\"\n              height=\"18\"\n              rx=\"4\"\n              class=\"fill-success/10 stroke-emerald-500/30 stroke-1\"\n            />\n            <text\n              x=\"350\"\n              y=\"130\"\n              text-anchor=\"middle\"\n              class=\"dark:fill-success fill-emerald-600 font-mono text-xs font-bold\"\n            >\n              90d Low · $279\n            </text>\n\n            <circle cx=\"460\" cy=\"64.4\" r=\"3.5\" class=\"fill-background stroke-primary stroke-2\" />\n\n            <!-- Pt 6: Aug 21 (Current $299) -->\n            <circle cx=\"560\" cy=\"86.1\" r=\"5\" class=\"fill-primary stroke-background stroke-2\" />\n            <rect x=\"508\" y=\"58\" width=\"80\" height=\"18\" rx=\"4\" class=\"fill-primary/10 stroke-primary/30 stroke-1\" />\n            <text x=\"548\" y=\"71\" text-anchor=\"middle\" class=\"fill-primary font-mono text-xs font-bold\">\n              Now · $299.00\n            </text>\n\n            <!-- X-Axis Timeline Milestones -->\n            <text x=\"60\" y=\"168\" text-anchor=\"middle\" class=\"fill-muted-foreground font-mono text-xs\">May 22</text>\n            <text x=\"150\" y=\"168\" text-anchor=\"middle\" class=\"fill-muted-foreground font-mono text-xs\">Jun 15</text>\n            <text x=\"250\" y=\"168\" text-anchor=\"middle\" class=\"fill-muted-foreground font-mono text-xs\">Jul 05</text>\n            <text x=\"350\" y=\"168\" text-anchor=\"middle\" class=\"fill-muted-foreground font-mono text-xs\">Jul 26</text>\n            <text x=\"460\" y=\"168\" text-anchor=\"middle\" class=\"fill-muted-foreground font-mono text-xs\">Aug 10</text>\n            <text x=\"560\" y=\"168\" text-anchor=\"middle\" class=\"fill-foreground font-mono text-xs font-semibold\">\n              Today\n            </text>\n          </svg>\n        </div>\n\n        <div class=\"text-muted-foreground mt-3 flex items-center justify-between text-xs\">\n          <div class=\"flex items-center gap-2\">\n            <span class=\"bg-warning size-2 rounded-full\"></span>\n            <span>Amber dashed threshold line updates automatically as you move the target slider below.</span>\n          </div>\n          <span class=\"font-mono text-xs\">Updated 4m ago</span>\n        </div>\n      </ui-card-content>\n    </ui-card>\n\n    <!-- 3. Configure Price Drop Alert Form -->\n    <ui-card class=\"border-border bg-card shadow-xs\">\n      <ui-card-header>\n        <ui-card-title class=\"flex items-center gap-2 text-base font-semibold sm:text-lg\">\n          <lucide-icon [img]=\"BellRing\" class=\"text-primary size-4\" />\n          Configure Price Drop Alert\n        </ui-card-title>\n        <ui-card-description class=\"text-xs sm:text-sm\">\n          Set your notification channel and custom trigger price. We check pricing every 15 minutes across verified\n          retailers.\n        </ui-card-description>\n      </ui-card-header>\n\n      <ui-card-content class=\"space-y-6\">\n        <!-- Step 1: Alert Delivery Method Radio -->\n        <div class=\"space-y-3\">\n          <label class=\"text-foreground text-sm font-semibold\">1. Alert Delivery Channel</label>\n          <ui-radio-group\n            [value]=\"alertMethod()\"\n            (valueChange)=\"setAlertMethod($event)\"\n            class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\"\n          >\n            <label for=\"angular-method-email\" [class]=\"methodClass('email')\">\n              <ui-radio-group-item id=\"angular-method-email\" value=\"email\" />\n              <div class=\"space-y-0.5\">\n                <div class=\"text-foreground flex items-center gap-1.5 text-sm font-semibold\">\n                  <lucide-icon [img]=\"Mail\" class=\"text-muted-foreground size-3.5\" />\n                  Email Notification\n                </div>\n                <p class=\"text-muted-foreground font-mono text-xs\">customer&#64;example.com</p>\n              </div>\n            </label>\n\n            <label for=\"angular-method-sms\" [class]=\"methodClass('sms')\">\n              <ui-radio-group-item id=\"angular-method-sms\" value=\"sms\" />\n              <div class=\"space-y-0.5\">\n                <div class=\"text-foreground flex items-center gap-1.5 text-sm font-semibold\">\n                  <lucide-icon [img]=\"Smartphone\" class=\"text-muted-foreground size-3.5\" />\n                  SMS Push Notification\n                </div>\n                <p class=\"text-muted-foreground font-mono text-xs\">+1 (555) 019-2834</p>\n              </div>\n            </label>\n          </ui-radio-group>\n        </div>\n\n        <ui-separator />\n\n        <!-- Step 2: Target Price Slider & Input -->\n        <div class=\"space-y-4\">\n          <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n            <div class=\"space-y-0.5\">\n              <label class=\"text-foreground text-sm font-semibold\">2. Target Price Alert Threshold</label>\n              <p class=\"text-muted-foreground text-xs\">\n                Trigger an alert when the item price drops to or below this amount.\n              </p>\n            </div>\n\n            <!-- Target Price Display -->\n            <div class=\"flex items-center gap-2\">\n              <div class=\"border-border bg-muted/40 flex items-center rounded-lg border px-3 py-1.5\">\n                <span class=\"text-muted-foreground mr-1.5 text-xs font-medium\">Target:</span>\n                <span class=\"text-foreground font-mono text-lg font-semibold tabular-nums\">\n                  \\${{ targetPrice().toFixed(2) }}\n                </span>\n              </div>\n            </div>\n          </div>\n\n          <!-- Slider component -->\n          <div class=\"space-y-2 pt-2\">\n            <ui-slider\n              [value]=\"[targetPrice()]\"\n              (valueChange)=\"onSliderChange($event)\"\n              [min]=\"200\"\n              [max]=\"349\"\n              [step]=\"1\"\n              class=\"w-full\"\n            />\n\n            <!-- Min/Max labels -->\n            <div class=\"text-muted-foreground flex justify-between font-mono text-xs\">\n              <span>$200.00 (Deep Deal)</span>\n              <span class=\"text-warning font-semibold\">Target: \\${{ targetPrice().toFixed(2) }}</span>\n              <span>$349.00 (MSRP)</span>\n            </div>\n          </div>\n\n          <!-- Savings calculation box & quick presets -->\n          <div\n            class=\"border-border/80 bg-muted/20 flex flex-col gap-3 rounded-lg border p-3.5 sm:flex-row sm:items-center sm:justify-between\"\n          >\n            <div class=\"flex items-center gap-2\">\n              <lucide-icon [img]=\"Tag\" class=\"text-success size-4 shrink-0\" />\n              <div class=\"text-xs\">\n                @if (targetPrice() < currentPrice) {\n                  <span class=\"text-foreground font-medium\">Notify when price drops below </span>\n                  <span class=\"text-success font-mono font-semibold\">\\${{ targetPrice().toFixed(2) }}</span>\n                  <span class=\"text-muted-foreground\"> — saves an extra </span>\n                  <span class=\"text-foreground font-mono font-semibold\">\\${{ additionalSavings().toFixed(2) }}</span>\n                  <span class=\"text-muted-foreground\"> ({{ additionalSavingsPercent() }}% additional drop)</span>\n                } @else if (targetPrice() === currentPrice) {\n                  <span class=\"text-foreground font-medium\">Matches current price </span>\n                  <span class=\"text-primary font-mono font-semibold\">\\${{ currentPrice.toFixed(2) }}</span>\n                  <span class=\"text-muted-foreground\"> — triggers on any new price movement</span>\n                } @else {\n                  <span class=\"text-foreground font-medium\">\n                    Target is set above current price (\\${{ currentPrice.toFixed(2) }}). Alert triggers immediately.\n                  </span>\n                }\n              </div>\n            </div>\n\n            <!-- Quick preset buttons -->\n            <div class=\"flex shrink-0 flex-wrap items-center gap-1.5\">\n              <button\n                ui-button\n                variant=\"outline\"\n                size=\"sm\"\n                class=\"h-7 px-2 font-mono text-xs\"\n                (click)=\"handlePresetClick(289)\"\n              >\n                $289 (-$10)\n              </button>\n              <button\n                ui-button\n                variant=\"outline\"\n                size=\"sm\"\n                class=\"border-success/40 text-success h-7 px-2 font-mono text-xs\"\n                (click)=\"handlePresetClick(279)\"\n              >\n                $279 (Low)\n              </button>\n              <button\n                ui-button\n                variant=\"outline\"\n                size=\"sm\"\n                class=\"h-7 px-2 font-mono text-xs\"\n                (click)=\"handlePresetClick(249)\"\n              >\n                $249 (-$50)\n              </button>\n            </div>\n          </div>\n        </div>\n\n        <ui-separator />\n\n        <!-- Step 3: In-Stock Notification Switch -->\n        <div\n          class=\"border-border/80 flex flex-col gap-3 rounded-lg border p-4 sm:flex-row sm:items-center sm:justify-between\"\n        >\n          <div class=\"space-y-0.5\">\n            <div class=\"flex items-center gap-2\">\n              <lucide-icon [img]=\"Zap\" class=\"text-warning size-4\" />\n              <label for=\"angular-stock-switch\" class=\"text-foreground cursor-pointer text-sm font-semibold\">\n                In-Stock &amp; Lightning Flash Deal Notification\n              </label>\n            </div>\n            <p class=\"text-muted-foreground text-xs\">\n              Send instant high-priority alert if available stock falls below 5 units or if a limited lightning coupon\n              goes live.\n            </p>\n          </div>\n\n          <button\n            ui-switch\n            id=\"angular-stock-switch\"\n            [checked]=\"inStockNotification()\"\n            (checkedChange)=\"inStockNotification.set($event)\"\n          ></button>\n        </div>\n\n        <!-- Alert confirmation banner (shown if saved) -->\n        @if (alertSaved()) {\n          <div class=\"border-success/30 bg-success/10 text-success flex items-start gap-3 rounded-lg border p-4\">\n            <div class=\"bg-success mt-0.5 shrink-0 rounded-full p-1 text-white\">\n              <lucide-icon [img]=\"Check\" class=\"size-3.5\" />\n            </div>\n            <div class=\"space-y-1 text-xs\">\n              <p class=\"text-success dark:text-foreground text-sm font-semibold\">\n                Price Drop Alert Configured Successfully!\n              </p>\n              <p>\n                We'll monitor <span class=\"font-semibold\">Pro Studio Wireless Headphones</span> every 15 minutes and\n                dispatch an alert to\n                <span class=\"font-mono font-semibold\">{{ alertDestination() }}</span>\n                the moment the price reaches\n                <span class=\"font-mono font-semibold\">\\${{ targetPrice().toFixed(2) }}</span> or lower.\n              </p>\n            </div>\n          </div>\n        }\n      </ui-card-content>\n\n      <ui-card-footer\n        class=\"border-border/60 flex flex-col gap-3 border-t pt-4 sm:flex-row sm:items-center sm:justify-between\"\n      >\n        <div class=\"text-muted-foreground flex items-center gap-1.5 text-xs\">\n          <lucide-icon [img]=\"ShieldCheck\" class=\"text-success size-4 shrink-0\" />\n          <span>Zero spam guarantee. You can pause or cancel alert subscriptions anytime.</span>\n        </div>\n\n        <button ui-button class=\"w-full gap-2 font-semibold sm:w-auto\" (click)=\"handleSetAlert()\">\n          <lucide-icon [img]=\"BellRing\" class=\"size-4\" />\n          <span>{{ alertSaved() ? 'Update Price Drop Alert' : 'Set Price Drop Alert' }}</span>\n        </button>\n      </ui-card-footer>\n    </ui-card>\n\n    <!-- 4. Active Tracked Products Mini Table -->\n    <ui-card class=\"border-border bg-card shadow-xs\">\n      <ui-card-header class=\"pb-3\">\n        <div class=\"flex flex-col gap-1 sm:flex-row sm:items-center sm:justify-between\">\n          <div>\n            <ui-card-title class=\"text-base font-semibold sm:text-lg\">Active Tracked Wishlist Items</ui-card-title>\n            <ui-card-description class=\"text-xs sm:text-sm\">\n              Real-time monitoring list currently linked to your notification profile.\n            </ui-card-description>\n          </div>\n          <span ui-badge variant=\"secondary\" class=\"w-fit font-mono text-xs\">\n            {{ trackedProducts().length }} items active\n          </span>\n        </div>\n      </ui-card-header>\n\n      <ui-card-content>\n        <div class=\"border-border/60 overflow-x-auto rounded-lg border\">\n          <div ui-table>\n            <thead ui-table-header>\n              <tr ui-table-row class=\"bg-muted/40 hover:bg-muted/40\">\n                <th ui-table-head class=\"text-xs font-semibold\">Product</th>\n                <th ui-table-head class=\"text-right text-xs font-semibold\">Current Price</th>\n                <th ui-table-head class=\"text-right text-xs font-semibold\">Target Alert</th>\n                <th ui-table-head class=\"text-right text-xs font-semibold\">90-Day Low</th>\n                <th ui-table-head class=\"text-xs font-semibold\">Channel</th>\n                <th ui-table-head class=\"text-xs font-semibold\">Status</th>\n                <th ui-table-head class=\"text-right text-xs font-semibold\">Actions</th>\n              </tr>\n            </thead>\n            <tbody ui-table-body>\n              @for (item of trackedProducts(); track item.id) {\n                <tr ui-table-row class=\"transition-colors\">\n                  <!-- Product name & image -->\n                  <td ui-table-cell class=\"py-3\">\n                    <div class=\"flex items-center gap-3\">\n                      <img\n                        [src]=\"item.image\"\n                        [alt]=\"item.name\"\n                        class=\"border-border/60 size-10 shrink-0 rounded-md border object-cover\"\n                      />\n                      <div class=\"min-w-0 space-y-0.5\">\n                        <p class=\"text-foreground max-w-56 truncate text-xs font-semibold sm:max-w-xs\">\n                          {{ item.name }}\n                        </p>\n                        <p class=\"text-muted-foreground truncate text-xs\">\n                          {{ item.variant }} · <span class=\"font-mono\">{{ item.sku }}</span>\n                        </p>\n                      </div>\n                    </div>\n                  </td>\n\n                  <!-- Current Price -->\n                  <td\n                    ui-table-cell\n                    class=\"text-foreground py-3 text-right font-mono text-xs font-semibold tabular-nums\"\n                  >\n                    \\${{ item.currentPrice.toFixed(2) }}\n                  </td>\n\n                  <!-- Target Price -->\n                  <td\n                    ui-table-cell\n                    class=\"text-warning text-warning py-3 text-right font-mono text-xs font-semibold tabular-nums\"\n                  >\n                    \\${{ item.targetPrice.toFixed(2) }}\n                  </td>\n\n                  <!-- 90-Day Low -->\n                  <td ui-table-cell class=\"text-muted-foreground py-3 text-right font-mono text-xs tabular-nums\">\n                    \\${{ item.lowest90d.toFixed(2) }}\n                  </td>\n\n                  <!-- Alert Channel -->\n                  <td ui-table-cell class=\"py-3\">\n                    <span ui-badge variant=\"outline\" class=\"gap-1 text-xs font-normal capitalize\">\n                      @if (item.channel === 'email') {\n                        <lucide-icon [img]=\"Mail\" class=\"text-muted-foreground size-3\" />\n                      } @else {\n                        <lucide-icon [img]=\"Smartphone\" class=\"text-muted-foreground size-3\" />\n                      }\n                      {{ item.channel }}\n                    </span>\n                  </td>\n\n                  <!-- Status Badge -->\n                  <td ui-table-cell class=\"py-3\">\n                    @if (item.status === 'reached') {\n                      <span\n                        ui-badge\n                        variant=\"outline\"\n                        class=\"border-success/30 bg-success/15 text-success gap-1 text-xs font-semibold\"\n                      >\n                        <lucide-icon [img]=\"Check\" class=\"size-3\" /> Target Reached!\n                      </span>\n                    } @else {\n                      <span ui-badge variant=\"secondary\" class=\"text-muted-foreground gap-1 text-xs font-medium\">\n                        <lucide-icon [img]=\"TrendingDown\" class=\"text-warning size-3\" /> Monitoring (-\\${{\n                          (item.currentPrice - item.targetPrice).toFixed(0)\n                        }})\n                      </span>\n                    }\n                  </td>\n\n                  <!-- Actions -->\n                  <td ui-table-cell class=\"py-3 text-right\">\n                    <div class=\"flex items-center justify-end gap-1.5\">\n                      <button\n                        ui-button\n                        variant=\"ghost\"\n                        size=\"sm\"\n                        class=\"text-muted-foreground hover:text-destructive size-8 p-0\"\n                        title=\"Remove Tracker\"\n                        (click)=\"handleRemoveProduct(item.id)\"\n                      >\n                        <lucide-icon [img]=\"Trash2\" class=\"size-3.5\" />\n                      </button>\n                    </div>\n                  </td>\n                </tr>\n              }\n            </tbody>\n          </div>\n        </div>\n      </ui-card-content>\n    </ui-card>\n  `,\n})\nexport class UiPriceDropAlertCardComponent implements OnDestroy {\n  @Input('class') className?: string\n\n  protected readonly cn = cn\n\n  protected readonly BellRing = BellRing\n  protected readonly Check = Check\n  protected readonly History = History\n  protected readonly Mail = Mail\n  protected readonly RefreshCw = RefreshCw\n  protected readonly ShieldCheck = ShieldCheck\n  protected readonly Smartphone = Smartphone\n  protected readonly Tag = Tag\n  protected readonly Trash2 = Trash2\n  protected readonly TrendingDown = TrendingDown\n  protected readonly Zap = Zap\n\n  readonly currentPrice = 299.0\n  readonly msrpPrice = 349.0\n  readonly lowest90dPrice = 279.0\n\n  readonly alertMethod = signal<PriceAlertChannel>('email')\n  readonly targetPrice = signal(280)\n  readonly inStockNotification = signal(true)\n  readonly alertSaved = signal(false)\n  readonly isRefreshing = signal(false)\n  readonly trackedProducts = signal<TrackedProduct[]>(initialTrackedProducts.map((p) => ({ ...p })))\n\n  // Dynamic savings calculations\n  readonly additionalSavings = computed(() => Math.max(0, this.currentPrice - this.targetPrice()))\n  readonly additionalSavingsPercent = computed(() =>\n    this.currentPrice > 0 ? ((this.additionalSavings() / this.currentPrice) * 100).toFixed(1) : '0.0',\n  )\n\n  // Dynamic SVG Chart Target Line Calculation\n  // Y range: $240 (y=150) to $360 (y=20), height=130, span=120\n  readonly targetY = computed(() => {\n    const clampedTarget = Math.max(240, Math.min(360, this.targetPrice()))\n    return 150 - ((clampedTarget - 240) / 120) * 130\n  })\n  readonly targetTransform = computed(() => `translate(565, ${this.targetY()})`)\n\n  readonly alertDestination = computed(() =>\n    this.alertMethod() === 'email' ? 'customer@example.com' : '+1 (555) 019-2834',\n  )\n\n  private refreshTimer: ReturnType<typeof setTimeout> | undefined\n\n  get hostClass(): string {\n    return cn('mx-auto block w-full max-w-5xl space-y-6', this.className)\n  }\n\n  methodClass(method: PriceAlertChannel): string {\n    return cn(\n      'flex cursor-pointer items-center gap-3 rounded-lg border p-3.5 transition-colors',\n      this.alertMethod() === method\n        ? 'border-primary bg-primary/5 ring-primary/20 shadow-xs ring-1'\n        : 'border-border bg-card hover:bg-muted/40',\n    )\n  }\n\n  setAlertMethod(value: string): void {\n    this.alertMethod.set(value === 'sms' ? 'sms' : 'email')\n  }\n\n  onSliderChange(value: number[]): void {\n    const next = value[0]\n    if (next !== undefined) this.targetPrice.set(next)\n  }\n\n  handleSetAlert(): void {\n    this.alertSaved.set(true)\n  }\n\n  handlePresetClick(price: number): void {\n    this.targetPrice.set(price)\n  }\n\n  handleRemoveProduct(id: string): void {\n    this.trackedProducts.update((prev) => prev.filter((p) => p.id !== id))\n  }\n\n  triggerRefresh(): void {\n    this.isRefreshing.set(true)\n    clearTimeout(this.refreshTimer)\n    this.refreshTimer = setTimeout(() => {\n      this.isRefreshing.set(false)\n    }, 600)\n  }\n\n  ngOnDestroy(): void {\n    clearTimeout(this.refreshTimer)\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/price-drop-alert-card/price-drop-alert-card.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/price-drop-alert-card/index.ts",
      "content": "export {\n  UiPriceDropAlertCardComponent,\n  type PriceAlertChannel,\n  type TrackedProduct,\n} from './price-drop-alert-card.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/price-drop-alert-card/index.ts"
    }
  ],
  "dependencies": [
    "lucide-angular"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "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/radio-group.json",
    "https://uipkge.dev/r/angular/separator.json",
    "https://uipkge.dev/r/angular/slider.json",
    "https://uipkge.dev/r/angular/switch.json",
    "https://uipkge.dev/r/angular/table.json"
  ],
  "description": "E-commerce wishlist price tracker with 90-day price history chart, dynamic target price threshold slider, multi-channel alert configurator, and active tracked items table.",
  "categories": [
    "commerce",
    "ecommerce"
  ]
}