type
concept
created
Mon Apr 06 2026 02:00:00 GMT+0200 (Central European Summer Time)
updated
Mon Apr 06 2026 02:00:00 GMT+0200 (Central European Summer Time)
sources
wiki/concepts/portfolio-command-center, wiki/concepts/slug-based-urls
tags
feature portfolio units ui
aliases
units-list, units-page

Units Page

abstract
Standalone paginated unit list at `/units` — 6,666 units with KPI cards, multi-filter bar, enriched table with lifecycle status and tenant info. Foundation for F1.4 Portfolio Command Center.

Overview

Previously, units were only accessible by drilling into property detail → building grid → clicking a unit. This page gives a portfolio-wide view of all units in a single filterable table.

URL: /units (sidebar → Portfolio → Units)

KPI Cards

Four summary cards at top:

  1. Total Units — 6,666 (occupied + vacant counts)
  2. Occupancy — 93.9% (6,258 / 6,666)
  3. Avg Rent — $1,189/mo (lease avg vs market avg)
  4. Monthly Revenue — $6.7M from active leases

Filters

Server-side filtering via query params:

Table Columns

Column Source Notes
Unit unit_number Bold, primary color
Property property_name Muted
Building building_name Hidden on mobile
Bed/Bath/Sqft Unit fields Condensed format
Rent lease_rent or market_rent Tabular nums, right-aligned
Status lifecycle_status Color-coded pill
Tenant tenant_first + tenant_last Hidden on small screens

Pagination: 50 units/page, server-side via LIMIT/OFFSET.

Lifecycle Status Display

Status Color Source
Active Green (#16a34a) tenant_lease_lifecycle.lease_status = 'active'
Month-to-Month Amber (#b45309) lease_status = 'month_to_month'
Notice Red (#b91c1c) lease_status = 'notice'
Vacant Muted units_unit.status = 'available'
Occupied (no lifecycle) Neutral status = 'occupied' but no lifecycle record (1,641 units)

Available Unit Data (DB)

All data below is joinable to units_unit via tenant_lease.unit_id or units_maintenance.unit_id.

Ledger Entries (tenant_ledger_entry)

Recurring Charges (tenant_recurring_charge)

Maintenance (units_maintenance)

Work Order Lifecycle (work_order_lifecycle)

Risk Scores (unit_risk_score)

Renewal Recommendations (renewal_recommendation)

Collection Cases (collection_case)

Additional Tables (empty or minimal)

Data Coverage

API Endpoints

Endpoint Method Purpose
/api/units/stats GET KPI card data (counts, averages, totals)
/api/units/properties GET Property dropdown options
/api/units GET Paginated, filtered unit list with JOINs

The enhanced /api/units endpoint joins:

units_unit → properties → properties_building → tenant_lease → tenant_lease_lifecycle → tenants

Unit Detail Tabs

The unit detail page (unit-detail.component.ts) has 5 functional tabs, each showing tab-specific content via @switch(activeTab()):

Overview (default)

Tenant

Financials

Maintenance

Compliance

Computed Signals Added

Implementation Files

File Role
src/app/features/units/units.component.ts Units list page (OnPush, signals)
src/app/features/properties/unit-detail.component.ts Unit detail page with 5 functional tabs
src/app/core/services/property.service.ts UnitListItem, UnitListStats, UnitDetail interfaces + service methods
src/app/app.routes.ts Route /units → lazy-loaded UnitsComponent
src/app/layouts/sidebar/sidebar.component.ts "Units" nav item under Portfolio
server.js 3 API endpoints (stats, properties, units)

Row Navigation

Clicking a row navigates via slug-based URL:

/property-management/{slugify(property_name)}/units/{unit_number}

Reuses existing UnitDetailComponent and by-name resolution endpoint.

Relationship to F1.4

This page is the foundation for the wiki/concepts/portfolio-command-center (F1.4). Future additions:

Sources

Related