A Full-Scale E-Commerce Storefront
Welcome to The Desire Store. This project is a deep dive into building a functional, responsive shopping experience using an "Engineering First" approach to frontend development.
π Live Demo
The development of this storefront followed a structured 3-step engineering logic to ensure scalability and clean code:
- Data Management: Product information is centralized in JavaScript objects to simulate a database environment, making the catalog easy to maintain.
- Dynamic Generation: Developed a rendering engine using JS loops to automatically generate HTML components, ensuring the UI stays in sync with the data.
- Interactive Logic: Implemented event listeners to handle "Add to Cart" functionality and persistent data storage via
localStorage.
- Dynamic Product Grid: Products are injected into the DOM via JavaScript.
- Persistent Shopping Cart: Items remain in the cart even after a page refresh.
- Responsive Design: Fully optimized for mobile, tablet, and desktop viewing.
- Engineering-First Code: Modular functions and clean separation of concerns.
- HTML5 - Semantic structure.
- CSS3 - Custom styling and Flexbox/Grid layouts.
- JavaScript (ES6+) - DOM manipulation and state management.
Below are the details of how the homepage was built. Click each section to see the "Under the Hood" logic.
π HTML: The Skeleton
I structured the page into three main segments to ensure a semantic and accessible layout:
- The Navbar: Built using a
<nav>container. It houses the Brand, the "Apni kaamna khojie" search bar, and the Cart icon.
<!-- skeleton of nav bar -->
<div>
<img src="brand-icon.jpg" alt="">
<input type="search" placeholder="search">
<button>
</button>
</div>- The Hero Section: A simple
<h2>designed to grab user attention immediately upon landing.
<!-- hero text -->
<p>
Jaha Paisa khatam hota hai...
Par Kaamna nahi.
</p>- The Product Grid: A parent
divthat acts as a container for all dynamically generated products.
<!-- products container -->
<div>
<!-- products -->
<div>
<!-- product's image -->
<img src="https://images.unsplash.com/photo-1620799140188-3b2a02fd9a77?w=500&auto=format&fit=crop&q=60&ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxzZWFyY2h8Mnx8aG9vZGllfGVufDB8fDB8fHww" alt="product image">
<!-- product name -->
<p>
hoodie
</p>
<!-- ratings -->
<div>
<img src="" alt="">
<span>253</span>
</div>
<!-- product price -->
<p></p>
<!-- product quantity input -->
<select name="" id="">
<option selected value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
<!-- add to cart button -->
<button>
add to cart
</button>
</div>
</div>π¨ CSS: The Styling (Bootstrap + Custom)
I leveraged Bootstrap 5 for a responsive layout grid but layered on custom CSS to achieve a unique, professional aesthetic.
- Priority Rule: I utilized External CSS for maintainability, while remaining mindful of the CSS specificity hierarchy (where Inline Styles hold the highest priority).
- The Image Box Trick: To solve the common issue of inconsistent card heights, I wrapped product images in an
.image-boxwithdisplay: flexand fixed heights to ensure a perfectly aligned grid. - 3D Effects: Implemented
box-shadowon the navbar and product cards to add depth and a modern "elevated" feel. - Search Bar Logic: Applied
flex-grow: 1to the search input, allowing it to intelligently fill available space within the navbar.
βοΈ JS: The Interaction Engine
Instead of hard-coding every item, I centralized all product data in products.js and used JavaScript to build the interface programmatically.
- Iterative Loop: Systematically traverse the products array.
- Template Literals: Used ES6 template strings to create a reusable HTML blueprint for each product card.
- DOM Injection: Utilized
.innerHTMLto render the generated code into the main container efficiently.
import { products } from '../data/products.js';
let productsHTML = '';
products.forEach(product => {
productsHTML +=
`
<div class="col">
<div class="card">
<div class="image-box">
<img src="${product.image}" class="card-img-top" alt="...">
</div>
<div class="card-body">
<p class="card-title">${product.name}</p>
<p class="card-text">
R${(product.pricePaisa / 100).toFixed(2)}
</p>
<div class="product-ratings">
<!-- <img src="" alt=""> -->
<div>
β
β
β
β
β
</div>
<div class="reviews">
(${product.rating.count})
</div>
</div>
<select name="" id="">
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
<option value="7">7</option>
<option value="8">8</option>
<option value="9">9</option>
<option value="10">10</option>
</select>
<button class="btn add-to-cart-button">
Add to Hart
</button>
</div>
</div>
</div>
`
});
console.log(productsHTML);
document.querySelector('.js-products-row')
.innerHTML = productsHTML;Note: Here is a look at the "Add to Hart" (Add to Cart) flow. It features an instant UI feedback loopβupdating the cart count and triggering a confirmation toast without refreshing the page.
- Zero-Refresh Updates: Cart state updates instantly via JavaScript.
- Visual Cues: The cart icon badge increments dynamically.
- Toast Notifications: A "Success" message appears to confirm the item was added.
Currently, this is handled via Vanilla JavaScript using:
- Event Delegation: Listening for clicks on all
.js-add-to-hart-buttonbuttons. - Local Storage: Persisting the cart data so items remain if the user refreshes.
- Dynamic UI Updates: Upon clicking the button, a script automatically increments the
spancount within the navbar cart icon, providing instant visual confirmation.
Tip
This logic is prepared for the upcoming React Migration, where this global state will be moved into a useCart hook for cleaner data flow.
To get a local copy up and running, follow these simple steps:
-
Clone the repository:
π git clone
-
Open the folder: Launch the project in VS Code.
-
Install Extensions: Ensure you have the Live Server extension installed.
-
Launch: Right-click index.html and select "Open with Live Server" to view the app in your browser.
Keep track of the project's progress and upcoming features.
- Homepage Development
- HTML/CSS/JS (Complete)
- Checkout Page
- Form validation and order summary. persistence
- Order Tracking System
- Real-time status simulation.
- React Migration
- Converting components into reusable React pieces.
