DEV Community

Cover image for Build a Full-Stack E-Commerce React App from Scratch: The Ultimate Guide
PRANKUR PANDEY
PRANKUR PANDEY

Posted on • Edited on

Build a Full-Stack E-Commerce React App from Scratch: The Ultimate Guide

Introduction :

The increasing demand for user-friendly, feature-rich e-commerce platforms has become viral whether it's Amazon, Walmart, or Shopify everyone is shifting to become a self-hosted e-commerce platform to sell and arrange better goods online without annoying customers to visit physical shops to purchase anything.

My Project :

I am too much tech-friendly as I believe that technology can solve anything so I started learning about it and eventually got into web development I chose React JS to build something to practice my skills while gaining a deep understanding of the core concepts of React JS & its entire ecosystem.

I wanted to build some real-world applications so that recruiters and other people could relate to them easily therefore I developed Agri Store a basic E-commerce platform to utilize the power of React JS.

Project Goals :

The goal was to dig deeper by coding a lot into it I intend to showcase the capabilities of React JS, React Router v6, Context API, MockBee, TailwindCSS, React Hot Toast, and integrate features like product listings, sorting/filtering, authentication, cart/wishlist management, payment processing, and purchase history.

Project Structure and Key Features :

I wanted to industry-level best practices by separating the projects into folders and the folder structure is as follows:

The SRC folder: As you all know React JS has a separate source (src) folder that contains all the logic and UI parts and by combining everything we link everything to the main App JS FILE which serves the index.html file It also the main source file.

The Component Folder: Components are a small amount of UI for the entire page instead of making the same component repetitively if it is being used multiple times we create it once and call it anywhere on any page.

The Context Folder: The context Folder is responsible for managing the states in the entire application it helps to clean the code separately and create the files and folders concerning the feature we are building.

The Pages Folder: Pages are nothing different than other web pages in React JS instead of building the entire pages in one go we break the pages into smaller components.

The Services Folder: The services folder contains all the backend data which can be hosted as a JSON file or it can also be retrieved from an API.

The UTILS Folder: Utils or utility folder generally contains the main or supported libraries code in one file making your code much cleaner and easy to read and understand.

Decoding Page Structure :

My Project contains multiple pages as I have also implanted dynamic routing enabling users to see the product details in separate pages.

I have added the following pages to my work

  1. Landing or Homepage to showcase what I am offering

  2. Product Listing Page to display how many products I have along with their values and a sidebar section to filter out the products based on their price, rating & availability

  3. Dynamic Product Listing page for each product

  4. Cart Page along with the checkout button you can also increase and decrease the quantity of product and remove it as well from the cart

  5. Order & address manager page with the option to add an address and proceed with payment.

  6. Order Confirmation page that your order has been received successfully.

  7. Wishlist page to add products for future reference.

  8. Profile manager page where you can see the order you have purchased, the address you have added, and your profile information under the separate tabs.

  9. Authentication page for user login and signup along with mock login credentials.

Image description

Decoding the Entire project :

First I would like to disclose the common components that are being used everywhere in the project I will also add the code snippets along with the explanations

1. Header across the app




import { React, Link, useState } from "../../Utils/CustomUtils";

import {

useCartContext,

useFilterContext,

useWishlistContext,

} from "../../Context/AllContextIndex";

function Header() {

const [isMenuOpen, setIsMenuOpen] = useState(false);

const { cart } = useCartContext();

const { wish } = useWishlistContext();

const { dispatch } = useFilterContext();

const token = window.localStorage.getItem("token");

return (

<div>

<div class=" flex flex-row items-center justify-between w-full p-2 sm:px-4 shadow-xl shadow-xs bg-gray-700 fixed-top top">

<Link to="/">

<div class="ml-8 text-lg text-white hidden md:flex">Car-kit</div>

</Link>

<span class="w-full md:w-1/3 h-10 cursor-pointer border border-gray-300 text-sm rounded-full flex">

<input type="search" onChange={(e) => dispatch({ type: "SEARCHBAR", payload: e.target.value })} placeholder="Search"

class="flex-grow px-4 rounded-l-full rounded-r-full text-sm focus:outline-none"

/>

</span>

<div class="flex text-white text-2xl ">

<div class="flex w-48 justify-between ">

<Link to="/ProductListingPage">

<span class="material-icons "> store </span>

</Link>

<div class="">

<Link to="/WishlistPage">

<span class="material-icons "> favorite</span>

</Link>

<span class="w-4 h-4 rounded-full text-center absolute leading text-xs bg-red-500">

{wish.length}

</span>

</div>

<div class="navbadge">

<Link to="/CartPage">

<span class="material-icons"> shopping_cart </span>

</Link>

<span class="w-4 h-4 rounded-full text-center absolute leading text-xs bg-red-500">

{cart.length}

</span>

</div>

{!token ? (

<Link to="/LoginPage">

<span class="material-icons "> login </span>

</Link>

) : (

<Link to="/Accountpage">

<span class="material-icons "> account_circle </span>

</Link>

)}

</div>

</div>

</div>

</div>

);

}

export { Header }



Enter fullscreen mode Exit fullscreen mode

This code is a React component called Header which likely represents a header section of a website or web application. Let's break down the code step by step:

Imports: The code imports necessary modules and functions from other files. It imports React, Link, and useState from "../../Utils/CustomUtils", and imports custom context hooks useCartContext, useFilterContext, and useWishlistContext from "../../Context/AllContextIndex".

Function Component Header: This is the main React function component named Header.

State Management: It uses the useState hook to manage the state of isMenuOpen, initializing it with false.

Context Usage: It uses the custom context hooks (useCartContext, useFilterContext, useWishlistContext) to get the state values (cart, wish, dispatch) from the respective contexts.

Token Retrieval: It retrieves a token from the localStorage. This token might be used for authentication purposes.

JSX Rendering: It returns JSX elements to render the header section. The header consists of various elements such as links, search bar, icons, etc.

Dynamic Content: It dynamically displays the length of the wishlist and cart by accessing the length of wish and cart arrays respectively.

Conditional Rendering: It conditionally renders a login link or an account link based on the presence of a token.

Event Handling: It attaches an onChange event handler to the search input field, which dispatches an action with the type "SEARCHBAR" and the input value as the payload when the user types in the search bar.

CSS Styling: Inline CSS classes are used to style the elements. Classes like flex, items-center, justify-between, w-full, etc., are applied to structure and style the header section.

Overall, this code represents a header component with navigation links, a search bar, icons for wishlist, cart, and login/account, and dynamic content based on the user's actions.

2. Footer across the app




import React from "../../Utils/CustomUtils";

import "../../Utils/CustomCSSUtils.css";

