This is the website for online computer store with a set of products to sell, currently with listing of 4 products available with 3 deals but there is an ability to add more products and pricing rules as needed.
This is a Next.js project bootstrapped with create-next-app
.
The folder stucture has been revamped to organise components, pages and styles in separate folders for maintainability.
Follow this README for instructions on Basic Requirements, Set Up along with details about the project so that you can understand the technical details and run the application smoothly.
- Basic Requirement
- Setting Up
- Starting the Server
- Running Tests
- Project Overview
- Folder Structure
- UI/UX
- Deployment
This project runs on Next 14 and requires minimum Node version of 18.17
.
You can check your version by running the following command
$ node -v
If your version of node is lower than the requirement, you can get the version by downloading directly from the website or by using nvm as detailed in this tutorial.
Once you have the basic requirement set up, make sure you are in the same directory as package.json
You can navigate to the required file by using cd
to change into a certain directory
$ cd /directory
or to change out of the current directory
$ cd ..
Once you re in the same directory as package.json
, run the following command to install the dependencies
$ npm i
After the installation is done, you should be able to run the development service by using
$ npm run dev
Open http://localhost:3000 with your browser to see the result.
There are a total of 31 tests under 9 test suites in the project. You can run these tests by using the test script
$ npm test
The project uses Jest for the tests.
The project is structured with frontend and backend in different folders within the src
folder.
The public
folder contains all the public assets like images, svgs and icons.
The tests for the project are placed in tests
folder mirroring the structure for src
folder with each test file ending with .test.js
.
models
folder has been used to place products.js
and pricingRules.js
where each model is storing the following data -
products.js
- Details about the products including SKU code and image link.pricingRules.js
- Details about the available deals. There are 3 types of deals that have been definied in the system.
a. X for Y deal - You get X items of the SKU for the price of Y items. Essentially getting X - Y items of the SKU for free.
b. Bulk Discount - You get a discounted price if you buy more than a set threshold of a particular SKU.
c. Bundle - If you buy a bundled item with the current SKU, you get the bundled item for free. For simplicity, in this project I have displayed this as a discount on the current SKU by bundling.
A database wasn't used because the application itself is rather straightforward, but the project can be extended further to make use of databases if necessary.
utils
folder contains the business logic with calculateTotalPriceAndBreakDown.js
defining the function to fetch the total price and the breakdown for the cart of items. It's corresponding test is available in tests/utils
folder.
pages
folder contains the pages for the application, with pages/api
containing backend APIs while the other pages are available on top level. The pages
are as follows -
-
/api/checkout.js
- Contains the backend api for/api/checkout
which is aPOST
API to fetch total price and the breakdown for the cart of items. Following is the request and response structure
Request:{ "items": [ { "SKU": "ipd", "name": "Super iPad", "price": 549.99, "image": "/images/ipd.jpeg", "quantity": 6 } ] }
Response:
{ "total": 2999.94, "breakdown": [ { "SKU": "ipd", "name": "Super iPad", "quantity": 6, "originalPrice": 549.99, "finalPrice": 2999.94, "discountApplied": 300, "discountDescription": "Bulk discount applied for purchasing more than 4" } ] }
-
index.js
- Contains the homepage of the application available at the route"/"
. -
checkout.js
- Contains the checkout page available at the route"/checkout"
that user lands on once they click on checkout from the cart sidebar. Users can only land on this page if their cart has items. -
success.js
- Contains the success page available at the route"/success"
that user lands on once they confirm their purchase on checkout page. Users can only land on this page if their cart has items. -
_app.js
- It is used to initialise the pages and apply global settings, it does contain the code wrap the entire application withCartProvider
to maintain context of cart across the pages. -
_document.js
- It is for customizing the overall HTML document structure. Currently, it just imports the fontInter
but it can be used for further customisation to HTML document structure for server-side rendering optimizations.
The corresponding tests are available in tests/pages
folder.
context
contains context files, currently it has CartContext
which maintains the state of cart across the application. It makes use of localStorage
to preserve the state even on reloads.
hooks
contains hooks that can be used on frontend across the application. Currently, it has useFetchPriceDetails
hook that fetches the price details of a cart from /api/checkout
API.
components
contains all the reusable components of the application. Following are the components available -
CartIcon.js
- Contains theCartIcon
component which shows whether the cart of the user is empty or not and opens cart sidebar on clicking.CartProductCard.js
- Contains theCartProductCard
component which displays a specific item in the cart along with the price and quantity with an option to be removed from the cart.CartSidebar.js
- Contains theCartSidebar
component which displays the cart sidebar that opens when user clicks on the cart icon. It asks the user to add items to cart if the cart is empty.ProductCard.js
- Contains theProductCard
component which displays the product with image and it's details. It also contains a CTA to "Add to Cart".ProductList.js
- Contains theProductList
component which displays the list of products in a responsive grid.
The corresponding tests are available in tests/components
folder.
The styles for the application are placed in styles
folder. Currently, it contains globals.css
defining the globally applied styles.
The folder stucture for the project is as follows -
online-store/
├── public/ -> contains public files
│ ├── images/
│ │ ├── atv.jpg
│ │ ├── ipd.jpg
│ │ ├── mbp.jpg
│ │ ├── vga.jpg
│ ├── favicon.ico
│ ├── next.svg
│ └── vercel.svg
├── src/ -> contains backend and frontend
│ ├── components/
│ │ ├── CartIcon.js
│ │ ├── CartProductCard.js
│ │ ├── CartSidebar.js
│ │ ├── ProductCard.js
│ │ └── ProductList.js
│ ├── context/
│ │ └── CartContext.js
│ ├── hooks/
│ │ └── useFetchPriceDetails.js
│ ├── models/
│ │ ├── pricingRules.js
│ │ └── products.js
│ ├── pages/
│ │ ├── api/
│ │ │ └── checkout.js
│ │ ├── _app.js
│ │ ├── _document.js
│ │ ├── checkout.js
│ │ ├── index.js
│ │ └── success.js
│ ├── styles/
│ │ └── globals.css
│ └── utils/
│ └── calculateTotalPriceAndBreakDown.js
├── tests/ -> contains tests
│ ├── components/
│ │ ├── CartIcon.test.js
│ │ ├── CartProductCard.test.js
│ │ ├── CartSidebar.test.js
│ │ ├── ProductCard.test.js
│ │ └── ProductList.test.js
│ ├── pages/
│ │ ├── api/
│ │ │ └── checkout.test.js
│ │ ├── checkout.test.js
│ │ └── index.test.js
│ └── utils/
│ └── calculateTotalPriceAndBreakDown.test.js
├── .eslintrc.json
├── .gitignore
├── babel.config.js
├── jest.config.js
├── jsconfig.json
├── LICENSE
├── next.config.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── README.md
└── tailwind.config.js
The UI is targetted to be simplistic in nature and easy to navigate, the application has been built to handle dark
and light
modes from the system settings. Feel free to toggle and check for the same.
To make the user experience more intutitive and effortless, there have been animations added for hover and state changes to the cart. Do check by navigating around.
To update the pricing or the pricing rules, feel free to update models and restart the server locally.
The project has been deployed using vercel and is available at - https://online-store-cs.vercel.app