Basecamp is a full-stack clone of hipcamp.com, a campground booking app similar to Airbnb.
- Ruby on Rails
- React.js
- Redux.js
- Node.js
- PostgreSQL
- Webpack
- Amazon AWS S3
- Google Maps API
Basecamp is built with a Ruby on Rails backend framework. The frontend utilizes React and Redux to create a dynamic single page application. All data is stored through PostgreSQL database, with photos for campsites being uploaded and stored through Amazon AWS S3. These technologies allow users to smoothly navigate throughout the site and allow for dynamic creation, updating, and deleting of bookings and reviews.
- Users can sign up for an account on Basecamp. They can also log in to view their profile page.
- Users can log in or sign up via the buttons in the top right corner. Once logged in they those buttons are replaced with Logout and Profile buttons.
- If a visitor does not want to create an account, they can log in as a Demo User. This provides them with full access to Basecamp's campsite, review, and booking features.
- Users can navigate through a collection of listed campsites on the home page.
- When a campsite is selected, the campsite's show page is rendered displaying relevant information.
@campsites.each do |campsite|
json.set! campsite.id do
json.extract! campsite, :id, :name, :location, :city, :state, :price, :site_type, :capacity, :lat, :lng
if campsite.photos.attached?
json.photo_url campsite.photos.map { |campsite| campsite.url }
end
if (campsite.reviews.length != 0)
reviews = campsite.reviews
total_rating = (reviews.count { |el| el.recomended }) * 100.0 / reviews.length
else
total_rating = 0
end
json.rating total_rating
json.num_rating campsite.reviews.length
end
end
- If a user is logged in, when they navigate to a campsite's show page they will see a hovering booking form on the right side of the screen.
- The date picker was created using the React-Date-Range library, giving users a simple and easy-to-use design for picking a start and end date for their reservation.
- Once a booking is made, they will be navigated to their user profile page and see a list of all bookings they have created.
- Here users can update or remove bookings.
- When a user is not logged in the booking form will be hidden from view.
const handleSubmit = (e) => {
e.preventDefault();
dispatch(updateBooking(booking)).then(()=> history.push(`/user/${sessionUser.id}`))
}
const handleChange = (field) => {
return (e)=>{
let newBooking = Object.assign({}, booking, {[field]: e.currentTarget.value})
setBooking(newBooking)
}
}
const handleDateChange = (ranges) => {
setStartDate(ranges.selection.startDate);
setEndDate(ranges.selection.endDate);
let dayDifference =
(ranges.selection.endDate.getTime() - ranges.selection.startDate.getTime()) / 86400000
let newBooking = Object.assign({}, booking,{ checkinDate: ranges.selection.startDate,
checkoutDate: ranges.selection.endDate,
price: campsite.price * dayDifference})
setBooking(newBooking)
}
- At the bottom of the campsite show page, users will see all reviews created for that campsite.
- If they have left a review, they will be able to edit or remove said review.
- On the splash page users can search for campsites by location, name, or state.
- This will render a search index where all campsite fulfilling the search criteria will be displayed.
const markerLatLngArr = new window.google.maps.LatLngBounds();
if (markerList.length > 0) {
markerList.forEach((marker) => {
marker.setMap(null)
})
}
setTimeout(()=>{
campsites.forEach((campsite) => {
setMarkerList(markerList.concat(new window.google.maps.Marker({
position: { lat: campsite.lat, lng: campsite.lng },
map: map,
animation: window.google.maps.Animation.DROP,
icon: {
url: blackPin,
scaledSize: new window.google.maps.Size(30, 30),
origin: new window.google.maps.Point(0, 0)
}
})))
markerLatLngArr.extend(new window.google.maps.LatLng(campsite.lat, campsite.lng))
map.fitBounds(markerLatLngArr)
})
},1000)