function Footer() {

return (

<div>

<footer class="text-gray-400 bg-gray-900 body-font fixed bottom-0 w-full">

<div class="container px-5 py-8 mx-auto flex items-center sm:flex-row flex-col ">

<a class="flex title-font font-medium items-center md:justify-start justify-center text-white">

<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-10 h-10 text-white p-2 bg-red-500 rounded-full" viewBox="0 0 24 24">

<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>

</svg>

<span class="ml-3 text-xl">CarSale</span>

</a>

<p class="text-sm text-gray-400 sm:ml-4 sm:pl-4 sm:border-l-2 sm:border-gray-800 sm:py-2 sm:mt-0 mt-4">© 2023 CarSale —

<a href="https://prankurpandeyy.netlify.com" class="text-gray-500 ml-1" target="_blank" rel="noopener noreferrer">@prankurpandeyy</a>

</p>

<span class="inline-flex sm:ml-auto sm:mt-0 mt-4 justify-center sm:justify-start">

<a class="text-gray-400" href="https://fb.com/prankurpandeyy">

<svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-5 h-5" viewBox="0 0 24 24">

<path d="M18 2h-3a5 5 0 00-5 5v3H7v4h3v8h4v-8h3l1-4h-4V7a1 1 0 011-1h3z"></path>

</svg>

</a>

<a class="ml-3 text-gray-400" href="https://twitter.com/prankurpandeyy">

<svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-5 h-5" viewBox="0 0 24 24">

<path d="M23 3a10.9 10.9 0 01-3.14 1.53 4.48 4.48 0 00-7.86 3v1A10.66 10.66 0 013 4s-4 9 5 13a11.64 11.64 0 01-7 2c9 5 20 0 20-11.5a4.5 4.5 0 00-.08-.83A7.72 7.72 0 0023 3z"></path>

</svg>

</a>

<a class="ml-3 text-gray-400" href="https://instagram.com/prankurpandeyy">

<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-5 h-5" viewBox="0 0 24 24">

<rect width="20" height="20" x="2" y="2" rx="5" ry="5"></rect>

<path d="M16 11.37A4 4 0 1112.63 8 4 4 0 0116 11.37zm1.5-4.87h.01"></path>

</svg>

</a>

<a class="ml-3 text-gray-400" href="https://linkedin.com/in/prankurpandeyy">

<svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="0" class="w-5 h-5" viewBox="0 0 24 24">

<path stroke="none" d="M16 8a6 6 0 016 6v7h-4v-7a2 2 0 00-2-2 2 2 0 00-2 2v7h-4v-7a6 6 0 016-6zM2 9h4v12H2z"></path>

<circle cx="4" cy="4" r="2" stroke="none"></circle>

</svg>

</a>

</span>

</div>

</footer>

</div>

);

}

export { Footer };



Enter fullscreen mode Exit fullscreen mode

This code defines a React component called Footer, which likely represents the footer section of a website or web application. Let's break down the code:

  1. Imports:
  • import React from "../../Utils/CustomUtils";: Imports the React module from "../../Utils/CustomUtils". This import is not used directly in the component but is typically required in every React component file.

  • import "../../Utils/CustomCSSUtils.css";: Imports a CSS file named "CustomCSSUtils.css" from the "../../Utils" directory. This CSS file is likely used to style elements within the footer component.

  1. Function Component Footer:
  • This is the main React function component named Footer.

  • It returns JSX elements to render the footer section.

  1. JSX Rendering:
  • The footer consists of various elements such as a logo, text, links to social media profiles, etc.

  • The logo is an SVG image wrapped in an anchor (<a>) tag.

  • Text content includes the name of the website and copyright information.

  • Social media links are represented by SVG icons wrapped in anchor tags (<a>).

  1. CSS Classes:
  • Inline CSS classes are used to style the elements. Classes like text-gray-400, bg-gray-900, px-5, py-8, etc., are applied to structure and style the footer section.

  • Additionally, classes from the imported CSS file (CustomCSSUtils.css) may also be applied to style certain elements.

  1. Export:
  • export { Footer };: This line exports the Footer component, making it available for import in other files. By exporting the Footer component, you make it accessible for use in other parts of your application.

Overall, this code represents a footer component with branding, text content, and links to social media profiles, styled using CSS classes.

3. Product Cards from the product listing page to the wishlist & checkout page :




import { React, Link, useNavigate } from "../../Utils/CustomUtils";

import {

useWishlistContext,

useCartContext,

useProductContext,

} from "../../Context/AllContextIndex";

import { addToCart, removeFromCart } from "../../Services/CartServices";

import { addToWishlist, deleteWishList } from "../../Services/WishlistServices";

import "./ProductCard.css";

function ProductCard({ productCardData }) {

const { _id, image, title, price, rating, inStock } = productCardData;

const { wish } = useWishlistContext();

const { dispatch } = useProductContext();

const { cart } = useCartContext();

const navigate = useNavigate();

const token = localStorage.getItem("token");

return (

<div>

<div class="w-full h-full flex justify-center items-center">

<div class="relative p-4 flex justify-center rounded-xl cursor-pointer">

<div class="top-0 left-0 mt-3 px-2 rounded-lg absolute z-30 bg-green-500 text-gray-100 text-xs md:text-sm font-medium md:block">

{inStock === true ? `in Stock` : `out of stock`}

</div>

<div class="top-0 left-0 h-2 md:h-3 mt-5 px-2 absolute z-20 bg-green-500"></div>

<div class="top-0 left-0 h-2 md:h-3 mt-6 pl-5 rounded-3xl absolute z-0 bg-green-600"></div>

<div class="w-52 pb-2 bg-white rounded-xl z-10">

<div class="relative">

<img src={image} class="max-h-60 object-cover rounded-t-xl" alt=""/>

</div>

<div class="px-2 py-1">

<Link to={`/Productdetails/${_id}`}>

<div class="text-sm md:text-base font-bold pr-2">{title}</div>

</Link>

<div class="flex py-2">

<div class="bg-gray-200 p-1 mr-2 rounded-full text-xs font-medium text-gray-900"> ${price}k</div>

<div class="flex justify-between item-center">

<div class="flex items-center">

<svg xmlns="http://www.w3.org/2000/svg" class="h-3 md:h-5 md:w-5 text-yellow-500" viewBox="0 0 20 20" fill="currentColor">

<path d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z" />

</svg>

<p class="text-gray-600 font-bold text-xs md:text-sm ml-1">

{rating}

<span class="text-gray-500 font-normal">

(76 rewiews)

</span>

</p>

</div>

</div>

</div>

<div className="flex flex-col justify-center items-center p-4">

{cart.some((prod) => prod._id === productCardData._id) ? (

<button class="p-1 flex mb-2 justify-center items-center bg-red-600 hover:bg-red-700 focus:ring-indigo-500 focus:ring-offset-indigo-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg " onClick={(_id) =>

removeFromCart(productCardData._id, dispatch)}>CART-

<span class="material-icons">remove_shopping_cart </span>

</button>

) : (

<button class="p-1 flex mb-2 justify-center items-center bg-gray-700 hover:bg-indigo-700 focus:ring-indigo-500 focus:ring-offset-indigo-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg "

onClick={() => addToCart(productCardData, dispatch)} >CART+

<span class="material-icons ">shopping_cart</span>

</button>

)}

{wish.some(

(wishlist) => wishlist._id === productCardData._id

) ? (

<button class="p-1 flex justify-center items-center bg-red-600 hover:bg-red-700 focus:ring-indigo-500 focus:ring-offset-indigo-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg" onClick={(_id) => deleteWishList(productCardData._id, dispatch)}>WISHLIST- <span class="material-icons">favorite </span> </button>

) : (

<button

class="p-1 flex justify-center items-center bg-gray-700 hover:bg-indigo-700 focus:ring-indigo-500 focus:ring-offset-indigo-200 text-white w-full transition ease-in duration-200 text-center text-base font-semibold shadow-md focus:outline-none focus:ring-2 focus:ring-offset-2 rounded-lg " onClick={() => addToWishlist(productCardData, dispatch)}>

WISHLIST+

<span class="material-icons">favorite_border </span>

</button>

)}

</div>

</div>

</div>

</div>

</div>

</div>

);}

