PROJECT
Lead Frontend Developer

Chalet Retreat

Chalet Retreat is a production-focused software project built by Sadam Hussain using Next.js, TypeScript, Material UI, and related technologies.

A luxury vacation rental platform built with Next.js and TypeScript, featuring interactive map-based property discovery powered by Google Maps API with custom clustering for thousands of listings. The platform delivers premium, image-rich experiences through aggressive media optimization (lazy loading, responsive images, CDN-backed caching) while maintaining sub-2-second load times. A multi-step Stripe-integrated booking flow handles high-value transactions with robust validation and progressive disclosure, and the entire frontend is backed by a Material UI + SASS design system tuned for the visual standards of luxury hospitality.

Tech Stack

Next.jsTypeScriptMaterial UIRedux ToolkitSASSReact QueryReact Hook FormGoogle Maps APIStripeJestReact Testing LibraryCypress
Chalet Retreat 1
Chalet Retreat 2
Chalet Retreat 3
Chalet Retreat 4

Status

Production Ready

Type

Enterprise platform

Last Updated

April 18, 2026

Architected and led the development of a premium luxury rental platform using Next.js and TypeScript, delivering a high-performance frontend that balances visual richness with fast page loads across image-heavy property listings.

Engineered an interactive property discovery experience with Google Maps API, implementing custom marker rendering, client-side marker clustering for dense geographic regions, and synchronized map-list state so that map interactions update listing views and vice versa.

Implemented a multi-step Stripe booking flow with progressive disclosure (property selection → date/guest configuration → payment → confirmation), React Hook Form validation at each step, and secure tokenized payment handling for high-value vacation transactions.

Built a comprehensive image optimization pipeline using Next.js Image component with responsive srcsets, blur placeholder generation, intersection-observer-based lazy loading, and CDN-backed caching to handle pages displaying dozens of high-resolution property photos.

Developed a premium design system using Material UI as the component foundation with SASS modules for custom theming, ensuring visual consistency across property cards, galleries, booking modals, and marketing surfaces.

Implemented client-side state management with Redux Toolkit for global application state (search filters, map viewport, user session) and React Query for server state (property listings, availability, pricing) with cache invalidation on search parameter changes.

Established unit and integration testing workflows with Jest and React Testing Library for component behavior, alongside Cypress for end-to-end verification of the complete booking journey from property discovery through payment confirmation.

Optimized rendering performance through route-based code splitting, dynamic imports for heavy components (map, image galleries), and strategic SSR/CSR decisions per page type—SSR for property detail pages (SEO), CSR for interactive map views (interactivity).

Delivered a mobile-optimized discovery experience with touch-friendly map interactions, swipeable property galleries, and a responsive layout that adapts the map-list split view for smaller screens.

Implemented geographic search with bounding-box queries that re-fetch listings as the user pans and zooms the map, with debounced API calls and optimistic UI updates to prevent jarring content reloads during exploration.

Chalet Retreat

Overview

Chalet Retreat is a premium vacation rental platform focused on high-end hospitality and luxury properties. The platform's core technical differentiator is its ability to deliver a visually immersive, image-heavy experience—dozens of high-resolution photos per listing across thousands of properties—without sacrificing performance. This required treating media optimization not as a post-launch enhancement but as a foundational architectural concern.

The product combines sophisticated visual storytelling, interactive map-based discovery with real-time geographic filtering, and a polished multi-step booking experience to help travelers discover and reserve upscale chalet properties. The frontend manages complex state synchronization between the map view and listing views, ensuring that geographic exploration and traditional list browsing remain perfectly in sync.

Business Context: Premium Hospitality at Scale

Luxury rental platforms face a unique challenge: the digital experience must mirror the premium nature of the physical properties. A slow-loading page or a janky map interaction immediately undermines the brand promise. Discovery needs to be visual and intuitive, while the technical foundation must remain fast despite being extremely image-heavy.

The core problem: High-end property listings are inherently media-intensive—each listing features dozens of professional photographs, virtual tours, and detailed amenity descriptions. Traditional approaches to rendering these pages either sacrifice visual quality (low-res thumbnails, limited galleries) for speed, or sacrifice speed (full-resolution images, no lazy loading) for quality. The platform needed both.

Stakeholder perspective:

  • Travelers expect a browsing experience that feels luxurious—high-quality imagery, smooth interactions, and a sense of discovery. They explore geographically ("chalets near the Alps") and visually (scrolling through galleries), often switching between both modes.
  • Property owners want their listings to look exceptional. Compressed or poorly rendered photos devalue their premium properties.
  • The business depends on conversions from browsing to booking. Every friction point in the discovery-to-checkout journey represents lost revenue on high-value transactions.

