2.8 KiB
Story Tab
Nav id: story
Icon: ◇
What it shows
The relationship archive — past meetings, gifts received, a hotel reveal (if Quinn shared hotel info), and a referral code section. This is the sentimental/historical view; upcoming meetings live in the Dates tab.
Data flow
getRelationship(token) — GET /vip/relationship/:token — returns the full relationship object. Story filters meetings to meetingDate <= now.
Same endpoint as Dates tab, independent fetch per mount.
Relationship object (relevant fields)
interface VipRelationship {
invite: {
label: string | null // client name (used in WelcomeScreen too)
tier: VipTier | null // reputation tier set by Quinn
}
meetings: VipMeeting[]
gifts: VipGift[]
hotel?: VipHotel // absent when not yet revealed
}
type VipTier = 'bronze' | 'silver' | 'gold' | 'diamond'
interface VipGift {
id: string
item: string
receivedAt: string // ISO 8601
estimatedValue: number | null
gifterNote: string | null
}
interface VipHotel {
hotelName: string
hotelAddress: string | null
}
Sections
Meetings (past only)
Past meetings rendered oldest-to-newest (API order assumed). Shows date, duration, location, and any note Quinn left. Same card design as Dates tab but without the "Confirmed" badge.
Gifts
Renders if gifts.length > 0. Each card shows item name, received date, estimated value (if set), and a gifter note in italic.
Hotel
HotelSection renders if relationship.hotel is non-null. Shows hotel name and address with a "for your eyes only" confidentiality note. Quinn controls whether to expose this.
Referrals
ReferralsSection is always rendered at the bottom of Story. It has two parts:
- Outbound codes —
getMyReferrals(token)→GET /vip/referrals/mine?token=<token>. Lists codes this client owns with used/unused badges. - Redeem form —
redeemReferralCode(token, code)→POST /vip/referrals/redeem. Inline error handling forreferral_already_used,referral_not_found,self_referral.
Empty state
If both pastMeetings.length === 0 and gifts.length === 0, the tab shows "Your story together is just beginning." Hotel and referrals still render below even in the empty state.
Non-obvious details
- Hotel info is withheld by default — the API only returns a non-null
hotelobject when Quinn explicitly chooses to share it via the admin panel. ReferralsSectionis glued to the bottom of Story (not its own tab) because it's contextually part of the client's relationship narrative.invite.labelfrom this endpoint is also read inVipPortalPagefor the welcome splash — two separategetRelationshipcalls run (welcome check on unlock, story fetch on tab open).