export default ProductCard;



Enter fullscreen mode Exit fullscreen mode

This code defines a React component called ProductCard, which is likely used to display individual product cards on a website or web application. Let's break down the code:

  1. Imports:
  • import { React, Link, useNavigate } from "../../Utils/CustomUtils";: Imports React, Link, and useNavigate from "../../Utils/CustomUtils". These are likely custom utility functions or modules used in the project.

  • import { useWishlistContext, useCartContext, useProductContext } from "../../Context/AllContextIndex";: Imports custom context hooks useWishlistContext, useCartContext, and useProductContext from "../../Context/AllContextIndex".

  • import { addToCart, removeFromCart } from "../../Services/CartServices";: Imports functions addToCart and removeFromCart from "../../Services/CartServices". These functions likely handle adding and removing items from the cart.

  • import { addToWishlist, deleteWishList } from "../../Services/WishlistServices";: Imports functions addToWishlist and deleteWishList from "../../Services/WishlistServices". These functions likely handle adding items to the wishlist and deleting items from it.

  • import "./ProductCard.css";: Imports a CSS file named "ProductCard.css".

  1. Function Component ProductCard:
  • This is the main React function component named ProductCard.

  • It receives props, specifically productCardData, which likely contains information about the product to be displayed in the card.

  1. Destructuring Props:
  • The productCardData prop is destructured to extract relevant data such as _id, image, title, price, rating, and inStock.
  1. Context Usage:
  • It uses custom context hooks to access the cart (cart), wishlist (wish), and product (dispatch) contexts.
  1. State and Navigate:
  • It uses the useNavigate hook to obtain a navigation function (navigate) for programmatic navigation.

  • It retrieves a token from the local storage.

  1. JSX Rendering:
  • It returns JSX elements to render the product card.

  • The card includes product details such as image, title, price, and rating.

  • It displays whether the product is in stock or out of stock.

  • It provides buttons for adding/removing the product from the cart and wishlist based on their respective states.

  • Each button triggers a specific action (e.g., adding to cart, removing from wishlist) via the provided service functions.

  1. CSS Styling:
  • It applies CSS classes and styles defined in the "ProductCard.css" file to style the elements of the product card.
  1. Export:
  • export default ProductCard;: This line exports the ProductCard component as the default export, making it available for import in other files. By exporting it as the default export, you can import and use the ProductCard component without using curly braces in other files.

Overall, this code represents a reusable component (ProductCard) used to display product information and provide functionality for adding/removing products from the cart and wishlist. It follows best practices by separating concerns, utilizing custom contexts and service functions, and applying CSS for styling.

4. Inputs at authentication pages as well as in the address manager




import { React, Link, useNavigate, useEffect, useState } from "../../Utils/CustomUtils";

import "../../Utils/CustomCSSUtils.css";

import { useLoginContext } from "../../Context/AllContextIndex";

import { loginHandler } from "../../Services/AuthServices";

function LoginInputs() {

const { dispatch, email, password, name } = useLoginContext();

const navigate = useNavigate();

function submitLoginData() {

loginHandler(email, password, dispatch);

navigate("/ProductListingPage");

}

const [error, setError] = useState("");

const [isDisabled, setIsDisabled] = useState(true);

useEffect(() => {

if (email.length > 0 && password.length > 0) {

setError("");

setIsDisabled(false);

} else {

setError("All fields must be filled.");

setIsDisabled(true);

}

}, [email, password]);

function setGuestLoginData(e) {

e.preventDefault();

const email = "6prankur@gmail.com";

const password = "12345678";

const name = `Guest`;

dispatch({ type: "EMAIL", payload: email });

dispatch({ type: "PASSWORD", payload: password });

dispatch({ type: "NAME", payload: name });

}

return (

<div>

<section class="text-gray-400 bg-gray-900 body-font">

<div class="container px-5 py-24 mx-auto flex flex-wrap items-center">

<div class="lg:w-3/5 md:w-1/2 md:pr-16 lg:pr-0 pr-0">

<h1 class="title-font font-medium text-3xl text-white">Slow-carb next level shoindxgoitch ethical authentic, poko scenester</h1>

<p class="leading-relaxed mt-4">Poke slow-carb mixtape knausgaard, typewriter street art gentrify hammock starladder roathse. Craies vegan tousled etsy austin.</p>

</div>

<div class="lg:w-2/6 md:w-1/2 bg-gray-800 bg-opacity-50 rounded-lg p-8 flex flex-col md:ml-auto w-full mt-10 md:mt-0">

<h2 class="text-white text-lg font-medium title-font mb-5">Log In</h2>

<div>

<form onSubmit={submitLoginData}>

<div class="relative mb-4">

<label for="full-name" class="leading-7 text-sm text-gray-400">Email</label>

<input id="email" type="email" value={email} name="email"

onChange={(e) => dispatch({ type: "EMAIL", payload: e.target.value })}

class="w-full bg-gray-600 bg-opacity-20 focus:bg-transparent focus:ring-2 focus:ring-red-900 rounded border border-gray-600 focus:border-red-500 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"

placeholder="Enter your email"

/>

</div>

<div class="relative mb-4">

<label for="email" class="leading-7 text-sm text-gray-400">Password</label>

<input id="password" type="password" name="password" value={password} placeholder="enter your password" onChange={(e) => dispatch({ type: "PASSWORD", payload: e.target.value })}

class="w-full bg-gray-600 bg-opacity-20 focus:bg-transparent focus:ring-2 focus:ring-red-900 rounded border border-gray-600 focus:border-red-500 text-base outline-none text-gray-100 py-1 px-3 leading-8 transition-colors duration-200 ease-in-out"

/>

</div>

<div className="flex flex-col">

<input type='submit' class="text-white bg-red-500 border-0 py-2 px-8 focus:outline-none hover:bg-red-600 rounded text-lg cursor-pointer" />

<button class="text-white bg-blue-500 border-0 py-2 px-8 focus:outline-none hover:bg-blue-600 rounded text-lg mt-2" onClick={setGuestLoginData}>Guest Login</button>

</div>

</form>

</div>

<p class="text-xs mt-3">Literally you probably haven't heard of them jean shorts.

<Link to="/SignupPage" class="text-xs ml-2 text-blue-500 font-semibold">

<a href="#" class="font-medium text-blue-600 dark:text-blue-500 hover:underline">SignUp</a>

</Link>

</p>

</div>

</div>

</section>

</div>

);}