Constraints that shaped the architecture:

  • Property images are the primary selling tool—image quality cannot be sacrificed for performance. The optimization strategy must be invisible to the user.
  • The map-based discovery interface must remain responsive even when displaying markers for thousands of properties in dense geographic regions.
  • Booking flows involve significant financial commitment (multi-night luxury stays), requiring the checkout experience to build trust through clear validation, progress indicators, and secure payment handling.
  • The platform must perform well on mobile devices where travelers commonly browse during trip planning, despite the heavy media load.

What I Built

1. Interactive Map-Based Discovery Engine

  • Google Maps Integration with Custom Rendering: Built a property discovery layer using the Google Maps API with custom marker rendering—each marker displays a price badge rather than a default pin, providing at-a-glance pricing information on the map. In dense geographic regions, markers automatically cluster to prevent visual overload, with cluster badges showing property counts.
  • Synchronized Map-List State: Implemented bidirectional state synchronization between the map view and the listing panel. Panning or zooming the map triggers a bounding-box query that re-fetches listings for the visible area. Clicking a listing in the panel centers the map on its location. Both interactions are debounced to prevent excessive API calls during rapid exploration.
  • Geographic Filtering Pipeline: Built a composable filter system where geographic bounds (from the map viewport), property attributes (bedrooms, amenities, price range), and availability dates combine into a single query. Filters are serialized into URL parameters, making search states shareable and bookmarkable.

2. Image Optimization Pipeline

  • Responsive Image Architecture: Leveraged Next.js Image component to serve appropriately sized images based on the viewer's device and viewport. A property hero image on desktop loads at 1200px width; on mobile, the same image loads at 640px—serving up to 60% less data without visible quality loss.
  • Progressive Loading Strategy: Implemented a multi-layer loading approach—inline blur placeholders (generated at build time from low-resolution base64 thumbnails) display immediately while the full image loads in the background. Combined with intersection-observer-based lazy loading, only images in or near the viewport load at all, preventing the browser from downloading dozens of full-resolution photos simultaneously.
  • Gallery Performance: Property detail pages feature multi-image galleries with swipeable carousels. Images beyond the first two visible slots are lazy-loaded, and preloading triggers when the user starts swiping (loading the next image before the swipe completes) to eliminate perceived latency.

3. Multi-Step Booking Flow with Stripe

  • Progressive Disclosure Checkout: Built the booking journey as a multi-step flow—property selection → dates and guest configuration → payment details → review and confirm. Each step validates independently before allowing progression, and users can navigate back without losing entered data (persisted in React Hook Form state).
  • Stripe Payment Integration: Integrated Stripe Elements for PCI-compliant payment collection, using Stripe's tokenized approach where raw card data never touches the application's servers. Payment intents are created server-side when the user enters the payment step, and confirmation happens client-side with proper error handling for declined cards, network failures, and 3D Secure authentication flows.
  • Pricing Transparency: The booking summary panel dynamically calculates total pricing (nightly rate × nights + cleaning fee + service fee + applicable taxes) and updates in real-time as the user modifies dates or guest counts. Price breakdowns are always visible to prevent surprise totals at checkout.

4. Design System for Luxury UX

  • Material UI + SASS Theming: Built a cohesive design system using Material UI components as the structural foundation with SASS modules for custom theming that reflects the luxury brand aesthetic. Custom theme tokens define the typography scale, color palette (neutral tones with gold accents), spacing rhythm, and elevation shadows that distinguish the platform from generic Material UI applications.
  • Responsive Layout System: Designed a split-view layout for desktop (map on one side, listings on the other) that collapses into a tabbed interface on mobile (toggle between map and list views). The layout transition preserves state—switching from map to list on mobile retains the geographic filter context.
  • Property Card Design: Engineered property cards with hover-triggered image carousels, price overlays, and availability badges. Cards are virtualized in long listing views to maintain scroll performance regardless of result count.

5. Testing & Quality Assurance

  • E2E Booking Journey Tests: Cypress test suites cover the complete booking flow from search → property selection → date picking → payment → confirmation. These tests use Stripe's test mode tokens to validate the full payment integration without processing real transactions.
  • Component Testing: Jest and React Testing Library verify individual component behavior—map marker rendering, filter state management, image lazy loading triggers, and form validation logic.
  • Performance Regression Testing: Lighthouse CI runs on every PR to catch performance regressions before they reach production. Budgets are set for LCP, FID, and CLS to ensure the image optimization pipeline doesn't degrade over time.

Architecture Highlights

Media Optimization as Architecture

