gotangible / pages / cart.jsx
cart.jsx
Raw
import React, { useEffect, useState } from "react";
import { useMoralis } from "react-moralis";
import Main from "../templates/Main";
import Image from "next/image";
import Link from "next/link";
import emptyCart from "../public/assets/svg/empty_cart.svg";
import { useShoppingCart } from "use-shopping-cart";
import CartItem from "../components/CartItem";

const DEBUG = false;

const Cart = () => {
  const { isWeb3Enabled, enableWeb3, isAuthenticated, isWeb3EnableLoading } =
    useMoralis();

  const {
    totalPrice,
    redirectToCheckout,
    cartCount,
    formattedTotalPrice,
    cartDetails,
  } = useShoppingCart();

  useEffect(() => {
    const connectorId = window.localStorage.getItem("connectorId");
    if (isAuthenticated && !isWeb3Enabled && !isWeb3EnableLoading)
      enableWeb3({ provider: connectorId });
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [isAuthenticated, isWeb3Enabled]);

  const [isCheckoutLoading, setIsCheckoutLoading] = useState(false);
  const handleCheckout = async () => {
    const response = await fetch("/api/create-session", {
      method: "post",
      headers: {
        "Content-Type": "application/json",
      },
      body: JSON.stringify(cartDetails),
    })
      .then((res) => res.json())
      .catch((error) => console.log(error));

    console.log(response.sessionId);
    redirectToCheckout({ sessionId: response.sessionId });
    setIsCheckoutLoading(false);
  };

  return (
    <Main>
      <div className="container flex items-start justify-center">
        <div className="max-w-6xl">
          {cartCount == 0 ? (
            <div className="mt-24 flex flex-col items-center justify-start">
              <Image src={emptyCart} width={400} height={400} />
              <h3 className="mt-12 mb-2 text-lg font-semibold text-white lg:text-xl">
                Your cart is empty
              </h3>
              <p className="mb-6 text-sm text-zinc-400">
                Items in your cart will appear here once you add them.
              </p>
              <Link href="/">
                <div className="inline-flex cursor-pointer items-center rounded-lg border-2 border-transparent bg-zinc-700 bg-opacity-30 px-5 py-2.5 text-center text-sm font-medium text-white backdrop-blur-lg backdrop-filter hover:border-[#5cd4ac]">
                  Home
                </div>
              </Link>
            </div>
          ) : (
            <div>
              <h1 className="mb-2 text-xl font-bold text-white">
                Cart Details
              </h1>
              <div className="flex flex-row">
                <div className="mr-2 flex w-2/3 flex-col">
                  {Object.keys(cartDetails).map((line_item, index) => {
                    return <CartItem item={cartDetails[line_item]} />;
                  })}

                  {DEBUG ? (
                    <>
                      <h1 className="mb-2 text-xl font-bold text-white">
                        Cart Data
                      </h1>
                      <div className=" flex rounded-2xl border-2 border-transparent bg-zinc-700 bg-opacity-30 p-4 backdrop-blur-lg backdrop-filter">
                        <code className="block overflow-x-scroll whitespace-pre text-xs text-white">
                          {JSON.stringify(cartDetails, null, 2)}
                        </code>
                      </div>
                    </>
                  ) : null}
                </div>
                <div className="ml-2 flex w-1/3 flex-col">
                  <div className="mb-4 flex flex-col rounded-lg bg-zinc-700 bg-opacity-30 p-3 backdrop-blur-lg backdrop-filter">
                    <h2 className="pb-2 text-base font-semibold text-white">
                      Order summary
                    </h2>
                    <div className="flex flex-row justify-between pb-1">
                      <h3 className="text-sm font-semibold text-zinc-100">
                        Subtotal
                      </h3>
                      <h3 className="text-sm font-semibold text-zinc-100">
                        {formattedTotalPrice}
                      </h3>
                    </div>
                    <div className="flex flex-row justify-between pb-3">
                      <h4 className="text-xs text-zinc-300">
                        Shipping and tax calculated at checkout.
                      </h4>
                    </div>
                    <button
                      className="flex w-full cursor-pointer select-none items-center justify-center rounded-lg border-2 border-[#5cd4ac] bg-[#5cd4ac] py-2 hover:border-[#35c897] hover:bg-[#35c897]"
                      onClick={() => {
                        setIsCheckoutLoading(true);
                        handleCheckout();
                      }}
                      disabled={isCheckoutLoading}
                    >
                      {isCheckoutLoading ? (
                        <svg
                          width="20"
                          height="20"
                          viewBox="0 0 38 38"
                          xmlns="http://www.w3.org/2000/svg"
                          stroke="#fff"
                        >
                          <g fill="none" fill-rule="evenodd">
                            <g transform="translate(1 1)" strokeWidth="2">
                              <circle
                                strokeOpacity=".5"
                                cx="18"
                                cy="18"
                                r="18"
                              />
                              <path d="M36 18c0-9.94-8.06-18-18-18">
                                <animateTransform
                                  attributeName="transform"
                                  type="rotate"
                                  from="0 18 18"
                                  to="360 18 18"
                                  dur="1s"
                                  repeatCount="indefinite"
                                />
                              </path>
                            </g>
                          </g>
                        </svg>
                      ) : (
                        <p className="text-sm font-semibold text-white">
                          Checkout
                        </p>
                      )}
                    </button>
                  </div>
                </div>
              </div>
            </div>
          )}
        </div>
      </div>
    </Main>
  );
};

export default Cart;