export default LoginInputs;



Enter fullscreen mode Exit fullscreen mode

This code defines a React component named LoginInputs, which likely represents a form for user login functionality. Let's break down the code:

  1. Imports:
  • import { React, Link, useNavigate, useEffect, useState } from "../../Utils/CustomUtils";: Imports React, Link, useNavigate, useEffect, and useState from "../../Utils/CustomUtils". These are likely custom utility functions or modules used in the project.

  • import "../../Utils/CustomCSSUtils.css";: Imports a CSS file named "CustomCSSUtils.css", presumably for styling the login form.

  • import { useLoginContext } from "../../Context/AllContextIndex";: Imports a custom context hook useLoginContext from "../../Context/AllContextIndex".

  • import { loginHandler } from "../../Services/AuthServices";: Imports a function loginHandler from "../../Services/AuthServices", which likely handles the authentication process.

  1. Function Component LoginInputs:
  • This is the main React function component named LoginInputs.

  • It doesn't receive any props directly.

  1. Context Usage:
  • It uses the custom context hook useLoginContext to access login-related state variables such as email, password, and dispatch.
  1. State Management:
  • It initializes local state variables error and isDisabled using the useState hook.

  • These states are used to manage error messages and to disable/enable the submit button based on form validation.

  1. Event Handling:
  • It defines event handlers for submitting login data and setting guest login data.

  • submitLoginData() is called when the login form is submitted. It calls the loginHandler function and navigates to the product listing page upon successful login.

  • setGuestLoginData() is called when the "Guest Login" button is clicked. It sets predefined guest login data in the login form.

  1. Effect Hook:
  • It uses the useEffect hook to perform form validation whenever the email or password state variables change.

  • If both fields are filled, it clears any existing errors and enables the submit button. Otherwise, it sets an error message and disables the submit button.

  1. JSX Rendering:
  • It returns JSX elements to render the login form.

  • The form includes input fields for email and password, along with a submit button and a "Guest Login" button.

  • It also includes a link to the signup page.

  1. CSS Styling:
  • It applies CSS classes and styles defined in the "CustomCSSUtils.css" file to style the elements of the login form.
  1. Export:
  • export default LoginInputs;: This line exports the LoginInputs component as the default export, making it available for import in other files.

Overall, this code represents a reusable component (LoginInputs) used to display a login form, handle user input, perform form validation, and interact with the authentication service. It follows best practices by separating concerns, utilizing custom contexts and services, and applying CSS for styling.

API's :

Now it is time to build pages and integrate the Data APIs before we start building the pages it is the perfect time to understand the APIs & their integration part and how we are using them in our project.

What is an API:

API stands for Application programming interface now let's break all these one by one

Application - In Information Technology an application is an online/offline tool made to serve a specific purpose to solve problems which includes business logic and is responsible for recording and growing the records online these records are recorded in the database through the frontend and the mechanism which helps to do so is called backend.

Programming - It is the technological process of telling a computer which tasks to perform to solve problems and while communicating with computers we use some languages these languages are programming languages such as C, C++ and my favorite JavaScript.

Interface - Consider the interface as a client between your backend data and database without exposing the business logic.

Now the API theory part is done it is time to show some real magic

This is a sample code of all the products that I am getting from the API call from Mockbee




import { React, toast, axios } from "../Utils/CustomUtils";



export async function getProdcutsData(dispatch) {

dispatch({ type: "LOADINGSPINNER", payload: true });

try {

await axios({

method: "GET",

url: `/api/products`,

}).then((response) =>

dispatch({ type: "APIPRODUCTDATA", payload: response.data.products })

);



dispatch({ type: "LOADINGSPINNER", payload: false });

} catch (erorr) {

toast.error(`Server is encountering some issues:`, erorr);

console.log(`Server is encountering some issues:`, erorr);

}

}



Enter fullscreen mode Exit fullscreen mode

This code is an asynchronous function named getProdcutsData used to fetch product data from an API endpoint. Let's break down the code:

  1. Imports: It imports necessary modules React, toast, and axios from the "../Utils/CustomUtils" module.

  2. Function Definition:

  • async function getProdcutsData(dispatch): It defines an asynchronous function named getProdcutsData that takes a dispatch function as a parameter.
  1. Dispatch Action:
  • dispatch({ type: "LOADINGSPINNER", payload: true }): It dispatches an action of type "LOADINGSPINNER" with the payload true to indicate that the loading spinner should be shown.
  1. API Request:
  • await axios({ method: "GET", url: "/api/products" }): It makes a GET request to the "/api/products" endpoint using Axios and waits for the response.
  1. Handling Response:
  • .then((response) => dispatch({ type: "APIPRODUCTDATA", payload: response.data.products })): Once the response is received, it extracts the products data from the response and dispatches an action of type "APIPRODUCTDATA" with the payload containing the products data.
  1. Dispatch Action (Loading Complete):
  • dispatch({ type: "LOADINGSPINNER", payload: false }): After receiving the product data or encountering an error, it dispatches an action to stop the loading spinner by setting the payload to false.
  1. Error Handling:
  • catch (erorr): If any error occurs during the API request, it catches the error.

  • toast.error(Server is encountering some issues:, erorr): It shows an error toast notification indicating that the server encountered some issues.

  • console.log(Server is encountering some issues:, erorr): It logs the error to the console for debugging purposes.

In summary, this code fetches product data from an API endpoint, dispatches actions to manage loading state, and handles errors appropriately using toast notifications and console logging.

All the APIs are integrated in a similar way as Frontend developer its the very crucial and most important part of your job to be very well versed with API integration.

Before the integration you will have to check and call it once the API is called you will get the response in your console first and after that you will have to tweak the response to display it on Screen, it is not that easy as I said earlier it is very crucial.

In this project, I have used 20+ API calls and each call is responsible for doing different tasks.

Developing Pages

Developing pages is the next task right after developing components here things go hard as this is the area where you will have to do two things in one go first is integrating API data and second is managing components.

This project has eight pages in the following order :

  1. Homepage

  2. Product listing page

  3. Single Product view page

  4. Cart Manager page

  5. Wishlist page

  6. Checkout page

  7. Order success page

  8. Profile manager page

Homepage

The Homepage is the main page of any application which describes what the application is all about, my homepage has the following structure here is the code




import React from "react";

import {

Footer,

Header,

Hero,

FeaturedBrands,

Spinner,

} from "../../Components/AllComponentIndex";

import { useProductDataContext } from "../../Context/ProductListingPageContext";

function Homepage() {

const { isLoading } = useProductDataContext();

return (

<div>

<Header />

{isLoading ? (

<Spinner />

) : (

<div className="mt-12">

<Hero />

<FeaturedBrands />

</div>

)}

<Footer />

</div>

);

}

export default Homepage;



Enter fullscreen mode Exit fullscreen mode

