An extension to an e-commerce site that allows users to find and book brand ambassadors’ online classes around the world. Inspired by Airbnb Online Experience and Class Pass.
By default a user will see all the classes. User can filter by clicking Day, Languages Offered and Interests. User can combine multiple filters.
-
We have a slice of state to keep track of our filters.
-
We have two
actions
: one to tell ourstore
to update request query parameters and one to go fetch Classes from our API. -
On the Filter Form we have event listeners for when filters are changed. We dispatch
updateFilter
action creator and pass user's newly constructed filters to store.
// components/search/filter_form.js
useEffect(() => {
updateFilter(filter);
updateFilterParams();
}, [filter]);
- Then we need to build our application state to reflect the filters. Using thunk middleware,
updateFilterParams
format the query paramter and then callfetchClasses
passing in the formatted filters fromgetState
. We then call the return function with dispatch and update classes instore
.
// actions/filter_actions.js
export const updateFilterParams = () => (dispatch, getState) => {
dispatch(changeFilterParams());
return fetchClasses(getState().ui.filters.queryParams)(dispatch);
};
- Potential enhancements include: filtering classes in the front end using package like isotope to save number of API calls, and storing query parameter in
localStorage
or URL path so that when user returns to the Class Index page, it is showing previously filtered results.
Back end and Front end have validations to ensure only admin users can modify their own classes and see "Edit" link on the Class Show page.
-
When a user successfully logs in, the back end sends a Json Web Token back in Bearer schema and we include it in our axios header.
-
We decode the token and store user
admin
status andid
in application state. We pass this information toRoutes
as props, then render Component if user is Admin, and otherwise redirect user to their profile. Lastly we use this new route -AdminRoutes
fornew-class
and/classes/:id/edit
. -
We populate the
admin
field in Class model when calling its APIs, which is also stored in application state. We then conditionally render "Edit Link" by checking if user is an admin and if class's admin equals current user ID. We redirect user usingreact-router
if condition fails.
// components/class/class_show.js
isClassOwner() {
return this.props._class.admin._id === this.props.currentUserId;
}
- In the back end, we first check if user is Admin. Then we check if the class's
admin._id
is user's ID before modifying the document.
Example of Deleting a Class
// routes/api/classes.js
router.delete('/:id',
passport.authenticate('jwt', { session: false }),
(req, res) => {
if (!req.user.isAdmin) {
return res.status(401).json({ notadmin: 'Only admin can delete a class' })
}
Class.findById(req.params.id)
.then(_class => {
if (_class.admin._id.toString() !== req.user.id) {
return res.status(401).json({ ownership: 'Only class owner can delete this class'})
}
_class.remove();
res.json(_class);
})
.catch(err => res.status(404).json({ noclassfound: 'No class found with that ID' }));
}
)
-
Install dependencies
Use the npm package manager to install dependencies in root directory.
npm run dev
This will run
frontend-install
and install dependencies from both front end and back end folders. It will also runconcurrently
and start both servers. You can view the frontend onlocalhost:3000
. -
Start developing.
Run the following command when debugging back end:
npm run server:debug
Front-end:
- React - Front end framework
- Redux - State management tool used with React
- axios - Used for API calls
- Javascript - Language for site functionality
- Material-UI - Used for advanced styling and design system
- Styled-Component - Used for custom styling React components
- CSS3 - Used in conjunction with Material-UI for styling
- HTML5 - Used for general structure of webpage
Back-end:
- Express - Back end framework
- node - Runtime environment for javascript
- mongoDB - NoSQL database
- mongoose - Object modeling for node.js and mongodb
- Show avatars of students in Class Time Index Item
- Reviews on Classes and Ambassadors
- Use
react-dates
from Airbnb in Filter Form - Expired Class Times should be deleted from the database and Users' bookings
- Users should receive notification if Class Times / Classes are modified or removed
- Pagination on Class Times and Classes
- Pictures for Classes
- Payment for Premium Classes
- Google Map integration for Offline Classes