Backpackr is a single-page application designed to help travelers plan their voyages with more ease and organization. It was birthed when four curious software engineers prodded over the age-old problem of hassling over messy Google docs to plan itineraries for group trips. The original inspiration was to create an application that combines an interactive messenger alongside a running itinerary list that could store the key information from the group trip chat.
Backpackr utilizes MongoDB and Express in the backend and React, Redux, and NodeJS in the frontend to achieve this, allowing users to utilize CRUD operations in both the comment and itinerary functionalities.
- MongoDB
- Express
- React
- NodeJS
Users can sign up for a new account, login to an existing account, or access a demo user to access the site features. The session token for the current user persists until the user explicitly logs out, allowing users to close out of tabs with ease.
If the user enters invalid information, either in the signup form or the login form, specific error messages appear to highlight which input fields would need corrections. Upon a successful login, the user lands on the user dashboard where a trip can be created, edited or deleted.
Each user is able to create new trips with a destination, a start date, and an end date. Upon entering the trip-specific dashboard, the user is greeted with three key components: 1) the user list of who is on the trip, 2) all the comments from everybody who has access the trip, and 3) the running list of itinerary items for that specific trip. A challenge in the backend was nesting all of these data objects within specific trips themselves.
// Get a specific trip.
router.get("/:id",
passport.authenticate('jwt', { session: false }),
(req, res) => {
Trip.findById(req.params.id)
.populate({
path: "users",
model: "User",
select: ["username", "_id"]
})
.populate({
path: "comments",
model: "Comment",
select: ["author", "comment", "date"]
})
.populate({
path: "itineraryItems",
model: "ItineraryItem"
})
.then(trip => {
Users can only access trips that they own or are apart of.
// ...Check if the current user is part of the trip.
if (trip.users.some(user => (req.user.id === user.id))) {
return res.json({ [trip.id]: trip })
} else {
// This user isn't authorized to view this trip.
return res.status(401).json({ unauthorized: "You are not authorized" });
}
})
.catch(err => {
return res.status(404).json({ notripfound: "This trip doesn't exist" })
});
});
Friends can be also introduced to a trip simply by adding their email associated with their account. Once added to a trip, a user has access to the trip and all associated information on their dashboards. Users can only join if they aren't already part of the trip.
Each trip has a private page where users who've been invited can chat with each other. Comments populate in the feed without having to refresh the page and of course, you can use your favorite emojis. Comments can only be deleted by their respective owner.
All users on a trip can also add itinerary items with specific address, description, category, and name details. Itinerary items can also be deleted without refreshing the page.
In the original mockup plans, we had wanted to include the Google Maps API to include on the trip dashboard to allow users to access Google Maps while adding itinerary items and discussing with friends over travel details. This has been saved for a later date.
The original mockup plans also included a tab functionality for the itinerary items, allowing better organization for essential travel details such as lodging, food, flights, etc.
As our group is composed of LGBTQ+ software engineers, we were hoping to integrate a resource for location-based links to resources for LGBTQ+ users to feel included and considered for in their travels.