This code defines a React functional component named Homepage. Let's break down the code:

  1. Imports:
  • React: Importing the React library to define React components.

  • Footer, Header, Hero, FeaturedBrands, Spinner: Importing various components from "../../Components/AllComponentIndex" to be used in the Homepage component.

  • useProductDataContext: Importing the useProductDataContext hook from "../../Context/ProductListingPageContext" to access data related to the product listing page.

  1. Function Definition:
  • function Homepage() { ... }: Defines a functional component named Homepage.
  1. Component Logic:
  • const { isLoading } = useProductDataContext();: Destructures the isLoading state from the useProductDataContext hook. This state indicates whether the data is loading or not.
  1. Component JSX:
  • <div>: Opens a container div for the component.

  • <Header />: Renders the Header component.

  • {isLoading ? (<Spinner />) : ( <div className="mt-12"> <Hero /> <FeaturedBrands /> </div> )}:

  • Checks if isLoading is true.

  • If isLoading is true, render the Spinner component to indicate that data is loading.

  • If isLoading is false, renders the Hero and FeaturedBrands components wrapped in a div with className="mt-12".

  • <Footer />: Renders the Footer component.

  • </div>: Closes the container div for the component.

  1. Export:
  • export default Homepage;: Exports the Homepage component as the default export.

In summary, the Homepage component renders a header, a spinner while the data is loading, and a hero section along with featured brands when the data has finished loading. It utilizes context to manage the loading state and components from the specified index file.

The final output look is here :

Image description

Product listing page

The Product listing page is responsible for listing all the products in grid view along with the sidebar containing different types of filters to change and find out the product with respect to their stock, price & order. Here is the code




import { React, toast, useNavigate } from "../../Utils/CustomUtils";

import {

useCatagoriesFilterContext,

useProductDataContext,

} from "../../Context/AllContextIndex";

import {

Footer,

Header,

Spinner,

ProductCard,

Sidebar,

} from "../../Components/AllComponentIndex";

import "./ProductlistingPage.css";

function ProductlistingPage() {

const { isLoading } = useProductDataContext();

const { searchbarData } = useCatagoriesFilterContext();

return (

<div className="bg-gray-700 h-screen">

<Header />

<div className="flex justify-start items-start">

<Sidebar />

<div className="flex flex-wrap ml-64 mt-24 mb-8 items-center justify-center">

{isLoading ? (

<Spinner />

) : (

searchbarData.map((productCardData) => {

return (

<ProductCard

productCardData={productCardData}

key={productCardData._id}

/>

);

})

)}

</div>

</div>
</div>

);

}

export default ProductlistingPage;



Enter fullscreen mode Exit fullscreen mode

This code defines a React functional component named ProductlistingPage. Let's break down the code:

  1. Imports:
  • React, toast, useNavigate: Importing React library, toast, and useNavigate hook from "../../Utils/CustomUtils".

  • useCatagoriesFilterContext, useProductDataContext: Importing context hooks from "../../Context/AllContextIndex".

  • Footer, Header, Spinner, ProductCard, Sidebar: Importing various components from "../../Components/AllComponentIndex" to be used in the ProductlistingPage component.

  1. Function Definition:
  • function ProductlistingPage() { ... }: Defines a functional component named ProductlistingPage.
  1. Component Logic:
  • const { isLoading } = useProductDataContext();: Destructures the isLoading state from the useProductDataContext hook. This state indicates whether the data is loading or not.

  • const { searchbarData } = useCatagoriesFilterContext();: Destructures the searchbarData from the useCatagoriesFilterContext hook. This data represents the filtered products based on categories.

  1. Component JSX:
  • <div className="bg-gray-700 h-screen">: Opens a container div with a grey background that covers the entire height of the screen.

  • <Header />: Renders the Header component.

  • <div className="flex justify-start items-start">: Opens a div with flex layout to arrange items horizontally, starting from the left.

  • <Sidebar />: Renders the Sidebar component.

  • <div className="flex flex-wrap ml-64 mt-24 mb-8 items-center justify-center">: Opens a div with flex layout, wrapping its contents, and applying margin and alignment styles.

  • {isLoading ? (<Spinner />) : ( searchbarData.map((productCardData) => { ... }))}: Renders the Spinner component if isLoading is true. Otherwise, it maps over the searchbarData array and renders a ProductCard component for each item.

  • </div>: Closes the div with flex layout.

  • </div>: Closes the outer container div.

  1. Export:
  • export default ProductlistingPage;: Exports the ProductlistingPage component as the default export.

In summary, the ProductlistingPage component renders a header, a sidebar, and a list of product cards. The product cards are dynamically rendered based on the data fetched from the context, and a spinner is shown while the data is loading.

The Final Output is here :

Image description

Single Product View Page

The Single Product view is the best example of dynamic routing which is made possible due to React Router it allows to enable dynamic routing resulting in creating a single page for each product along with its details.

Here is the sample code :




import React from "react";

import {Footer,Header,SingleProductCard} from "../../Components/AllComponentIndex";

function SingleProductPage() {

return (

<div>

<Header />

<SingleProductCard />

<Footer />

</div>

);

}

export default SingleProductPage;



Enter fullscreen mode Exit fullscreen mode

This code defines a React functional component named SingleProductPage. Let's break down the code:

  1. Imports:
  • React: Importing React library to define and use React components.

  • Footer, Header, SingleProductCard: Importing components from "../../Components/AllComponentIndex" to be used in the SingleProductPage component.

  1. Function Definition:
  • function SingleProductPage() { ... }: Defines a functional component named SingleProductPage.
  1. Component JSX:
  • <div>: Opens a container div.

  • <Header />: Renders the Header component.

  • <SingleProductCard />: Renders the SingleProductCard component.

  • <Footer />: Renders the Footer component.

  • </div>: Closes the container div.

  1. Export:
  • export default SingleProductPage;: Exports the SingleProductPage component as the default export.

In summary, the SingleProductPage component renders a header, a single product card, and a footer. It serves as a page for displaying details of a single product.

Let's dig deeper into what's inside the <SingleProductCard />




import {React,useEffect,useState,axios,toast,useParams} from "../../Utils/CustomUtils";

import {useWishlistContext,useCartContext,useProductContext} from "../../Context/AllContextIndex";

import { Rating } from "../../Components/AllComponentIndex";

import "./SingleProductCard.css";

import { addToCart, removeFromCart } from "../../Services/CartServices";

import { addToWishlist, deleteWishList } from "../../Services/WishlistServices";

