Skip to content

Instantly share code, notes, and snippets.

@emmyjosh
Forked from adrianhajdin/StateContext.js
Created December 29, 2022 11:48
Show Gist options
  • Select an option

  • Save emmyjosh/9b98e685796c7affcb1cc7380c84214f to your computer and use it in GitHub Desktop.

Select an option

Save emmyjosh/9b98e685796c7affcb1cc7380c84214f to your computer and use it in GitHub Desktop.

Revisions

  1. @adrianhajdin adrianhajdin revised this gist Apr 22, 2022. 1 changed file with 763 additions and 0 deletions.
    763 changes: 763 additions & 0 deletions globals.css
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,763 @@
    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;
    }
    }
  2. @adrianhajdin adrianhajdin created this gist Apr 22, 2022.
    134 changes: 134 additions & 0 deletions StateContext.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,134 @@
    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);
    60 changes: 60 additions & 0 deletions banner.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,60 @@
    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',
    },
    ],
    };
    33 changes: 33 additions & 0 deletions package.json
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,33 @@
    {
    "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"
    }
    }