article

Monday, June 12, 2023

React Shopping Cart

React Shoping Cart

React JS
https://create-react-app.dev/

Create Project
C:\react-js>npx create-react-app myreactdev

Run
C:\react-js\myreactdev> npm start

C:\react-js\myreactdev\src\App.js
//C:\react-js\myreactdev\src\App.js
import React, { useState } from "react";
import './App.css';
import Products from "./components/Products";
import Navbar from "./components/navbar";
import Cart from "./components/cart";

const App = () => {
  const [show, setShow] = useState(true);
  const [cart, setCart] = useState([]);

  const handleClick = (item) => {
    if (cart.indexOf(item) !== -1) return;
    setCart([...cart, item]);
  };

  const handleChange = (item, d) => {
    const ind = cart.indexOf(item);
    const arr = cart;
    arr[ind].amount += d;

    if (arr[ind].amount === 0) arr[ind].amount = 1;
    setCart([...arr]);
  };

  return (
    <React.Fragment>
      <Navbar setShow={setShow} size={cart.length} />
      {show ? (
        <Products handleClick={handleClick} />
      ) : (
        <Cart cart={cart} setCart={setCart} handleChange={handleChange} />
      )}
    </React.Fragment>
  );
};

export default App;
C:\react-js\myreactdev\src\components\navbar.js
//C:\react-js\myreactdev\src\components\navbar.js
import React, {  } from "react";

const Navbar = ({ setShow, size }) => {
  return (
    <nav className="navbar navbar-expand-lg navbar-light bg-light">
      <div className="container">
        <a className="navbar-brand" href="#">Cairocoders</a>
        <button className="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
          <span className="navbar-toggler-icon" />
        </button>
        <div className="collapse navbar-collapse" id="navbarSupportedContent">
          <ul className="navbar-nav me-auto mb-2 mb-lg-0">
            <li className="nav-item">
              <a className="nav-link active" aria-current="page" href="#" onClick={() => setShow(true)}>Home</a>
            </li>
            <li className="nav-item">
              <a className="nav-link" href="#">Link</a>
            </li>
          </ul>
          <div className="d-flex">
            <button className="btn btn-outline-primary" type="submit" onClick={() => setShow(false)}>
            <i class="fa fa-shopping-cart" aria-hidden="true"></i> Cart <span class="badge bg-danger">{size}</span>
            </button>
          </div>
        </div>
      </div>
    </nav>

  );
};

export default Navbar;
C:\react-js\myreactdev\src\components\Products.js
//C:\react-js\myreactdev\src\components\Products.js
import React, {  } from "react";
import list from "../data";
import Cards from "./card";

const Products = ({ handleClick }) => {
  return (
    <div className="container productlist">
      <div className="row">
      {list.map((item) => (
        <Cards key={item.id} item={item} handleClick={handleClick} />
      ))}
      </div>
    </div>
  );
};

export default Products;
C:\react-js\myreactdev\src\components\card.js
//C:\react-js\myreactdev\src\components\card.js
import React, {  } from "react";

const Cards = ({ item, handleClick }) => {
  const { title, description, price, img } = item;
  return (
    <div className="col-xs-18 col-sm-6 col-md-4">
    <div className="img_thumbnail product_list">
        <img src={img} alt="" className="img-fluid"/>
        <div className="caption">
            <h4>{title}</h4>
            <p>{description}</p>
            <p><strong>Price: </strong> {price}</p>
            <p className="btn-holder">
              <button onClick={() => handleClick(item)} className="btn btn-primary btn-block text-center">Add to Cart</button>
            </p>
        </div>
    </div>
    </div>
  );
};

export default Cards;
C:\react-js\myreactdev\src\components\cart.js
//C:\react-js\myreactdev\src\components\cart.js
import React, { useState, useEffect } from "react";