function SingleProductCard() {

const { wish } = useWishlistContext();

const { dispatch } = useProductContext();

const { cart } = useCartContext();

const [singleProduct, setSingleProduct] = useState([]);

const {_id,inStock,manufacturedBy,image,title,rating,price,description,categoryName,} = singleProduct;

const productId = useParams();

 // function to get the product data from the product id

function getProductById(productId) {

axios.get(`/api/products/${productId}`).then((res) => {

setSingleProduct(res.data.product);

}).catch((err) => {console.log(" err", err);

});

}

useEffect(() => {

toast.success(" Fetching single card data.");

getProductById(productId.id);

}, [productId]);


return (

<div>

<section class="text-gray-600 body-font overflow-hidden">

<div class="container px-5 py-24 mx-auto">

<div class="lg:w-4/5 mx-auto flex flex-wrap">

<img alt="ecommerce" class="lg:w-1/2 w-full lg:h-auto h-64 object-cover object-center rounded"

src={image && image}

/>

<div class="lg:w-1/2 w-full lg:pl-10 lg:py-6 mt-6 lg:mt-0">

<h1 class="text-gray-900 text-3xl title-font font-medium mb-1">

{title && title}

</h1>

<div class="flex mb-4">

<span class="flex items-center">

<svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-4 h-4 text-indigo-500" viewBox="0 0 24 24">

<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>

</svg>

<svg

fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-4 h-4 text-indigo-500" viewBox="0 0 24 24" >

<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>

</svg>

<svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-4 h-4 text-indigo-500" viewBox="0 0 24 24">

<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>

</svg>

<svg fill="currentColor" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-4 h-4 text-indigo-500" viewBox="0 0 24 24">

<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>

</svg>

<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-4 h-4 text-indigo-500" viewBox="0 0 24 24">

<path d="M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z"></path>

</svg>

<span class="text-gray-600 ml-3">4 Reviews</span>

</span>

</div>

<p class="leading-relaxed">{description && description}</p>

<div class="flex mt-6 items-center pb-5 border-b-2 border-gray-100 mb-5">

<div class="flex ml-6 items-center">

<div class="relative">

<span class="absolute right-0 top-0 h-full w-10 text-center text-gray-600 pointer-events-none flex items-center justify-center">

<svg fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-4 h-4" viewBox="0 0 24 24">

<path d="M6 9l6 6 6-6"></path>

</svg>

</span>

</div>

</div>

</div>

<div class="flex">

<span class="title-font font-medium text-2xl text-gray-900">

${price && price}

</span>

{cart.some((prod) => prod._id === _id) ? (

<button class="flex ml-auto text-white bg-red-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded" onClick={(_id) => removeFromCart(_id, dispatch)}>

{" "}

REMOVE FROM CART

<span class="material-icons buttonmi">

remove_shopping_cart{" "}

</span>

</button>

) : (

<button

class="flex ml-auto text-white bg-indigo-500 border-0 py-2 px-6 focus:outline-none hover:bg-indigo-600 rounded" onClick={() => addToCart(singleProduct, dispatch)}>

ADD TO CART <span class="material-icons buttonmi"> shopping_cart</span>

</button>

)}

{wish.some((wishlist) => wishlist._id === _id) ? (

<button

class="rounded-full w-10 h-10 bg-red-500 p-0 border-0 inline-flex items-center justify-center text-white ml-4"

onClick={(_id) => deleteWishList(_id, dispatch)}

>

<span class="material-icons buttonmi">

favorite_border{" "}

</span>

</button>

) : (

<button

onClick={() => addToWishlist(singleProduct, dispatch)}

class="rounded-full w-10 h-10 bg-gray-200 p-0 border-0 inline-flex items-center justify-center text-gray-500 ml-4"

>

<svg fill="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" class="w-5 h-5" viewBox="0 0 24 24" >

<path d="M20.84 4.61a5.5 5.5 0 00-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 00-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 000-7.78z"></path>

</svg>

</button>

)}

</div>

</div>

</div>

</div>

</section>

</div>

);

}

export default SingleProductCard;



Enter fullscreen mode Exit fullscreen mode

Here is the complete explanation of the code

This code defines a React functional component named SingleProductCard. Let's break down the code:

  1. Imports:
  • React: Importing React library to define and use React components.

  • useEffect, useState, axios, toast, useParams: Importing hooks and libraries from "../../Utils/CustomUtils" for managing component state, making HTTP requests, displaying notifications, and accessing route parameters.

  • useWishlistContext, useCartContext, useProductContext: Importing custom hooks from "../../Context/AllContextIndex" for accessing context data related to wishlist, cart, and product.

  • Rating: Importing the Rating component from "../../Components/AllComponentIndex".

  1. Function Definition:
  • function SingleProductCard() { ... }: Defines a functional component named SingleProductCard.
  1. Component State:
  • const [singleProduct, setSingleProduct] = useState([]);: Declares state variable singleProduct and its setter function using the useState hook. It initializes singleProduct with an empty array.
  1. Route Parameters:
  • const productId = useParams();: Retrieves route parameters using the useParams hook.
  1. Function to Fetch Product Data:
  • getProductById(productId): Defines a function getProductById to fetch product data based on the provided product ID using Axios.
  1. Effect Hook:
  • useEffect(() => { ... }, [productId]);: Executes the effect function whenever the productId changes. It fetches product data based on the productId using the getProductById function.
  1. Component JSX:
  • Renders the product details including title, image, rating, price, description, and buttons for adding/removing from cart and wishlist.
  1. Export:
  • export default SingleProductCard;: Exports the SingleProductCard component as the default export.

In summary, the SingleProductCard component fetches and displays details of a single product based on the product ID obtained from the route parameters. It also provides options for adding/removing the product from the cart and wishlist.

The screen output is here :

Image description

Cart Manager page

The cart manager in any e-commerce app is important as it helps users to completely manage the quantity and place the order for the product.

In this application, you can increase and decrease the quantity,remove the product from the cart, add the product to the wishlist and place the order.

Here is the sample code




import { Link, useEffect } from "../../Utils/CustomUtils";

import {

Header,

Footer,

TotalPrice,

Spinner,

} from "../../Components/AllComponentIndex";

import {

useCartContext,

useProductDataContext,

useWishlistContext,

} from "../../Context/AllContextIndex";

import { removeFromCart, updateQty } from "../../Services/CartServices";

import { addToWishlist, deleteWishList } from "../../Services/WishlistServices";

