Skip to content

Instantly share code, notes, and snippets.

@adrianhajdin
Last active April 9, 2024 15:49
Show Gist options
  • Save adrianhajdin/55e019f0ec6a48c0ca6d933d3cf0181c to your computer and use it in GitHub Desktop.
Save adrianhajdin/55e019f0ec6a48c0ca6d933d3cf0181c to your computer and use it in GitHub Desktop.
Build and Deploy a Modern Full Stack ECommerce Application with Stripe
export default {
name: 'banner',
title: 'Banner',
type: 'document',
fields: [
{
name: 'image',
title: 'Image',
type: 'image',
options: {
hotspot: true,
},
},
{
name: 'buttonText',
title: 'ButtonText',
type: 'string',
},
{
name: 'product',
title: 'Product',
type: 'string',
},
{
name: 'desc',
title: 'Desc',
type: 'string',
},
{
name: 'smallText',
title: 'SmallText',
type: 'string',
},
{
name: 'midText',
title: 'MidText',
type: 'string',
},
{
name: 'largeText1',
title: 'LargeText1',
type: 'string',
},
{
name: 'largeText2',
title: 'LargeText2',
type: 'string',
},
{
name: 'discount',
title: 'Discount',
type: 'string',
},
{
name: 'saleTime',
title: 'SaleTime',
type: 'string',
},
],
};
html,
body, * {
padding: 0;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen,
Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
box-sizing: border-box;
}
::-webkit-scrollbar {
width: 0px;
}
a {
color: inherit;
text-decoration: none;
}
.main-container{
max-width: 1400px;
margin: auto;
width: 100%;
}
.layout{
padding: 10px;
}
.navbar-container{
display: flex;
justify-content: space-between;
margin: 6px 18px;
position: relative;
}
.marquee-text{
font-size: 29px;
font-weight: 600;
margin: 60px 0px;
color: #f02d34;
}
.marquee {
position: relative;
height: 400px;
width: 100%;
overflow-x: hidden;
}
.track {
position: absolute;
white-space: nowrap;
will-change: transform;
animation: marquee 15s linear infinite;
width: 180%;
}
.track:hover {
animation-play-state: paused;
}
@keyframes marquee {
from { transform: translateX(0); }
to { transform: translateX(-50%); }
}
span.text-red {
-webkit-text-stroke: 1px #f02d34;
margin-left: 6px;
}
.logo{
color: gray;
font-size: 18px;
}
.cart-icon{
font-size: 25px;
color: gray;
cursor: pointer;
position: relative;
transition: transform .4s ease;
border: none;
background-color: transparent;
}
.cart-icon:hover{
transform: scale(1.1,1.1);
}
.cart-item-qty{
position: absolute;
right: -8px;
font-size: 12px;
color: #eee;
background-color: #f02d34;
width: 18px;
height: 18px;
border-radius: 50%;
text-align: center;
font-weight: 600;
}
.products-container{
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: 15px;
margin-top: 20px;
width: 100%;
}
.product-card{
cursor: pointer;
transform: scale(1, 1);
transition: transform 0.5s ease;
color: #324d67;
}
.product-card:hover{
transform: scale(1.1,1.1)
}
.product-image{
border-radius: 15px;
background-color: #ebebeb;
transform: scale(1, 1);
transition: transform 0.5s ease;
}
.product-name{
font-weight: 500;
}
.product-price{
font-weight: 800;
margin-top: 6px;
color: black;
}
.hero-banner-container{
padding: 100px 40px;
background-color: #dcdcdc;
border-radius: 15px;
position: relative;
height: 500px;
line-height: 0.9;
width: 100%;
}
.hero-banner-container .beats-solo{
font-size: 20px;
}
.hero-banner-container button{
border-radius: 15px;
padding: 10px 16px;
background-color: #f02d34;
color: white;
border: none;
margin-top: 40px;
font-size: 18px;
font-weight: 500;
cursor: pointer;
z-index:10000 !important;
}
.hero-banner-container h3{
font-size: 4rem;
margin-top: 4px;
}
.hero-banner-container h1{
color: white;
font-size: 10em;
margin-left: -20px;
text-transform: uppercase;
}
.hero-banner-image{
position: absolute;
top: 0%;
right:20%;
width: 450px;
height: 450px;
}
.desc{
position: absolute;
right: 10%;
bottom: 5%;
width: 300px;
line-height: 1.3;
display: flex;
flex-direction: column;
color: #324d67;
}
.desc p{
color: #5f5f5f;
font-weight: 100;
text-align: end;
}
.desc h5{
margin-bottom: 12px;
font-weight: 700;
font-size: 16px;
/* color: black; */
align-self: flex-end;
}
.products-heading{
text-align: center;
margin: 40px 0px;
color: #324d67;
}
.products-heading h2{
font-size: 40px;
font-weight: 800;
}
.products-heading p{
font-size: 16px;
font-weight: 200;
}
.footer-banner-container{
padding: 100px 40px;
background-color: #f02d34;
border-radius: 15px;
position: relative;
height: 400px;
line-height: 1;
color: white;
width: 100%;
margin-top: 120px;
}
.banner-desc{
display: flex ;
justify-content: space-between;
}
.banner-desc button{
border-radius: 15px;
padding: 10px 16px;
background-color: white;
color: red;
border: none;
margin-top: 40px;
font-size: 18px;
font-weight: 500;
cursor: pointer;
}
.banner-desc .left h3{
font-weight: 900;
font-size: 80px;
margin-left: 25px;
}
.banner-desc .left p{
margin:18px;
}
.footer-banner-image{
position: absolute;
/* top: -35%;
left: 8%; */
top: -25%;
left: 25%;
}
.banner-desc .right{
line-height: 1.4;
}
.banner-desc .right h3{
font-weight: 800;
font-size: 60px;
}
.banner-desc .right p{
font-size: 18px;
}
.banner-desc .right .company-desc{
font-size: 14px;
font-weight: 300;
}
.cart-wrapper{
width: 100vw;
background: rgba(0, 0, 0, 0.5);
position: fixed;
right: 0;
top: 0;
z-index: 100;
/* will-change: transform; */
transition: all 1s ease-in-out;
}
.cart-container{
height: 100vh;
width: 600px;
background-color: white;
float: right;
padding: 40px 10px;
position: relative;
}
.footer-container{
color: #324d67;
text-align: center;
margin-top: 20px;
padding: 30px 10px;
font-weight: 700;
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
justify-content: center;
}
.footer-container .icons{
font-size: 30px;
display: flex;
gap: 10px;
}
.cart-heading{
display: flex;
align-items: center;
font-size: 18px;
font-weight: 500;
cursor: pointer;
gap: 2px;
margin-left: 10px;
border: none;
background-color: transparent;
}
.cart-heading .heading{
margin-left: 10px;
}
.cart-num-items{
margin-left: 10px;
color: #f02d34;
}
.empty-cart{
margin:40px;
text-align:center;
}
.empty-cart h3{
font-weight: 600;
font-size: 20px;
}
.cancel{
cursor: pointer;
}
.product-container{
margin-top: 15px;
overflow: auto;
max-height: 70vh;
padding: 20px 10px;
}
.product{
display: flex;
gap: 30px;
padding: 20px;
}
.product .cart-product-image{
width:180px ;
height: 150px;
border-radius: 15px;
background-color: #ebebeb;
}
.item-desc .flex{
display: flex;
justify-content: space-between;
width: 350px;
color: #324d67;
}
.item-desc .bottom{
margin-top: 60px;
}
.flex h5{
font-size: 24px;
}
.flex h4{
font-size: 20px;
}
.total{
display: flex;
justify-content: space-between;
}
.total h3{
font-size: 22px;
}
.remove-item{
font-size: 24px;
color: #f02d34;
cursor: pointer;
background: transparent;
border: none;
}
.cart-bottom{
position: absolute;
bottom: 12px;
right: 5px;
width: 100%;
padding: 30px 65px;
}
.btn-container{
width: 400px;
margin: auto;
}
.btn{
width: 100%;
max-width: 400px;
padding: 10px 12px;
border-radius: 15px;
border: none;
font-size: 20px;
margin-top: 10px;
margin-top: 40px;
text-transform: uppercase;
background-color: #f02d34;
color: #fff;
cursor: pointer;
transform: scale(1, 1);
transition: transform 0.5s ease;
}
.btn:hover{
transform: scale(1.1,1.1);
}
.product-detail-container{
display: flex;
gap: 40px;
margin: 40px;
margin-top: 60px;
color: #324d67;
}
.product-detail-image{
border-radius: 15px;
background-color: #ebebeb;
width: 400px;
height: 400px;
cursor: pointer;
transition: .3s ease-in-out;
}
.product-detail-image:hover{
background-color: #f02d34;
}
.small-images-container{
display: flex;
gap: 10px;
margin-top: 20px;
}
.small-image{
border-radius: 8px;
background-color: #ebebeb;
width: 70px;
height: 70px;
cursor: pointer;
}
.selected-image{
background-color:#f02d34;
}
.reviews{
color: #f02d34;
margin-top: 10px;
display: flex;
gap: 5px;
align-items: center;
}
.product-detail-desc h4{
margin-top: 10px;
}
.product-detail-desc p{
margin-top: 10px;
}
.reviews p{
color: #324d67;
margin-top: 0px;
}
.product-detail-desc .price{
font-weight: 700 ;
font-size: 26px;
margin-top: 30px;
color:#f02d34;
}
.price .old-price, .product-price .old-price, .price .old-price{
color: gray;
text-decoration: line-through;
}
.product-detail-desc .quantity{
display: flex;
gap: 20px;
margin-top: 10px ;
align-items: center;
}
.product-detail-desc .buttons{
display: flex;
gap: 30px;
}
.buttons .add-to-cart{
padding: 10px 20px;
border: 1px solid #f02d34 ;
margin-top: 40px;
font-size: 18px;
font-weight: 500;
background-color: white;
color: #f02d34;
cursor: pointer;
width: 200px;
transform: scale(1, 1);
transition: transform 0.5s ease;
}
.buttons .add-to-cart:hover{
transform:scale(1.1,1.1)
}
.buttons .buy-now{
width: 200px;
padding: 10px 20px;
background-color: #f02d34;
color: white;
border: none;
margin-top: 40px;
font-size: 18px;
font-weight: 500;
cursor: pointer;
transform: scale(1, 1);
transition: transform 0.5s ease;
}
.buttons .buy-now:hover{
transform:scale(1.1,1.1)
}
.quantity-desc{
border: 1px solid gray;
padding: 6px;
}
.quantity-desc span{
font-size: 16px;
padding: 6px 12px;
cursor: pointer;
}
.quantity-desc .minus{
border-right: 1px solid gray;
color: #f02d34;
}
.quantity-desc .num{
border-right: 1px solid gray;
font-size: 20px;
}
.quantity-desc .plus{
color: rgb(49, 168, 49);
}
.maylike-products-wrapper{
margin-top: 120px;
}
.maylike-products-wrapper h2{
text-align: center;
margin: 50px;
color: #324d67;
font-size: 28px;
}
.maylike-products-container{
display: flex;
justify-content: center;
gap: 15px;
margin-top: 20px;
}
.max-qty{
font-weight: 500;
color: #f02d34;
}
.success-wrapper, .cancel-wrapper{
background-color: white;
min-height: 60vh;
}
.success, .cancel{
width: 1000px;
margin: auto;
margin-top: 160px;
background-color: #dcdcdc;
padding: 50px;
border-radius: 15px;
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.success .icon {
color: green;
font-size: 40px;
}
.success h2{
text-transform: capitalize;
margin-top: 15px 0px;
font-weight: 900;
font-size: 40px;
color:#324d67;
}
.success .email-msg{
font-size: 16px;
font-weight: 600;
text-align: center;
}
.cancel p{
font-size: 20px;
font-weight: 600;
}
.success .description{
font-size: 16px;
font-weight: 600;
text-align: center;
margin: 10px;
margin-top: 30px;
}
.success .description .email{
margin-left: 5px;
color: #f02d34;
}
.product-max-qty{
margin-top: 10px;
}
@media screen and (max-width:800px) {
.hero-banner-container{
height: 560px;
}
.hero-banner-image{
width: 77%;
height: 62%;
top: -2%;
right: -6%;
}
.footer-banner-container{
height: 560px;
margin-top: 80px;
}
.footer-banner-image{
width: 77%;
left: 30%;
top: 6%;
height: 56%
}
.banner-desc .left h3{
font-weight: 900;
font-size: 50px;
margin-left: 5px;
}
.banner-desc .left p{
margin:18px;
}
.banner-desc .right h3{
font-size: 45px;
}
.banner-desc .right p{
font-size: 18px;
}
.banner-desc .right .company-desc{
font-size: 14px;
}
.banner-desc{
flex-wrap: wrap;
gap: 20px;
}
.hero-banner-container{
line-height: 1.3;
}
.hero-banner-container h1{
font-size: 50px;
}
.hero-banner-container h3{
font-size: 40px;
}
.hero-banner-container button{
margin-top: 90px;
z-index: 10000;
}
.desc{
bottom: 60px;
}
.product-detail-container{
flex-wrap: wrap;
}
.product-detail-container .product-detail-image{
width: 350px;
height: 350px;
}
.cart-container{
width: 415px;
padding: 4px;
}
.cart-heading{
margin-top: 35px;
}
.product-container{
margin-top: 10px;
}
.product{
padding: 20px 5px;
}
.product .cart-product-image{
width: 25%;
height: 25%;
}
.buttons .add-to-cart{
width: 150px;
}
.buttons .buy-now{
width: 150px;
}
.product-detail-container{
margin: 20px;
}
.item-desc .flex{
width: 200px;
}
.top{
flex-wrap: wrap;
gap: 10px;
}
.item-desc .bottom{
margin-top: 30px;
}
.flex h5{
font-size: 16px;
color: #324d67;
}
.flex h4{
font-size: 16px;
color: black;
}
.cart-bottom{
padding: 30px;
}
.total h3{
font-size: 20px;
}
.track {
animation: marquee 10s linear infinite;
width: 550%;
}
.success-wrapper, .cancel-wrapper{
min-height: 69vh;
}
.success, .cancel {
width: 370px;
margin-top: 100px;
padding: 20px;
}
.success{
height: 350px;
}
.success h2{
font-size: 17px;
}
.btn-container{
width: 300px;
margin: auto;
}
}
{
"name": "sanity-ecommerce",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@sanity/client": "^3.2.0",
"@sanity/image-url": "^1.0.1",
"@stripe/stripe-js": "^1.25.0",
"canvas-confetti": "^1.5.1",
"next": "12.1.0",
"next-sanity-image": "^3.2.1",
"react": "17.0.2",
"react-dom": "17.0.2",
"react-hot-toast": "^2.2.0",
"react-icons": "^4.3.1",
"stripe": "^8.209.0"
},
"devDependencies": {
"eslint": "^8.10.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-next": "^12.1.0",
"eslint-plugin-import": "^2.25.4",
"eslint-plugin-jsx-a11y": "^6.5.1",
"eslint-plugin-react": "^7.29.3",
"eslint-plugin-react-hooks": "^4.3.0"
}
}
import React, { createContext, useContext, useState, useEffect } from 'react';
import { toast } from 'react-hot-toast';
const Context = createContext();
export const StateContext = ({ children }) => {
const getLocalStorage = (name) => {
if (typeof window !== 'undefined') {
const storage = localStorage.getItem(name);
if (storage) return JSON.parse(localStorage.getItem(name));
if (name === 'cartItems') return [];
return 0;
}
};
const [showCart, setShowCart] = useState(false);
const [cartItems, setCartItems] = useState(getLocalStorage('cartItems'));
const [totalPrice, setTotalPrice] = useState(getLocalStorage('totalPrice'));
const [totalQuantities, setTotalQuantities] = useState(getLocalStorage('totalQuantities'));
const [qty, setQty] = useState(1);
let findProduct;
let index;
useEffect(() => {
localStorage.setItem('cartItems', JSON.stringify(cartItems));
localStorage.setItem('totalPrice', JSON.stringify(totalPrice));
localStorage.setItem('totalQuantities', JSON.stringify(totalQuantities));
}, [cartItems, totalPrice, totalQuantities]);
const onAdd = (product, quantity) => {
const checkProductInCart = cartItems.find(
(cartProduct) => cartProduct._id === product._id,
);
if (checkProductInCart) {
setTotalPrice(totalPrice + product.price * quantity);
setTotalQuantities(totalQuantities + quantity);
const updatedCartItems = cartItems.map((cartProduct) => {
if (cartProduct._id === product._id) {
return { ...cartProduct, quantity: cartProduct.quantity + quantity };
}
return cartProduct;
});
setCartItems(updatedCartItems);
toast.success(`${qty} ${product.name} added`);
} else {
setTotalPrice(totalPrice + product.price * quantity);
setTotalQuantities(totalQuantities + quantity);
// eslint-disable-next-line no-param-reassign
product.quantity = quantity;
setCartItems([...cartItems, { ...product }]);
toast.success(`${qty} ${product.name} added`);
}
};
const onRemove = (product) => {
findProduct = cartItems.find((item) => item._id === product._id);
const tempCart = cartItems.filter((item) => item._id !== product._id);
setTotalPrice(totalPrice - findProduct.price * findProduct.quantity);
setTotalQuantities(totalQuantities - findProduct.quantity);
setCartItems(tempCart);
};
const toggleCartItemQuantity = (id, value) => {
findProduct = cartItems.find((item) => item._id === id);
index = cartItems.findIndex((product) => product._id === id);
if (value === 'inc') {
findProduct.quantity += 1;
cartItems[index] = findProduct;
setTotalPrice(totalPrice + findProduct.price);
setTotalQuantities(totalQuantities + 1);
}
if (value === 'dec') {
if (findProduct.quantity > 1) {
findProduct.quantity -= 1;
cartItems[index] = findProduct;
setTotalPrice(totalPrice - findProduct.price);
setTotalQuantities(totalQuantities - 1);
}
}
};
const incQty = () => {
setQty((oldQty) => {
const tempQty = oldQty + 1;
return tempQty;
});
};
const decQty = () => {
setQty((oldQty) => {
let tempQty = oldQty - 1;
if (tempQty < 1) {
tempQty = 1;
}
return tempQty;
});
};
return (
<Context.Provider
// eslint-disable-next-line react/jsx-no-constructed-context-values
value={{
onAdd,
onRemove,
cartItems,
totalPrice,
totalQuantities,
setShowCart,
setCartItems,
setTotalPrice,
setTotalQuantities,
showCart,
incQty,
decQty,
qty,
toggleCartItemQuantity,
}}
>
{children}
</Context.Provider>
);
};
export const useStateContext = () => useContext(Context);
@GurajBhoday
Copy link

