Complete specification of the Paradise Luxury Villa property page — layout, widgets, behaviors, booking flow, and all supporting pages. Use this as the blueprint for every future property page.
| # | Section ID | Type | Purpose | Customize Per Property |
|---|---|---|---|---|
| 0 | global-header | Header/Nav | Fixed nav bar with logo, desktop links, mobile menu | ❌ Shared |
| 1 | skqn1jj | Hero | Full-height property image with gradient overlay, title, location, badges, share/save buttons, photo count | ✅ Image, title, location, bed/bath/guest count |
| 2 | soubigl | Photo Gallery | Grid of property photos (2/3/4 columns responsive), lightbox-ready | ✅ All images |
| 3 | s3u23zh | Sticky Sub-Nav | Horizontal nav links (Overview, Amenities, Rooms, Reviews, Location, House Rules) + price + CTA button. Desktop only. | ✅ Price |
| 4 | s0och9g | Overview + Booking Card | THE CORE WIDGET. Left: host info, rating, description, amenities grid. Right: sticky booking card with date picker, guest selector, two-state toggle (booking → confirm & pay), price breakdown, cancellation info, Stripe integration. | ✅ Description, amenities list, nightly rate, property image |
| 5 | sk38aqr | Availability Calendar | Dual-month calendar with date selection, availability key, footer with clear/reserve | ❌ Keep as-is |
| 6 | sn57kgd | Sleeping Arrangements | "Where you'll sleep" — grid of bedroom/living room cards with images | ✅ Room names, images, bed descriptions |
| 7 | sjyho8f | Reviews | 5.0 rating summary, category breakdown bars, individual review cards in 2-column grid | ✅ Review data, names, content |
| 8 | sywem5k | Location | "Where you'll be" — Google Maps embed + nearby highlights list | ✅ Map embed URL, nearby places |
| 9 | s1d1g4b | House Rules | Grid of rule cards with icons (check-in/out, pets, parking, safety, cancellation) | ✅ Rule specifics |
| 10 | global-footer | Footer | 4-column footer with logo, quick links, company, contact | ❌ Shared |
The booking card in section s0och9g uses two mutually exclusive states, toggled via JavaScript:
id="booking-state"
and
id="reserved-state" class="hidden"
.hidden
class between them
bg-[#E8DCC4]
for header section
The property page's
index.js
handles all interactivity. Every future property page must include
this exact JavaScript architecture.
handleDatesClick()
Toggles calendar visibility, renders months, smooth-scrolls to calendar
handleDateClick(day, month, year)
Sets checkin/checkout with range logic, re-renders
handleReserve()
Calculates pricing, populates S2 fields, switches to confirm & pay state
handleConfirmPay()
Fetches Stripe checkout session, redirects to Stripe hosted checkout
handleEditBooking()
Returns to booking state, reopens calendar for editing
renderCalendars() / renderMonth()
Builds calendar UI with proper disabled/selected/boundary states
Guest functions
toggleGuestsPopup, handleGuestsMinus/Plus, closeGuestsPopup, updateGuestDisplay
init() / teardown()
Standard lifecycle: attach/detach all event listeners
User clicks date picker → calendar expands → selects
check-in/check-out → adjusts guest count. "Check Availability"
triggers
handleReserve().
Booking card morphs into confirm & pay state. Shows property
thumbnail, trip details, price, cancellation policy. "Confirm and
pay" →
handleConfirmPay()
→ POST to Stripe API → redirect.
Stripe handles all payment collection — credit card, Apple Pay, etc. No card data touches our servers. Success redirects to confirmation page with URL parameters.
Golden fireworks canvas animation + floating gold particles. Reads booking details from URL params. Shows confirmation code (HH-2026-XXXX), property info, dates, guests, price breakdown, total paid.
Each property spawns these supporting pages. Naming convention uses the property slug.
Slug:
{property-slug}-amenities
— Full amenities list linked from the "Show all amenities" button
in the overview section.
Slug:
request-to-book
— Two-column layout: left has property detail widget (image, trip
summary, price breakdown, cancellation policy), right has payment
form with Confirm & Pay button connected to Stripe. Currently
shared across properties; URL params pass checkin/checkout/guests.
Slug:
booking-confirmed
— Dark elegant page with golden fireworks (canvas), floating
particles, champagne icon, confirmation code, booking details from
URL params. Shared across all properties.
POST https://holidayhomes-api.vercel.app/api/create-checkout-session
Body:
{
property: String, // Display name
propertyId: String, // Page slug
location: String, // "City, State"
checkin: String, // "YYYY-MM-DD"
checkout: String, // "YYYY-MM-DD"
guests: Number,
nights: Number,
nightlyRate: Number,
subtotal: Number,
cleaningFee: Number,
serviceFee: Number,
taxes: Number,
total: Number,
successUrl: String, // → /booking-confirmed?checkin=...&total=...
cancelUrl: String // → back to property page
}
Response: { url: "https://checkout.stripe.com/..." }
Success URL must include all booking params as query strings so the confirmation page can read them.
When creating a new property page, follow this exact process:
addNewPage
with property slug (e.g.
beverly-hills-estate)
id
attributes identical (booking-state, reserved-state,
checkin-display, etc.)
data-*
attributes identical
index.js
verbatim to the new page
handleConfirmPay(): property, propertyId, location
handleReserve()
with the same pricing values
addNewPage
with slug
{property-slug}-amenities
request-to-book
— Works with any property via URL params
booking-confirmed
— Works with any property via URL params
All interactive elements use these exact classes and attributes. Do NOT change them across properties.
Every
id listed
above MUST exist on every property page with the EXACT same name.
The JavaScript depends on these IDs to wire up interactivity.
Missing IDs = broken booking flow.
This is what the AI will reference for all future property pages
10 Sections
Hero → Gallery → Sub-Nav → Overview+Booking → Calendar → Rooms → Reviews → Location → House Rules → Footer
2-State Booking Card
Booking state → Confirm & Pay state. Flush, seamless, no intermediate pages.
3 Supporting Pages
Amenities page + Request-to-Book + Booking Confirmed (with golden fireworks)
Stripe Integration
POST to holidayhomes-api → hosted checkout → success URL with booking params
40+ Element IDs
All interactive elements use exact, consistent IDs across every property page
~600 Lines of JS
Calendar rendering, guest selection, state toggling, Stripe checkout, lifecycle management
Internal reference document — not published publicly
View the template in action