function CartPage() {

const { dispatch, wish } = useWishlistContext();

const { isLoading } = useProductDataContext();

const { cart, state, totalprice } = useCartContext();

useEffect(() => {

dispatch({

type: "TOTALPRICE",

payload: cart.reduce(

(acc, item) => acc + Number(item.qty) * Number(item.price),

0

),

});

}, [cart]);

return (

<>

<Header cart={cart} />

<section class=" bg-gray-100 py-12 sm:py-16 lg:py-20 mb-20">

<div class="mx-auto px-4 sm:px-6 lg:px-8">

<div class="flex items-center justify-center">

</div>

<div class="mx-auto mt-20 mb-8 max-w-2xl md:mt-12">
<div class="bg-white shadow">

<div class="px-4 py-6 sm:px-8 sm:py-10">

<div class="flow-root">

<ul class="-my-8">

{cart.map(cartdata => {

return (

<li class="flex flex-col space-y-3 py-6 text-left sm:flex-row sm:space-x-5 sm:space-y-0">

<div class="shrink-0">

<img class="h-24 w-24 max-w-full rounded-lg object-cover" src={cartdata.image} alt="" />

</div>
<div class="relative flex flex-1 flex-col justify-between">

<div class="sm:col-gap-5 sm:grid sm:grid-cols-2">

<div class="pr-8 sm:pr-5">

<p class="text-base font-semibold text-gray-900">{cartdata.title}</p>

<span class="relative inline-block px-3 py-1 font-semibold text-green-900 leading-tight">

{wish.some(

(wishlist) => wishlist._id === cartdata._id

) ? (

<button data-tooltip-target="tooltip-default"

onClick={(_id) =>

deleteWishList(cartdata._id, dispatch)

}

>

<span class="material-icons">

heart_broken

</span>

</button>

) : (

<button

onClick={() => addToWishlist(cartdata, dispatch)}

>

<span class="material-icons">

{" "}

favorite_border{" "}

</span>

</button>

)}

</span>

<span class="relative inline-block px-3 py-1 font-semibold text-green-900 leading-tight">

<button

onClick={(_id) =>

removeFromCart(cartdata._id, dispatch)

}

>

<span class="material-icons">delete</span>

</button>

</span>

</div>

<div class="mt-4 flex items-end justify-between sm:mt-0 sm:items-start sm:justify-end">

<p class="shrink-0 w-20 text-base font-semibold text-gray-900 sm:order-2 sm:ml-8 sm:text-right">{cartdata.price}</p>

<div class="sm:order-1">

<div class="mx-auto flex h-8 items-stretch text-gray-600">

<button class="flex items-center justify-center rounded-l-md bg-gray-200 px-4 transition hover:bg-black hover:text-white" onClick={() =>

updateQty("decrement", cartdata._id, dispatch)

}>-</button>

<div class="flex w-full items-center justify-center bg-gray-100 px-4 text-xs uppercase transition">{cartdata.qty}</div>

<button class="flex items-center justify-center rounded-r-md bg-gray-200 px-4 transition hover:bg-black hover:text-white" onClick={() =>

updateQty("increment", cartdata._id, dispatch)

}>+</button>

</div>

</div>

</div>

</div>

</div>

</li>)

})

}

</ul>

</div>
<div class="mt-6 border-t border-b py-2">

<div class="flex items-center justify-between">

<p class="text-sm text-gray-400">Subtotal</p>

<p class="text-lg font-semibold text-gray-900">{totalprice}</p>

</div>

</div>

<div class="mt-6 flex items-center justify-between">

<p class="text-sm font-medium text-gray-900">Total</p>

<p class="text-2xl font-semibold text-gray-900"><span class="text-xs font-normal text-gray-400"></span> {totalprice}</p>

</div>
<div class="mt-6 text-center">

<Link to='/Checkoutpage'>

<button type="button" class="group inline-flex w-full items-center justify-center rounded-md bg-gray-900 px-6 py-4 text-lg font-semibold text-white transition-all duration-200 ease-in-out focus:shadow hover:bg-gray-800">

Checkout

<svg xmlns="http://www.w3.org/2000/svg" class="group-hover:ml-8 ml-4 h-6 w-6 transition-all" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">

<path stroke-linecap="round" stroke-linejoin="round" d="M13 7l5 5m0 0l-5 5m5-5H6" />

</svg>

</button> </Link>

</div>

</div>

</div>

</div>

</div>

</section>

<Footer />

</>

);

}

export default CartPage;



Enter fullscreen mode Exit fullscreen mode

This code defines a React functional component named CartPage, which represents the shopping cart page of an e-commerce application. Let's break down the code:

  1. Imports:
  • Link: Importing Link from "../../Utils/CustomUtils" for routing.

  • useEffect: Importing the useEffect hook from React for side effects.

  • Header, Footer, TotalPrice, Spinner: Importing components from "../../Components/AllComponentIndex".

  • useCartContext, useProductDataContext, useWishlistContext: Importing custom hooks from "../../Context/AllContextIndex" for accessing context data related to the cart, product data, and wishlist.

  • removeFromCart, updateQty, addToWishlist, deleteWishList: Importing functions from "../../Services/CartServices" and "../../Services/WishlistServices" for managing cart and wishlist actions.

  1. Function Definition:
  • function CartPage() { ... }: Defines a functional component named CartPage.
  1. Context and State Variables:
  • Retrieves context and state variables using custom context hooks: useWishlistContext, useProductDataContext, useCartContext.

  • Destructures variables like dispatch, wish, isLoading, cart, state, totalprice from the respective contexts.

  1. Effect Hook:
  • Uses the useEffect hook to calculate the total price of items in the cart whenever the cart state changes. It dispatches an action to update the total price.
  1. Component JSX:
  • Renders the header, which includes a cart icon indicating the number of items in the cart.

  • Displays a section for the shopping cart items, including product image, title, price, quantity, and buttons for removing items from the cart or wishlist.

  • Calculates and displays the subtotal and total price of the items in the cart.

  • Provides a "Checkout" button linked to the Checkout page using the Link component.

  1. Export:
  • export default CartPage;: Exports the CartPage component as the default export.

In summary, the CartPage component renders the contents of the shopping cart, and allows users to update quantities, remove items, and proceed to checkout. It also interacts with the wishlist, allowing users to add or remove items.

The cart manager screen output is here :

1711683292669

Wishlist page

The wishlist page allows users to add products for future reffernce hereis the sample code .




import { React } from "../../Utils/CustomUtils";

import {

useProductDataContext,

useWishlistContext,

} from "../../Context/AllContextIndex";

import {

Footer,

Header,

ProductCard,

Spinner,

} from "../../Components/AllComponentIndex";



import "./Wishlist.css";

function WishlistPage() {

const { wish } = useWishlistContext();

const { isLoading } = useProductDataContext();



return (

<div>

<Header />



{isLoading ? (

<Spinner />

) : wish.length === 0 ? (

<div className="cart-mesg"> there are no items in Wishlist </div>

) : (

<div className="wishlist-cards">

{wish.map((wishlistpagedata) => {

return (

<ProductCard

productCardData={wishlistpagedata}

key={wishlistpagedata._id}

/>

);

})}

</div>

)}



<Footer />

</div>

);

}



export default WishlistPage;



Enter fullscreen mode Exit fullscreen mode

This code defines a React functional component named WishlistPage, which represents the wishlist page of an e-commerce application. Here's a breakdown of the code:

  1. Imports:
  • React: Importing the React object from "../../Utils/CustomUtils".

  • useProductDataContext, useWishlistContext: Importing custom hooks from "../../Context/AllContextIndex" for accessing context data related to product data and wishlist.

  • Footer, Header, ProductCard, Spinner: Importing components from "../../Components/AllComponentIndex".

  1. Function Definition:
  • function WishlistPage() { ... }: Defines a functional component named WishlistPage.
  1. Context and State Variables:
  • Retrieves context variables using custom context hooks: useWishlistContext and useProductDataContext.

  • Destructures variables like wish and isLoading from the respective contexts.

  1. Component JSX:
  • Renders the header component.

  • Checks if data is loading. If loading, it displays a spinner component (Spinner).

  • If the wishlist is empty (wish.length === 0), it displays a message indicating that there are no items in the wishlist.

  • If the wishlist is not empty, it maps through each item in the wishlist (wish) and renders a ProductCard component for each item.

  1. CSS Styling:
  • Applies CSS styles defined in the "Wishlist.css" file.
  1. Export:
  • export default WishlistPage;: Exports the WishlistPage component as the default export.