Image performance in Chalet Retreat isn't a set of optimization tricks applied after the fact—it's built into the component architecture. Every component that renders an image uses a shared OptimizedImage wrapper that handles responsive sizing, lazy loading, blur placeholders, and error fallbacks. This wrapper abstracts the complexity of Next.js Image configuration so that developers adding new image-heavy features automatically get optimized rendering without thinking about it.

The key insight is that in an image-heavy application, media optimization must be the default, not an opt-in. If developers have to remember to add lazy loading and responsive sizing, some will forget, and performance degrades gradually.

Map-List State Synchronization

The map and listing views share a single source of truth for the current search context (geographic bounds, filters, sort order). This state lives in Redux Toolkit, and both views subscribe to it reactively. When the map viewport changes, the geographic bounds update in the store, which triggers a React Query refetch with the new bounding box, which updates the listing view. Conversely, selecting a listing updates the map's center coordinates.

This bidirectional synchronization required careful debouncing—map panning fires rapid viewport change events, and refetching listings on every frame would overwhelm the API. A 300ms debounce on viewport changes provides a responsive feel without excessive network calls.

Rendering Strategy by Page Purpose

  • SSR for Property Detail Pages: These pages need SEO indexing (property names, descriptions, locations in search results) and social sharing previews (Open Graph images). SSR ensures crawlers and social platforms see fully rendered content.
  • CSR for the Map Discovery Interface: The map view is purely interactive—SEO doesn't apply to a map viewport. Client-side rendering avoids unnecessary server-side Google Maps API calls and allows the map to initialize with the user's preferred view state.
  • ISR for Category/Destination Landing Pages: Destination pages ("Chalets in Zermatt") use ISR with periodic revalidation—content changes daily (new listings, price updates) but doesn't need real-time freshness for a landing page.

Stripe Integration Security Model

Payment security follows Stripe's recommended architecture:

  • Card data is collected using Stripe Elements (an iframe-based component), so raw card numbers never enter the application's DOM or JavaScript scope.
  • Payment intents are created server-side with the booking amount and metadata before the client collects payment details.
  • Confirmation happens client-side via Stripe.js, which handles 3D Secure challenges and communicates directly with Stripe's servers.
  • Webhook handlers on the backend confirm payment completion and trigger booking confirmation logic, ensuring the booking is recorded even if the client disconnects after payment.

Technical Deep Dive: Map-Based Discovery with Virtualized Rendering

The most architecturally interesting challenge was building a responsive, performant map discovery experience that handles thousands of property markers while synchronizing with a filterable listing panel.

The Problem: Rendering thousands of markers on a Google Map causes severe performance degradation—each marker is a DOM element, and the map becomes unresponsive with more than a few hundred visible markers. Simultaneously, the listing panel needs to show results corresponding to the visible map area, and interactions in either view must update the other in real-time.

The Architecture:

  1. Client-Side Marker Clustering: Instead of rendering individual markers for every property, the system uses a client-side clustering algorithm that groups nearby markers based on the current zoom level. At city-level zoom, users see cluster badges ("47 properties") that expand into individual markers as they zoom in. The clustering recalculates on every zoom/pan event, using a spatial index (grid-based) for efficient nearest-neighbor grouping.

  2. Bounding-Box Queries: Rather than loading all properties globally, the system queries for properties within the map's current viewport bounds. As the user pans, the visible bounding box changes, and a debounced query fetches the new set of properties. React Query caches previous bounding-box results, so revisiting a previously viewed area renders instantly from cache while revalidating in the background.

  3. Virtualized Listing Panel: The listing panel uses virtualization (rendering only the DOM elements visible in the scroll viewport) so that a search returning hundreds of results doesn't create hundreds of DOM nodes simultaneously. Combined with property card image lazy loading, the listing panel remains smooth regardless of result count.

  4. Interaction Synchronization: Map clicks, marker hovers, and listing panel interactions all dispatch to the same Redux store slice. Hovering over a listing highlights its marker on the map. Clicking a marker scrolls the listing panel to the corresponding card. This shared state model ensures both views always reflect the same selection and filter context.

  5. Performance Budget: The entire map interaction loop (pan → debounce → API call → cluster → render markers → update listings) targets a 500ms end-to-end latency budget. API response time is the bottleneck, so the bounding-box query is optimized server-side with spatial indexes, and the client pre-renders cached results while the fresh query resolves.

Why this approach: The simpler alternatives (loading all markers at once, or using server-side marker tiling) either break on large datasets or require infrastructure complexity that wasn't justified. Client-side clustering with bounding-box queries provides the right balance—the map feels responsive at any zoom level, the API serves manageable result sets, and the UX is seamless.