Module parse failed: Unexpected token (1:7)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders

export type Platform = 'browser' | 'node' | 'neutral';
| export type Format = 'iife' | 'cjs' | 'esm';
| export type Loader = 'base64' | 'binary' | 'copy' | 'css' | 'dataurl' | 'default' | 'empty' | 'file' | 'js' | 'json' | 'jsx' | 'text' | 'ts' | 'tsx';

This is another error I am getting

@StartingFrom101
Copy link

ecommerce-error

having an issue for some reason

try npx create-next-app@12.3.4, version 13 of create-next-app breaks some stuff for me

@HamzaChbit
Copy link

Stripe routing. Next13 : app/api/stripe/route.js. is correct

@FrancoFrancis
Copy link

happy to be back here after a while :)

@zelda999
Copy link

zelda999 commented Sep 15, 2023

Thanks brother,
I change a little for StateContext file

const toggleCartItemQuantity = (id: string, value: string) => {
    foundProduct = cartItems.find((item) => item._id === id);
    index = cartItems.findIndex((product) => product._id === id);
    if (foundProduct && foundProduct.quantity !== undefined) {
      if (value === "inc") {
        foundProduct.quantity += 1;
        cartItems[index] = foundProduct;

        setCartItems([...cartItems]); // set again if use localstorage
        setTotalPrice(totalPrice + foundProduct.price);
        setTotalQuantities(totalQuantities + 1);
      } else if (value === "dec") {
        if (foundProduct.quantity > 1) {
          foundProduct.quantity -= 1;
          cartItems[index] = foundProduct;

          setCartItems([...cartItems]); // set again if use localstorage
          setTotalPrice(totalPrice - foundProduct.price);
          setTotalQuantities(totalQuantities - 1);
        }
      }
    }
  };