const Cart = ({ cart, setCart, handleChange }) => {
  const [price, setPrice] = useState(0);

  const handleRemove = (id) => {
    const arr = cart.filter((item) => item.id !== id);
    setCart(arr);
    handlePrice();
  };

  const handlePrice = () => {
    let ans = 0;
    cart.map((item) => (ans += item.amount * item.price));
    setPrice(ans);
  };

  useEffect(() => {
    handlePrice();
  });

  return (
    <div className="container productlist">
    <table id="cart" className="table table-hover table-condensed">
      <thead>
        <tr>
          <th style={{width: '50%'}}>Product</th>
          <th style={{width: '10%'}}>Price</th>
          <th style={{width: '8%'}}>Quantity</th>
          <th style={{width: '22%'}} className="text-center">Subtotal</th>
          <th style={{width: '10%'}} />
        </tr>
      </thead>
      <tbody>
      {cart.map((item) => (
        <tr key={item.id}>
          <td>
            <div className="row">
              <div className="col-sm-3 hidden-xs"><img src={item.img} width={100} height={100} className="img-responsive" /></div>
              <div className="col-sm-9">
                <h4 className="nomargin">{item.title}</h4>
              </div>
            </div>
          </td>
          <td data-th="Price">$55</td>
          <td data-th="Quantity">
              <button onClick={() => handleChange(item, 1)} className="btn btn-success">+</button>
              <button>{item.amount} className="btn btn-danger"</button>
              <button onClick={() => handleChange(item, -1)} className="btn btn-success">-</button>
          </td>
          <td data-th="Subtotal" className="text-center">${item.price}</td>
          <td className="actions" data-th>
            <button className="btn btn-danger btn-sm cart_remove" onClick={() => handleRemove(item.id)}><i className="fa fa-trash-o" /> Delete</button>
          </td>
        </tr>
        ))}
      </tbody>
      <tfoot>
        <tr>
          <td colSpan={5} style={{textAlign: 'right'}}><h3><strong>Total ${price}</strong></h3></td>
        </tr>
        <tr>
          <td colSpan={5} style={{textAlign: 'right'}}>
            <a href="#" className="btn btn-danger"> <i className="fa fa-arrow-left" /> Continue Shopping</a>
            <button className="btn btn-success" type="submit" id="checkout-live-button"><i className="fa fa-money" /> Checkout</button>
          </td>
        </tr>
      </tfoot>
    </table>
    </div>
  );
};

export default Cart;
C:\react-js\myreactdev\src\data.js
//C:\react-js\myreactdev\src\data.js
const list = [
    {
      id: 1,
      title: "Asus Vivobook 14",
      description: "Asus Vivobook 14 AMD Ryzen 3 3250 8gb/128gb M415DA-R3128 Slate",
      price: 89,
      img: "../images/1.jpg",
      amount: 1,
    },
    {
      id: 2,
      title: "Acer Aspire 5 15.6",
      description: "Acer Aspire 5 15.6 laptop Ryzen 5-5500U 8GB RAM 512GB SSD",
      price: 98,
      img: "../images/2.jpg",
      amount: 1,
    },
    {
      id: 3,
      title: "Lenovo laptop t440",
      description: "Lenovo laptop t440 t450 t460 t470s i5 i7 5th gen 7th gen laptop built in camera",
      price: 143,
      img: "../images/3.jpg",
      amount: 1,
    },
    {
      id: 4,
      title: "HP 3.0 2TB Flash Drive Metal",
      description: "HP 3.0 2TB Flash Drive Metal Waterproof High speed U Disk Flash Drive",
      price: 57,
      img: "../images/4.jpg",
      amount: 1,
    },
    {
      id: 5,
      title: "Desk Mat Laptop Mat Pad Gaming",
      description: "Desk Mat Laptop Mat Pad Gaming Large Mouse Pad Long Mousepad Leatherette Waterproof",
      price: 149,
      img: "../images/5.jpg",
      amount: 1,
    },
    {
      id: 6,
      title: "XIAOMI Original OTG metal pendrive 2TB",
      description: "XIAOMI Original OTG metal pendrive 2TB",
      price: 135,
      img: "../images/6.jpg",
      amount: 1,
    },
    
  ];
  
  export default list;
C:\react-js\myreactdev\src\App.css
//C:\react-js\myreactdev\src\App.css
body {
  background-color: #f6f6f6;
}
.img_thumbnail {
  position: relative;
  padding: 0px;
  margin-bottom: 20px;
}
.img_thumbnail img {
  width: 100%;
}
.img_thumbnail .caption{
  margin: 7px;
  text-align: center;
}
.btn{
  border:0px;
  margin:10px 0px;
  box-shadow:none !important;
}
.productlist { margin-top: 50px;margin-bottom: 50px;}

.total-header-section{
  border-bottom:1px solid #d2d2d2;
}
.total-section p{
  margin-bottom:20px;
}
.cart-detail{
  padding:15px 0px;
}
.cart-detail-img img{
  width:100%;
  height:100%;
  padding-left:15px;
}
.cart-detail-product p{
  margin:0px;
  color:#000;
  font-weight:500;
}
.cart-detail .price{
  font-size:12px;
  margin-right:10px;
  font-weight:500;
}
.cart-detail .count{
  color:#000;
}
.checkout{
  border-top:1px solid #d2d2d2;
  padding-top: 15px;
}
.checkout .btn-primary{
  border-radius:50px;

}
.product_list {
  box-shadow: 0px 10px 30px rgb(0 0 0 / 10%);
  border-radius: 10px;
  height: 100%;padding-top:30px;
  overflow: hidden;
}
react-js\myreactdev\public\index.html
//react-js\myreactdev\public\index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>React App</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css">
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js"></script>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
Run C:\react-j\myreactdev>npm start
http://localhost:3000/

Related Post