Key Challenges & Solutions

  • Challenge: Property pages with 20-30 high-resolution images took several seconds to load, degrading the premium browsing experience. Approach: Built a multi-layer image optimization pipeline—responsive srcsets serve appropriately sized images per device, blur placeholders provide instant visual feedback, intersection-observer lazy loading prevents off-screen images from loading, and a CDN caches optimized variants. Why: No single optimization technique is sufficient for heavily image-laden pages. The layered approach ensures that each optimization handles a different aspect of the problem (bandwidth, perceived load time, browser resource usage, cache efficiency).

  • Challenge: Thousands of map markers caused the Google Maps rendering to become sluggish, with frame drops during pan and zoom interactions. Approach: Implemented client-side marker clustering that groups nearby markers at higher zoom levels, reducing the visible DOM element count from thousands to dozens. The clustering algorithm recalculates efficiently on viewport changes using a grid-based spatial index. Why: The naive approach (render all markers) scales poorly because each marker is a separate DOM element with event listeners. Clustering reduces rendering cost while preserving the ability to discover individual properties by zooming in.

  • Challenge: The multi-step booking flow needed to maintain state across steps (dates, guests, payment) while allowing back-navigation without data loss. Approach: Used React Hook Form with a shared form context across all booking steps. Each step validates independently, but the form state persists across step transitions. Draft booking data is also saved to sessionStorage for recovery if the user accidentally navigates away. Why: Rebuilding form state on back-navigation is a common source of checkout frustration. Persistent form context eliminates this while sessionStorage provides a safety net for accidental page closures during high-value transactions.

  • Challenge: Map panning fires rapid viewport change events, and refetching property listings on every event would overwhelm the API and cause UI flickering. Approach: Debounced viewport change events by 300ms before triggering API refetches. During the debounce window, the previous listing results remain visible. React Query's stale-while-revalidate behavior shows cached results immediately when revisiting previously viewed areas. Why: The balance between responsiveness and efficiency requires debouncing—too short and the API is overwhelmed, too long and the UI feels laggy. 300ms provides responsive-feeling updates without excessive network calls.

Outcomes

  • Performance: Delivered consistently fast page loads across image-heavy property listings through the multi-layer media optimization pipeline, meeting the performance standards expected of a luxury digital product.
  • Discovery Experience: The synchronized map-list interface with client-side clustering enabled smooth geographic exploration of the full property catalog without performance degradation at any zoom level.
  • Booking Conversion: The progressive checkout flow with inline validation, pricing transparency, and persistent form state reduced friction in the high-value booking journey.
  • Mobile Experience: The responsive layout system successfully adapted the rich desktop experience (split map-list view) to mobile devices (tabbed interface) without losing functionality or state context.
  • SEO Visibility: SSR for property detail pages and ISR for destination landing pages provided search engine indexability for the platform's most important content.

Engineering Takeaways

Chalet Retreat reinforced that in premium markets, performance is a design requirement, not a technical metric. A luxury property loses its appeal if the page is slow to load or the map feels sluggish. This project proved that through careful rendering decisions and systematic media optimization, a visually immersive experience can coexist with top-tier technical performance.

Patterns I'd reuse:

  • The OptimizedImage wrapper pattern that makes media optimization the default for every developer, not an opt-in. In any image-heavy application, this prevents gradual performance degradation as the team adds new features.
  • Bidirectional state synchronization between map and list views through a shared store. This pattern applies to any dual-view interface where two representations of the same data need to stay in sync.
  • Progressive checkout with per-step validation and persistent form state. This pattern works for any high-value, multi-step form flow where abandonment is costly.

What I'd reconsider:

  • Google Maps API has per-load pricing that scales with traffic. For a high-traffic consumer platform, evaluating open-source alternatives (Mapbox GL JS, Leaflet with vector tiles) could significantly reduce mapping costs while providing more rendering control.
  • The client-side clustering approach works well for the current scale but would benefit from server-side pre-clustering for very large datasets where sending all marker coordinates to the client becomes bandwidth-inefficient.

Trade-offs acknowledged:

  • Chose Google Maps over open-source alternatives for familiar UX and extensive documentation, accepting per-load API costs in exchange for reduced development time and user familiarity.
  • Chose Material UI as the design system foundation over building from scratch, accepting the need for extensive theme customization to achieve a luxury aesthetic that doesn't look like a generic Material Design application.
  • Chose client-side clustering over server-side tile-based marker rendering, accepting the initial data transfer of all marker coordinates in exchange for simpler infrastructure and smoother client-side interactions.