I have a problem when using localStorage and I found a way to resolve it. I want to share with everyone, I hope it will help somebody the same me

@FadyAdel04
Copy link

Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading 'length')

({totalQuantities} items)
20 |

21 | {(cartItems.length < 1 )(
| ^
22 |


23 |
24 |

Your shopping bag is empty

help please

@responsive-we
Copy link

responsive-we commented Oct 14, 2023

import React, { useRef } from 'react';
import Link from 'next/link';
import { AiOutlineMinus, AiOutlinePlus, AiOutlineLeft, AiOutlineShopping } from 'react-icons/ai';
import { TiDeleteOutline } from 'react-icons/ti';
import toast from 'react-hot-toast';

import { useStateContext } from '../context/StateContext';
import { urlFor } from '../lib/client';


const Cart = () => {
  const cartRef = useRef();
  const { totalPrice, totalQuantities, cartItems, setShowCart } = useStateContext();

  return (
    <div className="cart-wrapper" ref={cartRef}>
      <div className="cart-container">
        <button
        type="button"
        className="cart-heading"
        onClick={() => setShowCart(false)}>
          <AiOutlineLeft />
          <span className="heading">Your Cart</span>
          <span className="cart-num-items">({totalQuantities} items)</span>
        </button>

        {cartItems.length < 1 && (
          <div className="empty-cart">
            <AiOutlineShopping size={150} />
            <h3>Your shopping bag is empty</h3>
            <Link href="/">
              <button
                type="button"
                onClick={() => setShowCart(false)}
                className="btn"
              >
                Continue Shopping
              </button>
            </Link>
          </div>
        )}

        <div className="product-container">
          {cartItems.length >= 1 && cartItems.map((item) => (
            <div className="product" key={item._id}>
              <img src={urlFor(item?.image[0])} className="cart-product-image" />

            </div>
          ))}
        </div>
      </div>
    </div>
  )
}

export default Cart

I am getting an error saying :"Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading '0')"

Please help me ASAP!!
image

@programmer1402
Copy link

import React, { useRef } from 'react';
import Link from 'next/link';
import { AiOutlineMinus, AiOutlinePlus, AiOutlineLeft, AiOutlineShopping } from 'react-icons/ai';
import { TiDeleteOutline } from 'react-icons/ti';
import toast from 'react-hot-toast';

import { useStateContext } from '../context/StateContext';
import { urlFor } from '../lib/client';


const Cart = () => {
  const cartRef = useRef();
  const { totalPrice, totalQuantities, cartItems, setShowCart } = useStateContext();

  return (
    <div className="cart-wrapper" ref={cartRef}>
      <div className="cart-container">
        <button
        type="button"
        className="cart-heading"
        onClick={() => setShowCart(false)}>
          <AiOutlineLeft />
          <span className="heading">Your Cart</span>
          <span className="cart-num-items">({totalQuantities} items)</span>
        </button>

        {cartItems.length < 1 && (
          <div className="empty-cart">
            <AiOutlineShopping size={150} />
            <h3>Your shopping bag is empty</h3>
            <Link href="/">
              <button
                type="button"
                onClick={() => setShowCart(false)}
                className="btn"
              >
                Continue Shopping
              </button>
            </Link>
          </div>
        )}

        <div className="product-container">
          {cartItems.length >= 1 && cartItems.map((item) => (
            <div className="product" key={item._id}>
              <img src={urlFor(item?.image[0])} className="cart-product-image" />

            </div>
          ))}
        </div>
      </div>
    </div>
  )
}

export default Cart

I am getting an error saying :"Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading '0')"

Please help me ASAP!! image

could you check the cartItems, and it contains array image?

@responsive-we
Copy link

Thank you for your solution. There was some error in StateContext.js file

@Amir-gabr
Copy link

import React, { useRef } from 'react';
import Link from 'next/link';
import { AiOutlineMinus, AiOutlinePlus, AiOutlineLeft, AiOutlineShopping } from 'react-icons/ai';
import { TiDeleteOutline } from 'react-icons/ti';
import toast from 'react-hot-toast';

import { useStateContext } from '../context/StateContext';
import { urlFor } from '../lib/client';

const Cart = () => {
const cartRef = useRef();
const { totalPrice, totalQuantities, cartItems, setShowCart } = useStateContext();

return (



<button
type="button"
className="cart-heading"
onClick={() => setShowCart(false)}>

Your Cart
({totalQuantities} items)

    {cartItems.length < 1 && (
      <div className="empty-cart">
        <AiOutlineShopping size={150} />
        <h3>Your shopping bag is empty</h3>
        <Link href="/">
          <button
            type="button"
            onClick={() => setShowCart(false)}
            className="btn"
          >
            Continue Shopping
          </button>
        </Link>
      </div>
    )}

    <div className="product-container">
      {cartItems.length >= 1 && cartItems.map((item) => (
        <div className="product" key={item._id}>
          <img src={urlFor(item?.image[0])} className="cart-product-image" />

        </div>
      ))}
    </div>
  </div>
</div>

)
}

export default Cart
I am getting an error saying :"Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading '0')"
275152381-5f51063e-ac8a-4963-b03f-4602b6060b65
275152381-5f51063e-ac8a-4963-b03f-4602b6060b65

@responsive-we
Copy link

import React, { useRef } from 'react'; import Link from 'next/link'; import { AiOutlineMinus, AiOutlinePlus, AiOutlineLeft, AiOutlineShopping } from 'react-icons/ai'; import { TiDeleteOutline } from 'react-icons/ti'; import toast from 'react-hot-toast';

import { useStateContext } from '../context/StateContext'; import { urlFor } from '../lib/client';

const Cart = () => { const cartRef = useRef(); const { totalPrice, totalQuantities, cartItems, setShowCart } = useStateContext();

return (

<button
type="button"
className="cart-heading"
onClick={() => setShowCart(false)}>

Your Cart
({totalQuantities} items)

    {cartItems.length < 1 && (
      <div className="empty-cart">
        <AiOutlineShopping size={150} />
        <h3>Your shopping bag is empty</h3>
        <Link href="/">
          <button
            type="button"
            onClick={() => setShowCart(false)}
            className="btn"
          >
            Continue Shopping
          </button>
        </Link>
      </div>
    )}

    <div className="product-container">
      {cartItems.length >= 1 && cartItems.map((item) => (
        <div className="product" key={item._id}>
          <img src={urlFor(item?.image[0])} className="cart-product-image" />

        </div>
      ))}
    </div>
  </div>
</div>

) }

export default Cart I am getting an error saying :"Unhandled Runtime Error TypeError: Cannot read properties of undefined (reading '0')" 275152381-5f51063e-ac8a-4963-b03f-4602b6060b65 275152381-5f51063e-ac8a-4963-b03f-4602b6060b65

You must see the output coming by logging the item param using console.log. And after getting the output you can debug it further or share it in this comment section.

@lambofil
Copy link

lambofil commented Apr 9, 2024

can somebody share all the command for installing all the dependencies.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment