The booking detail page at /dashboard/shop-rentals/bookings/[id] is
where every operator action lives once a reservation exists. This is a
section-by-section walkthrough.
Header
Top of the page shows:
- ← Back to Bookings link
- Booking number ("#12345")
- Status badge (color-coded)
- Created timestamp
Top-right action buttons (visibility depends on status):
- Refund — only when remaining refundable balance > 0
- Cancel Booking — only when status is pending, confirmed, or checked_in
Late return banner
If the late-fee cron has flagged this booking, an amber banner appears between the header and main content:
⚠ Late return
This rental is past the scheduled return time.
Computed late fee: $15.00
[Apply late fee]
Click Apply late fee to add the fee as an adjustment_cents and
clear the late flag. See Late returns.
Main columns
The page is a 2/3 + 1/3 split.
Left column (2/3)
Schedule
- Scheduled pickup and return times
- Actual pickup / return (only if stamped)
- Duration (days or hours)
- Rate type (hourly / daily / weekly)
Financial summary
- Base cost
- Overage (if any — for distance-based pricing)
- Promo / adjustments
- Subtotal
- Tax
- Cancellation fee (if cancelled)
- Total
- Deposit (held, captured, or released)
- Amount paid
- Refunded
- Balance due
This is the source of truth for accounting. If anything looks off,
check the pricing_snapshot on the database row to verify what tier
was applied.
Distance (e-bike / scooter only)
- Total km traveled
- Included km
- Overage km
- Overage cost
Customer card
- Name, email, phone, customer number
- Link to full customer profile
Vehicle / model card
- Assigned vehicle (or model with "unassigned" indicator)
- Link to vehicle detail page
Assignments section (model-bookings only)
If the booking was made at the model level (not vehicle-specific), this section shows:
- List of currently assigned vehicles
- Eligible-vehicles dropdown for adding more
- UUID-paste fallback (rarely needed)
- Release buttons per assignment
- Unassigned count
Delivery section (delivery bookings only)
- Address
- Time slot
- Delivery fee
- Notes
- Status (pending → confirmed → en_route → delivered)
- State-machine action buttons (Confirm, Reject, Mark En Route, Mark Delivered)
- Rejection dialog with required reason
- Audit log (every status change)
Right column (1/3)
Counter actions
Quick links specific to this booking:
- View customer profile
- View assigned vehicle
- Open the public manage-link (if one was issued)
Admin notes
Editable text field for operator-only notes. Customers don't see this. Click Edit to enter, Save to commit. Use for things like: "Customer asked for shorter saddle," "Damage on left grip noted at pickup, not chargeable."
Cancellation details (if cancelled)
- Cancelled at, by whom
- Reason
- Cancellation fee captured
Payment Info (if Stripe IDs exist)
- Deposit Intent ID (raw Stripe ID for support lookups)
- Payment Intent ID
Agreements & Waivers
The waivers panel shows:
- Pending waivers — with "Copy link" button
- Signed waivers — with timestamp, typed name, optional PDF link
- "Issue signing link" buttons for each active template
See Issuing a signing link for the full workflow.
Modals (overlays)
Refund Modal
Triggered by the Refund button.
- Destination: Wallet / Card
- Mode: Full / Partial
- Amount field (only for partial)
- Reason text area
- Confirm + Go Back buttons
Cancel Dialog
Triggered by the Cancel Booking button.
- Reason text area (optional)
- Confirm Cancel + Go Back buttons
The cancel API auto-issues a wallet refund for paid - cancellation_fee
if within the free-cancel window. See
Cancellation handling.
Reject Delivery Dialog
Only visible on delivery bookings in pending status. Requires a reason (rejected deliveries are auditable).
Editing fields
Most fields are read-only on this page. Use the PATCH endpoint or specific sub-routes for changes:
| Action | Endpoint |
|---|---|
| Change pickup/return time | PATCH /api/reservations/[id] {pickup_at, return_at} |
| Reassign vehicle | Same PATCH with vehicle_uuid |
| Adjust pricing manually | PATCH /api/reservations/[id] {adjustment_cents, adjustment_reason} |
| Update admin notes | The Edit button on the page |
What you can't see / do here
- Print receipt — visit
/api/reservations/[id]/receiptfor the PDF - Charge a card — the existing capture-authorized cron handles this; manual capture is via the admin charge-card endpoint
- Refund the cancellation fee — the refund flow doesn't yet have a "refund only the cancellation fee" mode; use partial refund matching the fee amount
- Resend confirmation email — not yet exposed; planned feature
Common booking-detail workflows
Pickup-day prep
- Find the booking in today's manifest, click in
- Verify the assignment (specific vehicle picked)
- Check that any required waivers are signed
- If the customer has prepaid, balance_due should be $0
- Press Check in then Start rental when they arrive
Mid-rental change
- Open the booking
- Edit
return_at(extend) or swap vehicles via assignment - Save — the pricing snapshot is preserved unless the new total exceeds the original tier's max duration
Post-return follow-up
- Open the completed booking
- Confirm receipts and refunds match expectations
- If damage was logged, verify the service log entry
- Issue any post-hoc charge or refund as needed
Running a fleet on this hardware?
Levy Fleets runs scooters, e-bikes, mopeds and golf carts on the IoT hardware you already have, with integration pages for 29 vendors including Segway, Okai, Omni, Queclink, Invers and Comodule. Keyless unlock, geofencing, rider payments and rider support are included, and the Managed plan is a share of revenue with no per-vehicle software fee.