Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x | "use client";
import React, { useEffect } from "react";
import { usePathname } from "next/navigation";
import { useCartModalContext } from "@/contexts";
import {
removeItemFromCart,
selectTotalPrice } from "@/redux/features/cartSlice";
import { useAppSelector } from "@/redux/store";
import { useSelector } from "react-redux";
import SingleItem from "./SingleItem";
import Link from "next/link";
import EmptyCart from "./EmptyCart";
import { Icon } from "@/components/ui/icons";
import { Button } from "@/components/ui";
import { formatCurrency } from "@/lib/core";
const CartSidebarModal = () => {
const { isCartModalOpen, closeCartModal } = useCartModalContext();
const cartItems = useAppSelector((state) => state.cartReducer.items);
const pathname = usePathname();
const totalPrice = useSelector(selectTotalPrice);
// Close modal on route change
useEffect(() => {
if (isCartModalOpen) {
closeCartModal();
}
}, [pathname]); // eslint-disable-line react-hooks/exhaustive-deps
useEffect(() => {
// closing modal while clicking outside
function handleClickOutside(event: MouseEvent) {
if (event.target && !(event.target as HTMLElement).closest(".modal-content")) {
closeCartModal();
}
}
if (isCartModalOpen) {
document.addEventListener("mousedown", handleClickOutside);
}
return () => {
document.removeEventListener("mousedown", handleClickOutside);
};
}, [isCartModalOpen, closeCartModal]);
return (
<div
className={`fixed top-0 left-0 z-99999 overflow-y-auto no-scrollbar w-full h-screen bg-dark/70 ease-linear duration-300 ${
isCartModalOpen ? "translate-x-0" : "translate-x-full"
}`}
role="dialog"
aria-modal="true"
aria-label="Shopping cart"
data-testid="cart-sidebar"
>
<div className="flex items-center justify-end">
<div className="w-full max-w-[500px] shadow-1 bg-white dark:bg-gray-800 px-4 sm:px-7.5 lg:px-11 relative modal-content">
<div className="sticky top-0 z-10 bg-white dark:bg-gray-800 flex items-center justify-between pb-7 pt-4 sm:pt-7.5 lg:pt-11 border-b border-gray-3 dark:border-gray-700 mb-7.5">
<h2 className="font-medium text-dark dark:text-gray-100 text-lg sm:text-2xl">
Cart View
</h2>
<Button
onClick={() => closeCartModal()}
aria-label="Close cart"
variant="ghost"
size="sm"
className="flex items-center justify-center ease-in duration-150 bg-meta text-dark-5 dark:text-gray-400 hover:text-dark dark:hover:text-gray-200"
>
<Icon name="x-circle" size={30} />
</Button>
</div>
<div className="h-[66vh] overflow-y-auto no-scrollbar">
<div className="flex flex-col">
{/* <!-- cart item --> */}
{cartItems.length > 0 ? (
cartItems.map((item, key) => (
<SingleItem
key={key}
item={item}
removeItemFromCart={removeItemFromCart}
/>
))
) : (
<EmptyCart />
)}
</div>
</div>
<div className="border-t border-gray-3 dark:border-gray-700 bg-white dark:bg-gray-800 pt-5 pb-4 sm:pb-7.5 lg:pb-11 mt-7.5 sticky bottom-0 z-10">
<div className="flex items-center justify-between gap-5 mb-6">
<p className="font-medium text-xl text-dark dark:text-gray-100">Subtotal:</p>
<p className="font-medium text-xl text-dark dark:text-gray-100">{formatCurrency(totalPrice)}</p>
</div>
<div className="flex items-center gap-4">
<Link
onClick={() => closeCartModal()}
href="/cart"
className="w-full flex justify-center font-medium text-white bg-blue py-[13px] px-6 rounded-md ease-out duration-200 hover:bg-blue-dark"
>
View Cart
</Link>
<Link
onClick={() => closeCartModal()}
href="/checkout"
className="w-full flex justify-center font-medium text-white bg-dark py-[13px] px-6 rounded-md ease-out duration-200 hover:bg-opacity-95"
>
Checkout
</Link>
</div>
</div>
</div>
</div>
</div>
);
};
export default CartSidebarModal;
|