Offers Dashboard
Offers Dashboard
The Offers dashboard provides a multi-stage pipeline view for managing rental offers. It is available at /dashboard/offers.
Pipeline Stages
Offers move through nine sequential stages:
| Stage | Description |
|---|---|
| Invited | Applicant has been invited to make an offer |
| In Progress | Offer is being prepared |
| With Agent | Offer is under agent review |
| Awaiting Amendments | Changes have been requested |
| Sent to Landlord | Offer has been forwarded to the landlord |
| Landlord Reviewed | Landlord has reviewed the offer |
| Accepted | Offer accepted |
| Rejected | Offer rejected |
| Cancelled | Offer withdrawn or cancelled |
Each stage column is colour-coded. The badge and header colour are consistent across the pipeline view and the offer detail page.
Offer Cards
Each card in the pipeline displays:
- Applicant name
- Property address (if assigned)
- Offered rent (monthly)
- Last updated timestamp (relative, e.g. "3 hours ago")
Clicking a card opens the full offer detail page.
Filtering & Search
Property Filter
A dropdown above the pipeline lists all active properties. Selecting a property filters the pipeline to show only offers for that property.
The selected property is reflected in the URL as a ?propertyId= query parameter, so filtered views can be bookmarked or shared.
Example URL:
/dashboard/offers?propertyId=prop_abc123
Search
The search bar filters cards by applicant name or property address. Search and property filter can be used together.
Offer Detail Page
Each offer has a dedicated detail page at:
/dashboard/offers/[id]
The detail page shows:
| Field | Description |
|---|---|
| Applicant | Full name of the applicant |
| Property | Property address linked to the offer |
| Offered Rent | Monthly rent amount proposed |
| Assigned Agent | User ID of the agent handling the offer |
| Created | Full date and time the offer was created |
| Last Updated | Relative time since the last change |
| Status | Colour-coded badge matching the pipeline stage |
A Back to offers link returns to the pipeline view.
While the offer is loading, a skeleton placeholder is shown. If the offer cannot be found or an error occurs, an error message is displayed.
Data Model
The offers table includes the following property-related columns added in v0.1.21:
propertyId: text("property_id") // foreign key to the properties table
propertyAddress: text("property_address") // denormalised address for display
An index (offers_property_idx) is created on propertyId for efficient filtering.
Audit Logging
All write operations on offers are audit-logged:
- Create — logged when a new offer is submitted
- Update — logged when offer fields are changed
- Status change — logged each time the stage changes
API Reference (tRPC)
All procedures are under the offer router.
offer.list
Returns a paginated list of offers.
Input filters:
| Parameter | Type | Description |
|---|---|---|
propertyId | string (optional) | Filter by property |
search | string (optional) | Search by applicant name or property address |
offer.pipelineSummary
Returns offer counts grouped by pipeline stage.
Input filters:
| Parameter | Type | Description |
|---|---|---|
propertyId | string (optional) | Scope summary to a single property |
offer.listProperties
Returns all active properties. Used to populate the property filter dropdown.
offer.getById
Returns a single offer by ID.
Input:
| Parameter | Type | Description |
|---|---|---|
offerId | string | The offer ID |
offer.create
Creates a new offer. Triggers an audit log entry.
New fields in v0.1.21:
| Field | Type | Description |
|---|---|---|
propertyId | string (optional) | Property to associate |
propertyAddress | string (optional) | Address for display |
offer.update
Updates an existing offer. Triggers an audit log entry.
New fields in v0.1.21: same as create above.