In summary, the WishlistPage component renders the contents of the wishlist. If the wishlist is empty, it displays a message. Otherwise, it renders each item in the wishlist using the ProductCard component.

The Wishlist page output is here :

Image description

Checkout page

The checkout page is the page where we place actual details and give the consent to place the order in this project the page allows users to see what they are about to purchase under how much quantity and what the total cost to be paid, add an address to enable payments(testing mode) and then only the order will be placed here is the code.




import React from "react";

import {

Footer,

Header,

Checkout,

Spinner,

} from "../../Components/AllComponentIndex";

import { useProductDataContext } from "../../Context/ProductListingPageContext";



import "./Checkoutpage.css";

function Checkoutpage() {

const { isLoading } = useProductDataContext();

return (

<div>

<Header />

{isLoading ? <Spinner /> : <Checkout />}

<Footer />

</div>

);

}

export default Checkoutpage;



Enter fullscreen mode Exit fullscreen mode

This code defines a React functional component named Checkoutpage, which represents the checkout page of an e-commerce application. Let's break down the code:

  1. Imports:
  • React: Importing the React object from "react".

  • Footer, Header, Checkout, Spinner: Importing components from "../../Components/AllComponentIndex".

  • useProductDataContext: Importing a custom hook from "../../Context/ProductListingPageContext" to access context data related to product listing.

  1. Function Definition:
  • function Checkoutpage() { ... }: Defines a functional component named Checkoutpage.
  1. Context and State Variables:
  • Retrieves context variables using the custom hook useProductDataContext.

  • Destructures the isLoading variable from the context.

  1. Component JSX:
  • Renders the header component.

  • Checks if data is loading. If loading, it displays a spinner component (Spinner).

  • If data is not loading, it renders the checkout component (Checkout).

  • Renders the footer component.

  1. CSS Styling:
  • Applies CSS styles defined in the "Checkoutpage.css" file.
  1. Export:
  • export default Checkoutpage;: Exports the Checkoutpage component as the default export.

In summary, the Checkoutpage component renders the checkout page of the e-commerce application. It first displays the header, then either a spinner or the checkout component based on whether data is loading, and finally the footer.

The Checkout page output is here :

Image description

Order success page

This page shows the order has been placed here is the code.




import React from "react";

import {

Footer,

Header,

OrderConfirm,

Spinner,

} from "../../Components/AllComponentIndex";

import { useProductDataContext } from "../../Context/ProductListingPageContext";



function OrderSuccessPage() {

const { isLoading } = useProductDataContext();

return (

<div>

<Header />

{isLoading ? <Spinner /> : <OrderConfirm />}

<Footer />

</div>

);

}
export default OrderSuccessPage;



Enter fullscreen mode Exit fullscreen mode

This code defines a React functional component named OrderSuccessPage, which represents a page confirming the successful placement of an order. Let's break down the code:

  1. Imports:
  • React: Importing the React object from "react".

  • Footer, Header, OrderConfirm, Spinner: Importing components from "../../Components/AllComponentIndex".

  • useProductDataContext: Importing a custom hook from "../../Context/ProductListingPageContext" to access context data related to the product listing.

  1. Function Definition:
  • function OrderSuccessPage() { ... }: Defines a functional component named OrderSuccessPage.
  1. Context and State Variables:
  • Retrieves context variables using the custom hook useProductDataContext.

  • Destructures the isLoading variable from the context.

  1. Component JSX:
  • Renders the header component.

  • Checks if data is loading. If loading, it displays a spinner component (Spinner).

  • If data is not loading, it renders the order confirmation component (OrderConfirm).

  • Renders the footer component.

  1. Export:
  • export default OrderSuccessPage;: Exports the OrderSuccessPage component as the default export.

In summary, the OrderSuccessPage component renders a page confirming the successful placement of an order. It displays the header, followed by either a spinner or the order confirmation component based on whether data is loading, and finally the footer.

The Order Sucess page output is here :

Image description

Profile manager page

The profile manager page shows the profile data, purchased product details and already added address here is the code




import React from "react";

import {

Footer,

AccountTabs,

Header,

Spinner,

} from "../../Components/AllComponentIndex";

import { useProductDataContext } from "../../Context/ProductListingPageContext";

import "./AccountPage.css";


function AccountPage() {

const { isLoading } = useProductDataContext();

return (

<div>

<Header />

{isLoading ? <Spinner /> : <AccountTabs />}

<Footer />

</div>

);

}

export default AccountPage;



Enter fullscreen mode Exit fullscreen mode

This code defines a React functional component named AccountPage, which represents a page for managing user accounts. Let's break down the code:

  1. Imports:
  • React: Importing the React object from "react".

  • Footer, AccountTabs, Header, Spinner: Importing components from "../../Components/AllComponentIndex".

  • useProductDataContext: Importing a custom hook from "../../Context/ProductListingPageContext" to access context data related to the product listing.

  • ./AccountPage.css: Importing a CSS file for styling this component.

  1. Function Definition:
  • function AccountPage() { ... }: Defines a functional component named AccountPage.
  1. Context and State Variables:
  • Retrieves context variables using the custom hook useProductDataContext.

  • Destructures the isLoading variable from the context.

  1. Component JSX:
  • Renders the header component.

  • Checks if data is loading. If loading, it displays a spinner component (Spinner).

  • If data is not loading, it renders the account tabs component (AccountTabs), which presumably contains different tabs for managing user account information.

  • Renders the footer component.

  1. Export:
  • export default AccountPage;: Exports the AccountPage component as the default export.

In summary, the AccountPage component renders a page for managing user accounts. It displays the header, followed by either a spinner or the account tabs component based on whether data is loading, and finally the footer. The specific functionality of the account tabs is handled by the AccountTabs component.

The Profile Manager page output is here :

Image description

Authentication Pages:

The authentication pages are the most important part of any application as they allow the users to register on the platform and later log into the system with valid credentials.

It also helps to track the registered user data by providing a better user experience.

My application has two authentication pages one is a Signup page and another is a Login page, each page has different input types for user signup they will have to provide their name and email along with all these they also have to make a secure password that can be later used for login.

The Login page only accepts two inputs one is your registered email which you had used for the signup and the same registered password.

You can check both of screen output here :

Login Page

Image description

The Login page also has a Guest Login feature which will take you into the application without registering on the platform.

Signup Page

Image description

Summary

  1. I have followed the clean code architecture as it allows me to display the code in a cleaner way making it easy to understand and maintain.

  2. I Followed the standard folder structure for maintaining and separating the code into smaller chunks.

  3. Complete coding follows the functional programming concept.

  4. I am not a UI/UX guy the intention was to understand the React JS in a better way by building projects so I developed it without focusing much on the UI/UX part.

Thanks for Reading it you can see the complete code on github and can browse the project here

If you have anything to share with me or want me to develop some web app I am always open to opportunities you can connect here on Linkedin

Top comments (0)