This is a solution of windbnb challenge from Dev Challenges.
Users should be able to:
- See a list of properties
- See the property card with a name, rating, apartment type, and super host
- Open the filter drawer
- Filter properties by location and number of guests
- See the number of filtered items
- See pages following given designs
- Live Demo: Demo
- Semantic HTML5 markup
- CSS custom properties
- Flexbox
- CSS Grid
- Mobile-first workflow
- JavaScript ES6+
- React - JS library
- Styled Components - For styles
- Vite - Bundle tool
- Standard - Linter
- React Icons - Icons library
This was an interesting challenge to practice with React.
Implemented customs hooks
to improve readability of components
// With this hook a can create specific filters and update them individually
export const useFilter = (state = initialState) => {
const [filters, setFilters] = useState(state)
const addLocation = (location) => setFilters(prev => ({
...prev,
location
}))
const addGuests = (guests) => setFilters(prev => ({
...prev,
guests
}))
return {
filters,
addLocation,
addGuests
}
}
// Usage
const {filters: filterName, addLocation: addNameLocation, addGuest: addNameGuests} = useFilter(initialState)
Followed component composition pattern to spread the data across the app without the use of useContext
hook
// FilterList/index.jsx
export const FilterList = ({ children, filter, activeTab }) => {
const isActive = filter === activeTab
return (
<StyledList isActive={isActive}>
{children}
</StyledList>
)
}
// Modal/index.jsx
<FilterList filter='location' activeTab={activeTab}>
{
locations.map(location => {
const [city, country] = location.split(', ')
return (
<LocationItem
key={city}
location={{ city, country }}
setSelectedLocation={setSelectedLocation}
/>
)
})
}
</FilterList>
Added a service to handle the data output depending on the filters applied
export const getFilteredData = (filters, array) => {
const { location, guests } = filters
let filteredData = array
if (location && guests) {
//Filter by location and guests
} else if (location) {
//Filter only by location
} else if (guests) {
//Filter only by guests
}
return filteredData
}
Used this cool trick to remove the duplicated locations from the data file with only two lines
const rawLocations = data.map(({ city, country }) => (`${city}, ${country}`))
const locations = [...new Set(rawLocations)]
-
Styled Components docs - The official documentation of styled components, this resource was very useful to understand this package.
-
Conditional styled components article - This is a great article to understand the basis on condition handling with styled component. Helped me a lot with this project.
To test this project by yourself first clone the repository, then you can use this commands:
Install project
npm install
Run local server
npm run dev
Build project
npm run build
Preview Build
npm run preview