In this repo you'll find the code for my solution to Cabify's frontend challenge. The following sections will give you an overall view on how it's done and how to run it.
Here you have some comments on the structure of the project divided in 3 subsections: Overall, Logic and Components.
- This project has been generated using create-react-app
- The project follows a features folder structure
- The code is unit-tested using react-testing-library. You can see the code coverage report by running
yarn run test:coverage
as explained in the Available Scripts section- A
tests
badge has been enabled in this repo to check UT status.
- A
- Redux has been chosen as the main state manager for the app data along with redux-toolkit, which is the official tool for using redux.
- The reducers follow a Ducks pattern, which is also the recommended way by the redux team and most of the community.
- You can find the app reducers in
src/features/shoppingCart/state
- As required for the challenge, all the logic related to products (totals, discounts, etc.) is performed by the Checkout class
- You can find the Checkout class in
src/features/shoppingCart/logic
- You can find the Checkout class in
- To make Checkout logic a bit more scalable, a descriptor pattern has been applied on products and discounts data.
- This means, Checkout class is data-agnostic. It just takes
products
anddiscounts
descriptors in the constructor and uses the props inside them to run all the logic. - In addition,
discounts
descriptors are enhanced descriptors. Ideally, descriptors would come from a server, which means all the data inside them must be serializable. This means we can't get functions into them. So I have enhanceddiscounts
descriptors by adding some functions (getDescription
andgetDiscountValue
) already in the client side. - You can find the descriptors in
src/features/shoppingCart/descriptors
- This means, Checkout class is data-agnostic. It just takes
- For structuring components, I've chosen Atomic design, which is a methodology for creating design systems.
- You can find all the components in
src/features/shoppingCart/components
- You can find all the components in
- For styles, I've used Styled components, which fits very well with almost every component-based application.
- Along with styled components, I've used a
theme
object to store all the main props related with styles (colors, font sizes, etc.)- You can find it at
src/styles
- You can find it at
- For exctracting some logic/data parsing out of components, I've written a Custom hook.
- You can find it at
src/features/shoppingCart/hooks
- You can find it at
- As a documentation tool, I've used Storybook, which also helps to build standalone components with no need of using a real app. You can run Storybook by using
yarn storybook
command.
- Using react-theme-provider or similar to inject the
theme
object instead of importing it direclty - Using react-app-rewired to avoid using annoying relative urls on imports ("../../../../")
- Using redux-saga to implement asynchronous behaviour when needed.
- Responsive design
- Static types (Flow, Typescript)
In the project directory, you can run:
Installs all the project dependencies. You must run this one before anything else.
Runs the app in the development mode.
Open http://localhost:3000 to view it in the browser.
The page will reload if you make edits.
You will also see any lint errors in the console.
Launches the test runner in the interactive watch mode.
See the section about running tests for more information.
Launches the test runner in single run mode and returns a code coverage report.
Runs Storybook tool. Open http://localhost:6006 to view it in the browser.
Builds the app for production to the build
folder.
It correctly bundles React in production mode and optimizes the build for the best performance.
The build is minified and the filenames include the hashes.
Your app is ready to be deployed!
See the section about deployment for more information.