This is a robust shopping cart application developed using Svelte, TypeScript, and Vite. The application provides a seamless shopping experience, allowing users to add items to a shopping cart, apply discounts, and proceed to checkout.
This was my first application built with Svelte, TypeScript, and Vite. It uses Svelte stores for state management and Vite for building and serving the application. The application also uses Vitest for testing.
The codebase is organized into several key directories:
src
: Contains the main application code, including Svelte components and the shopping cart store.tests
: Contains unit and functional tests for the application.src/config
: Contains JSON files for products and discounts.Products and discounts can be easily modified by editing the corresponding JSON files in the src/config
directory:
products.json
: Defines the available products. Each product has a code
, name
, and price
.discounts.json
: Defines the discount rules. Each rule has a type
and parameters specific to the type.For example, to add a new product, you would add a new object to the products.json
file:
{
"code": "NEWPROD",
"name": "New Product",
"price": 500
}
To add a new discount rule, you would add a new property to the discounts.json
file:
{
"NEWPROD": {
"type": "bulkDiscount",
"requiredQuantity": 2,
"discountPercentage": 50
}
}
This rule would apply a 50% discount to the "New Product" when two or more are added to the cart.
To run the application, follow these steps:
git clone https://github.com/agustif/shopping-cart-discounts.git
cd shopping-cart-discounts
npm install
npm run dev
The application will be available at http://localhost:5xxx
.
To run the tests, use the following command: npm run test
The application supports the following discount rules:
These rules are applied automatically when the relevant items are added to the cart. The application calculates the total cost after discounts during checkout.
The application currently supports two types of discounts: "buy X get Y free" and "bulk discount". These are defined in the DiscountType
enum in src/stores/cart.ts
:
enum DiscountType {
BUY_X_GET_Y_FREE = 'buyXGetYFree',
BULK_DISCOUNT = 'bulkDiscount',
};
The logic for applying these discounts is implemented in the calculateTotal
function in the same file:
if (discountConfig) {
switch (discountConfig.type) {
case DiscountType.BUY_X_GET_Y_FREE:
if (item.quantity >= discountConfig.requiredQuantity) {
const freeItems = Math.floor(item.quantity / discountConfig.requiredQuantity) * discountConfig.freeQuantity;
discount = freeItems * item.price;
}
break;
case DiscountType.BULK_DISCOUNT:
if (item.quantity >= discountConfig.requiredQuantity) {
discount = total * (discountConfig.discountPercentage / 100);
}
break;
default:
break;
}
}
If you want to add more types of discounts, you can do so by extending the DiscountType
enum and adding the corresponding logic in the calculateTotal
function. For example, to add a "percentage off" discount, you could do the following:
DiscountType
enum:enum DiscountType {
BUY_X_GET_Y_FREE = 'buyXGetYFree',
BULK_DISCOUNT = 'bulkDiscount',
PERCENTAGE_OFF = 'percentageOff',
};
calculateTotal
function:case DiscountType.PERCENTAGE_OFF:
discount = total * (discountConfig.discountPercentage / 100);
break;
discounts.json
file:{
"NEWPROD": {
"type": "percentageOff",
"discountPercentage": 20
}
}
This rule would apply a 20% discount to the "New Product".
You can also run this application using Docker. First, build the Docker image:
npm run docker:build
This will create a Docker image named shopping-cart-discounts-app
.
Then, you can run the application:
npm run docker:run
This will start the application and make it available at http://localhost:8080
.