/projects
AvantStay Challenge
Vacation rental platform UI with property search, filtering, and sorting flows over real-time GraphQL data.
- Stack
- React
- TypeScript
- GraphQL
Palette
Navy
#022b54
Deep Navy
#011b35
Teal
#2fa6b4
Light Teal
#53c3d0
Mist
#e8eff5
Gold
#b29d56
Case study
A 48-hour coding challenge from 2021. Vacation rental search and filter, on top of AvantStay's production GraphQL API. The brief was a design mockup, no UI library allowed. I joined the team after.
The constraint
No UI library. Just React, TypeScript, and CSS. The brief was specific: a usable property search interface backed by a real GraphQL endpoint, with filtering and sorting. Layout, copy, error states, and polish were left open.
What shipped
Property grid with cover image, price, and capacity. Filters for location, sleeps, bedrooms, and date range. Sorting by price and capacity. URL-as-state, so every filter writes to the query string and any view is shareable.
Filters compose into the GraphQL query through Apollo's useQuery hook, which re-fetches when its variables change. AvantStay's API only sees the filters the user has actually selected, which keeps server-side query plans lean and makes the network tab readable when something doesn't return what was expected.
Empty result sets render a deliberate empty state with the active filter summary, not a blank grid. The summary is itself a teaching surface: it tells the user which constraints they applied, in what order, and which one is most likely to be the limiting factor.
The decisions
URL-as-state was the most important call. Filters survive refresh, deep links work for free, and the back button does what users expect. The cost is parsing and serialization wiring for every filter type, which is one-time work.
Sort field and direction were left as separate parameters rather than collapsed into one. The shipped URL uses order=PRICE_DESC explicitly; the alternative would be a single sort key like sort=price-desc that combines field and direction into one string. Independent parameters scale: adding a new sort field doesn't double the option list. Combined parameters front-load discoverability for new users at the cost of clean composition.
/challenge-avantstay?region=0bb20925-51bc-11ea-adb3-c5da55d0cc57&startDate=2026-06-02&endDate=2026-07-22&guests=6&order=PRICE_DESCOutcome
I got the offer and joined the team. The challenge surfaced patterns I now reach for in production: query-string-as-state for any filtered list and deliberate empty states with the active filter summary.