lilith-platform.live/codebase/@features/vip/docs/dates.md
2026-04-19 23:39:57 -07:00

1.9 KiB

Dates Tab

Nav id: reservations (label is "Dates" — internal id kept as reservations) Icon: ◆


What it shows

Upcoming confirmed meetings between Quinn and the client, sorted ascending by date. Past meetings are excluded (they move to the Story tab). Empty state shows an explanatory message rather than nothing.


Data flow

getRelationship(token)GET /vip/relationship/:token — returns the full relationship object including all meetings. The Dates tab filters to meetingDate > now.

The same endpoint is called by the Story tab for past meetings and gifts. The two tabs share the API call but hold independent state — no shared cache, each re-fetches on mount.


Meeting object

interface VipMeeting {
  id: string
  meetingDate: string       // ISO 8601
  durationMinutes: number | null
  locationNote: string | null
  notes: string | null      // visible to client
}

Display logic

Each upcoming meeting renders:

  • Date + time (formatDatetime — weekday, month, day, year, hour:minute)
  • Duration if durationMinutes > 0 (e.g. "2h", "1h 30m")
  • locationNote — appended to duration with ·, or shown alone if no duration
  • notes — italic secondary text, visible to client
  • "Confirmed" badge (gold, always shown for upcoming — no pending state exposed to client)

Border is borderHover (brighter gold) vs the default border used in Story — slight visual distinction to make upcoming dates feel more prominent.


Non-obvious details

  • The tab id is reservations not dates — matches the API concept (a reservation = a confirmed meeting slot). The label "Dates" is the client-facing wording.
  • There is no booking UI. Clients cannot request dates from this tab — it's read-only. Booking happens out-of-band (via Messages or external scheduling).
  • Past meetings intentionally excluded here to avoid clutter. Full history is in Story.