{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "tenant-rent-ledger",
  "title": "Tenant Rent Ledger",
  "type": "registry:block",
  "files": [
    {
      "path": "packages/registry-angular/blocks/tenant-rent-ledger/tenant-rent-ledger.component.ts",
      "content": "// Property management resident portal with tenant header, 4 financial\n// overview cards (monthly rent, next due date, autopay status, escrow deposit),\n// autopay toggle with date schedule selection, and a complete 6-record payment\n// ledger with receipt actions. Port of the React block 1:1.\nimport { ChangeDetectionStrategy, Component, Input, signal } from '@angular/core'\nimport {\n  Building2,\n  Calendar,\n  CheckCircle2,\n  Clock,\n  CreditCard,\n  Download,\n  Home,\n  Landmark,\n  LucideAngularModule,\n  ShieldCheck,\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  UiCardHeaderComponent,\n  UiCardTitleComponent,\n} from '@/ui/card/card.component'\nimport { UiSeparatorComponent } from '@/ui/separator/separator.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 interface PaymentRecord {\n  id: string\n  period: string\n  description: string\n  dueDate: string\n  paidDate: string\n  method: string\n  methodType: 'ach' | 'card' | 'wire'\n  amount: string\n  status: 'paid' | 'waived'\n  statusLabel: string\n}\n\ninterface FinancialCard {\n  title: string\n  value: string\n  unit: string\n  description: string\n  icon: typeof Home\n  iconColor: string\n}\n\nconst financialCards: FinancialCard[] = [\n  {\n    title: 'Monthly Base Rent',\n    value: '$3,450.00',\n    unit: '/ mo',\n    description: 'Fixed lease rate through Jul 2027',\n    icon: Home,\n    iconColor: 'bg-primary/10 text-primary',\n  },\n  {\n    title: 'Next Due Date',\n    value: 'Sep 01, 2026',\n    unit: '',\n    description: 'Due in 11 days · Grace period to Sep 5',\n    icon: Calendar,\n    iconColor: 'bg-info/10 text-info',\n  },\n  {\n    title: 'Autopay Status',\n    value: 'Active',\n    unit: '',\n    description: 'Scheduled for 1st of month with Visa •••• 4892',\n    icon: Zap,\n    iconColor: 'bg-success/10 text-success',\n  },\n  {\n    title: 'Security Deposit on File',\n    value: '$3,450.00',\n    unit: '',\n    description: 'Held in Escrow (Interest Bearing)',\n    icon: ShieldCheck,\n    iconColor: 'bg-warning/10 text-warning',\n  },\n]\n\nconst paymentRecords: PaymentRecord[] = [\n  {\n    id: 'pay-2026-08',\n    period: 'August 2026 Rent',\n    description: 'Base Rent ($3,400.00) + High-Speed Fiber ($50.00)',\n    dueDate: 'Aug 01, 2026',\n    paidDate: 'Aug 01, 2026',\n    method: 'ACH Transfer · Chase •••• 4892',\n    methodType: 'ach',\n    amount: '$3,450.00',\n    status: 'paid',\n    statusLabel: 'Paid on Time',\n  },\n  {\n    id: 'pay-2026-07',\n    period: 'July 2026 Rent',\n    description: 'Base Rent ($3,400.00) + Assigned Parking Spot #4B ($50.00)',\n    dueDate: 'Jul 01, 2026',\n    paidDate: 'Jul 01, 2026',\n    method: 'ACH Transfer · Chase •••• 4892',\n    methodType: 'ach',\n    amount: '$3,450.00',\n    status: 'paid',\n    statusLabel: 'Paid on Time',\n  },\n  {\n    id: 'pay-2026-06',\n    period: 'June 2026 Rent',\n    description: 'Base Rent ($3,400.00) + Water & Sewer Allocation ($50.00)',\n    dueDate: 'Jun 01, 2026',\n    paidDate: 'Jun 03, 2026',\n    method: 'Visa •••• 4892',\n    methodType: 'card',\n    amount: '$3,450.00',\n    status: 'waived',\n    statusLabel: 'Late Fee Waived',\n  },\n  {\n    id: 'pay-2026-05',\n    period: 'May 2026 Rent',\n    description: 'Base Rent ($3,400.00) + Storage Locker #12 ($50.00)',\n    dueDate: 'May 01, 2026',\n    paidDate: 'May 01, 2026',\n    method: 'ACH Transfer · Chase •••• 4892',\n    methodType: 'ach',\n    amount: '$3,450.00',\n    status: 'paid',\n    statusLabel: 'Paid on Time',\n  },\n  {\n    id: 'pay-2026-04',\n    period: 'April 2026 Rent',\n    description: 'First Full Month Base Rent ($3,400.00) + Pet Rent ($50.00)',\n    dueDate: 'Apr 01, 2026',\n    paidDate: 'Apr 01, 2026',\n    method: 'ACH Transfer · Chase •••• 4892',\n    methodType: 'ach',\n    amount: '$3,450.00',\n    status: 'paid',\n    statusLabel: 'Paid on Time',\n  },\n  {\n    id: 'pay-2026-03-dep',\n    period: 'Security Deposit & Move-In Fee',\n    description: '100% Refundable Security Escrow Deposit + Key Fob Activation',\n    dueDate: 'Mar 15, 2026',\n    paidDate: 'Mar 15, 2026',\n    method: 'Wire Transfer · Wells Fargo •••• 1044',\n    methodType: 'wire',\n    amount: '$3,450.00',\n    status: 'paid',\n    statusLabel: 'Paid on Time',\n  },\n]\n\n@Component({\n  changeDetection: ChangeDetectionStrategy.Eager,\n  selector: 'ui-tenant-rent-ledger, [ui-tenant-rent-ledger]',\n  standalone: true,\n  // React renders the root <div> itself: the host stays out of layout and `class` goes to the root.\n  host: { '[attr.class]': '\"contents\"' },\n  imports: [\n    LucideAngularModule,\n    UiBadgeComponent,\n    UiButtonComponent,\n    UiCardComponent,\n    UiCardContentComponent,\n    UiCardDescriptionComponent,\n    UiCardHeaderComponent,\n    UiCardTitleComponent,\n    UiSeparatorComponent,\n    UiSwitchComponent,\n    UiTableBodyComponent,\n    UiTableCellComponent,\n    UiTableComponent,\n    UiTableHeadComponent,\n    UiTableHeaderComponent,\n    UiTableRowComponent,\n  ],\n  template: `\n    <div data-slot=\"tenant-rent-ledger\" [class]=\"rootClass\">\n      <!-- Resident & Unit Header -->\n      <div\n        class=\"bg-card flex flex-col gap-4 rounded-xl border p-5 shadow-xs sm:flex-row sm:items-center sm:justify-between\"\n      >\n        <div class=\"space-y-1.5\">\n          <div class=\"flex flex-wrap items-center gap-2.5\">\n            <h2 class=\"text-foreground text-xl font-bold tracking-tight sm:text-2xl\">Elena Rostova</h2>\n            <span ui-badge variant=\"secondary\" class=\"text-xs font-semibold\"> Unit 4B </span>\n            <span ui-badge variant=\"outline\" class=\"border-success/20 bg-success/10 text-success text-xs font-medium\">\n              <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-3\" />\n              $0.00 Paid in Full\n            </span>\n          </div>\n          <div class=\"text-muted-foreground flex items-center gap-1.5 text-xs sm:text-sm\">\n            <lucide-icon [img]=\"Building2\" class=\"text-muted-foreground size-4 shrink-0\" />\n            <span>Pacific Heights Luxury Residences, San Francisco</span>\n          </div>\n        </div>\n        <div class=\"flex items-center gap-3 self-start sm:self-auto\">\n          <button ui-button class=\"font-medium shadow-xs\">\n            <lucide-icon [img]=\"CreditCard\" class=\"size-4\" />\n            Pay Rent Now\n          </button>\n        </div>\n      </div>\n\n      <!-- 4 Financial Overview Cards -->\n      <div class=\"grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4\">\n        @for (card of financeCards; track card.title) {\n          <div ui-card class=\"shadow-xs\">\n            <div ui-card-content class=\"space-y-2 p-5\">\n              <div class=\"flex items-center justify-between gap-2\">\n                <p class=\"text-muted-foreground text-xs font-medium\">{{ card.title }}</p>\n                <div [class]=\"cardIconClass(card)\">\n                  <lucide-icon [img]=\"card.icon\" class=\"size-4\" />\n                </div>\n              </div>\n              <div>\n                <div class=\"flex items-baseline gap-1\">\n                  <p class=\"text-foreground text-2xl font-bold tracking-tight tabular-nums\">{{ card.value }}</p>\n                  @if (card.unit) {\n                    <span class=\"text-muted-foreground text-xs font-normal\">{{ card.unit }}</span>\n                  }\n                </div>\n                <p class=\"text-muted-foreground mt-1 text-xs\">{{ card.description }}</p>\n              </div>\n            </div>\n          </div>\n        }\n      </div>\n\n      <!-- Autopay & Payment Method Card -->\n      <div ui-card class=\"shadow-xs\">\n        <div ui-card-header>\n          <div class=\"flex items-center justify-between\">\n            <div>\n              <h3 ui-card-title class=\"text-base font-semibold\">Autopay &amp; Payment Preferences</h3>\n              <p ui-card-description class=\"text-xs\">\n                Configure automatic monthly rent deduction and manage saved funding methods.\n              </p>\n            </div>\n            @if (autopayEnabled()) {\n              <span ui-badge variant=\"outline\" class=\"border-success/20 bg-success/10 text-success text-xs font-medium\">\n                Autopay Active\n              </span>\n            } @else {\n              <span ui-badge variant=\"secondary\" class=\"text-xs font-medium\"> Autopay Paused </span>\n            }\n          </div>\n        </div>\n        <div ui-card-content class=\"space-y-5\">\n          <!-- Toggle Autopay Switch -->\n          <div\n            class=\"bg-muted/30 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              <label for=\"autopay-toggle\" class=\"text-foreground cursor-pointer text-sm font-medium\">\n                Enable Automatic Rent Deductions\n              </label>\n              <p class=\"text-muted-foreground text-xs\">\n                Automatically charge your primary payment method on your selected schedule before due date.\n              </p>\n            </div>\n            <button\n              ui-switch\n              id=\"autopay-toggle\"\n              [checked]=\"autopayEnabled()\"\n              (checkedChange)=\"autopayEnabled.set($event)\"\n            ></button>\n          </div>\n\n          <div ui-separator></div>\n\n          <!-- Primary Bank Account / Card -->\n          <div class=\"space-y-3\">\n            <div class=\"flex items-center justify-between\">\n              <h4 class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                Primary Payment Method\n              </h4>\n              <button ui-button variant=\"ghost\" size=\"xs\" class=\"text-primary hover:text-primary text-xs font-medium\">\n                Change Method\n              </button>\n            </div>\n            <div class=\"flex flex-col gap-3 rounded-lg border p-4 sm:flex-row sm:items-center sm:justify-between\">\n              <div class=\"flex items-center gap-3.5\">\n                <div\n                  class=\"bg-background flex size-10 shrink-0 items-center justify-center rounded-lg border shadow-xs\"\n                >\n                  <lucide-icon [img]=\"CreditCard\" class=\"text-foreground size-5\" />\n                </div>\n                <div class=\"space-y-0.5\">\n                  <div class=\"flex items-center gap-2\">\n                    <span class=\"text-foreground text-sm font-semibold tabular-nums\">Visa •••• 4892</span>\n                    <span ui-badge variant=\"secondary\" class=\"text-xs font-normal\">Default</span>\n                  </div>\n                  <p class=\"text-muted-foreground text-xs\">Elena Rostova · Expires 08/28 · Bank of America</p>\n                </div>\n              </div>\n              <div class=\"flex items-center gap-2\">\n                <span ui-badge variant=\"outline\" class=\"border-success/20 bg-success/10 text-success text-xs\">\n                  <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-3\" />\n                  Verified for ACH &amp; Debit\n                </span>\n              </div>\n            </div>\n          </div>\n\n          <div ui-separator></div>\n\n          <!-- Autopay Date Selector (1st vs 5th) -->\n          <div class=\"space-y-3\">\n            <div class=\"space-y-0.5\">\n              <h4 class=\"text-muted-foreground text-xs font-semibold tracking-wider uppercase\">\n                Scheduled Deduction Date\n              </h4>\n              <p class=\"text-muted-foreground text-xs\">\n                Select when rent will be debited from your account each cycle.\n              </p>\n            </div>\n            <div class=\"grid grid-cols-1 gap-3 sm:grid-cols-2\">\n              <button\n                type=\"button\"\n                [disabled]=\"!autopayEnabled()\"\n                [class]=\"scheduleOptionClass('1st')\"\n                (click)=\"autopayDay.set('1st')\"\n              >\n                <div [class]=\"scheduleRadioClass('1st')\">\n                  @if (autopayDay() === '1st' && autopayEnabled()) {\n                    <span class=\"bg-background size-1.5 rounded-full\"></span>\n                  }\n                </div>\n                <div class=\"space-y-1\">\n                  <div class=\"flex items-center gap-2\">\n                    <span class=\"text-foreground text-sm font-medium\">1st of the month</span>\n                    <span\n                      ui-badge\n                      variant=\"outline\"\n                      class=\"border-success/20 bg-success/10 text-success text-xs font-medium\"\n                    >\n                      Recommended\n                    </span>\n                  </div>\n                  <p class=\"text-muted-foreground text-xs\">\n                    Debited promptly on the rent due date. Ensures zero delinquency risk.\n                  </p>\n                </div>\n              </button>\n\n              <button\n                type=\"button\"\n                [disabled]=\"!autopayEnabled()\"\n                [class]=\"scheduleOptionClass('5th')\"\n                (click)=\"autopayDay.set('5th')\"\n              >\n                <div [class]=\"scheduleRadioClass('5th')\">\n                  @if (autopayDay() === '5th' && autopayEnabled()) {\n                    <span class=\"bg-background size-1.5 rounded-full\"></span>\n                  }\n                </div>\n                <div class=\"space-y-1\">\n                  <div class=\"flex items-center gap-2\">\n                    <span class=\"text-foreground text-sm font-medium\">5th of the month</span>\n                    <span ui-badge variant=\"secondary\" class=\"text-xs font-normal\"> Grace Period </span>\n                  </div>\n                  <p class=\"text-muted-foreground text-xs\">\n                    Processes within the standard 5-day building grace window before late fees.\n                  </p>\n                </div>\n              </button>\n            </div>\n          </div>\n        </div>\n      </div>\n\n      <!-- Payment History Ledger Table -->\n      <div class=\"space-y-3\">\n        <div class=\"flex flex-col gap-2 sm:flex-row sm:items-center sm:justify-between\">\n          <div>\n            <h3 class=\"text-foreground text-base font-semibold tracking-tight\">Payment History &amp; Ledger</h3>\n            <p class=\"text-muted-foreground text-xs\">\n              Complete transaction record of monthly rent charges, utility allocations, and security deposits.\n            </p>\n          </div>\n          <button\n            ui-button\n            aria-label=\"Download attachment\"\n            variant=\"outline\"\n            size=\"sm\"\n            class=\"self-start sm:self-auto\"\n          >\n            <lucide-icon [img]=\"Download\" class=\"size-4\" />\n            Download Statement (PDF)\n          </button>\n        </div>\n\n        <div class=\"bg-card overflow-x-auto rounded-lg border shadow-xs\">\n          <table ui-table>\n            <thead ui-table-header>\n              <tr ui-table-row>\n                <th ui-table-head>Billing Period &amp; Description</th>\n                <th ui-table-head>Due Date</th>\n                <th ui-table-head>Paid Date</th>\n                <th ui-table-head>Payment Method</th>\n                <th ui-table-head class=\"text-right\">Amount Paid</th>\n                <th ui-table-head>Status</th>\n                <th ui-table-head class=\"text-right\"><span class=\"sr-only\">Actions</span></th>\n              </tr>\n            </thead>\n            <tbody ui-table-body>\n              @for (record of records; track record.id) {\n                <tr ui-table-row class=\"hover:bg-muted/50\">\n                  <td ui-table-cell>\n                    <div class=\"text-foreground text-sm font-medium\">{{ record.period }}</div>\n                    <div class=\"text-muted-foreground text-xs\">{{ record.description }}</div>\n                  </td>\n                  <td ui-table-cell class=\"text-muted-foreground text-sm tabular-nums\">{{ record.dueDate }}</td>\n                  <td ui-table-cell class=\"text-foreground text-sm font-medium tabular-nums\">{{ record.paidDate }}</td>\n                  <td ui-table-cell>\n                    <div class=\"text-foreground flex items-center gap-1.5 text-xs sm:text-sm\">\n                      @if (record.methodType === 'ach') {\n                        <lucide-icon [img]=\"Landmark\" class=\"text-muted-foreground size-3.5 shrink-0\" />\n                      } @else if (record.methodType === 'card') {\n                        <lucide-icon [img]=\"CreditCard\" class=\"text-muted-foreground size-3.5 shrink-0\" />\n                      } @else {\n                        <lucide-icon [img]=\"ShieldCheck\" class=\"text-muted-foreground size-3.5 shrink-0\" />\n                      }\n                      <span class=\"truncate\">{{ record.method }}</span>\n                    </div>\n                  </td>\n                  <td ui-table-cell class=\"text-foreground text-right text-sm font-bold tabular-nums\">\n                    {{ record.amount }}\n                  </td>\n                  <td ui-table-cell>\n                    @if (record.status === 'paid') {\n                      <span\n                        ui-badge\n                        variant=\"outline\"\n                        class=\"border-success/20 bg-success/10 text-success text-xs font-medium whitespace-normal\"\n                      >\n                        <lucide-icon [img]=\"CheckCircle2\" class=\"text-success size-3\" />\n                        {{ record.statusLabel }}\n                      </span>\n                    } @else {\n                      <span ui-badge variant=\"outline\" class=\"border-info/20 bg-info/10 text-info text-xs font-medium\">\n                        <lucide-icon [img]=\"Clock\" class=\"text-info size-3\" />\n                        {{ record.statusLabel }}\n                      </span>\n                    }\n                  </td>\n                  <td ui-table-cell class=\"text-right\">\n                    <button\n                      ui-button\n                      variant=\"ghost\"\n                      size=\"sm\"\n                      class=\"text-muted-foreground hover:text-foreground h-8 gap-1.5 text-xs\"\n                      aria-label=\"Download receipt PDF\"\n                    >\n                      <lucide-icon [img]=\"Download\" class=\"size-3.5\" />\n                      <span>Receipt</span>\n                    </button>\n                  </td>\n                </tr>\n              }\n            </tbody>\n          </table>\n        </div>\n\n        <div\n          class=\"text-muted-foreground flex flex-col gap-3 pt-1 text-xs sm:flex-row sm:items-center sm:justify-between\"\n        >\n          <p>\n            Showing <span class=\"text-foreground font-medium\">6</span> of\n            <span class=\"text-foreground font-medium\">6</span> lease payments · Lease Ref:\n            <span class=\"font-mono\">PH-4B-2026</span>\n          </p>\n          <div class=\"flex items-center gap-2\">\n            <button ui-button variant=\"outline\" size=\"xs\" disabled>Previous</button>\n            <button ui-button variant=\"outline\" size=\"xs\" disabled>Next</button>\n          </div>\n        </div>\n      </div>\n    </div>\n  `,\n})\nexport class UiTenantRentLedgerComponent {\n  protected readonly Building2 = Building2\n  protected readonly Calendar = Calendar\n  protected readonly CheckCircle2 = CheckCircle2\n  protected readonly Clock = Clock\n  protected readonly CreditCard = CreditCard\n  protected readonly Download = Download\n  protected readonly Home = Home\n  protected readonly Landmark = Landmark\n  protected readonly ShieldCheck = ShieldCheck\n  protected readonly Zap = Zap\n\n  protected readonly financeCards = financialCards\n  protected readonly records = paymentRecords\n\n  @Input('class') className?: string\n\n  readonly autopayEnabled = signal(true)\n  readonly autopayDay = signal<'1st' | '5th'>('1st')\n\n  get rootClass(): string {\n    return cn('w-full space-y-6', this.className)\n  }\n\n  cardIconClass(card: FinancialCard): string {\n    return cn('flex size-8 shrink-0 items-center justify-center rounded-lg', card.iconColor)\n  }\n\n  scheduleOptionClass(day: '1st' | '5th'): string {\n    return cn(\n      'focus-visible:ring-ring flex cursor-pointer items-start gap-3 rounded-lg border p-3.5 text-left transition-colors duration-150 focus-visible:ring-2 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n      this.autopayDay() === day && this.autopayEnabled()\n        ? 'border-primary bg-primary/5 ring-primary ring-1'\n        : 'border-border hover:bg-muted/50',\n    )\n  }\n\n  scheduleRadioClass(day: '1st' | '5th'): string {\n    return cn(\n      'mt-0.5 flex size-4 shrink-0 items-center justify-center rounded-full border transition-colors',\n      this.autopayDay() === day && this.autopayEnabled()\n        ? 'border-primary bg-primary text-primary-foreground'\n        : 'border-muted-foreground/50',\n    )\n  }\n}\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/tenant-rent-ledger/tenant-rent-ledger.component.ts"
    },
    {
      "path": "packages/registry-angular/blocks/tenant-rent-ledger/index.ts",
      "content": "export { UiTenantRentLedgerComponent, type PaymentRecord } from './tenant-rent-ledger.component'\n",
      "type": "registry:block",
      "target": "~/src/app/components/blocks/tenant-rent-ledger/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/separator.json",
    "https://uipkge.dev/r/angular/switch.json",
    "https://uipkge.dev/r/angular/table.json"
  ],
  "description": "Property management resident portal with tenant header, 4 financial overview cards (monthly rent, next due date, autopay status, escrow deposit), autopay toggle with date schedule selection, and a complete 6-record payment ledger with receipt actions.",
  "categories": [
    "real-estate",
    "app",
    "billing",
    "dashboard"
  ]
}