OwlCyberSecurity - MANAGER
Edit File: CheckoutOther.tsx
"use client"; import { activity, userAddressAccess } from "@/redux/features/auth-slice"; import React, { useState, useEffect } from "react"; import { toast } from "sonner"; import { toast as hotToast } from "react-hot-toast"; import { useDispatch, useSelector } from "react-redux"; import ChooseAddressForBasket from "./ChooseAddressForBasket"; import { OtherSelectTotalRial, OtherSelectTotalShipBroker, OtherSelectTotalbuyCost, OtherSelectTotalbuyProfit, OtherSelectItems, OtherSelectTotalPrice, removeAllItemsFromOther, removeFromOtherBasket, updateOtherCount, updateOtherCart, } from "@/redux/features/otherBasketSlice"; import OtherBasketItems from "./foreign-shopping/OtherBasketItems"; import { useRouter } from "next/navigation"; import Link from "next/link"; function CheckoutOther() { const dispatch = useDispatch(); const router = useRouter(); const OtherCart = useSelector(OtherSelectItems); const totalPrice = useSelector(OtherSelectTotalPrice); const totalRial = useSelector(OtherSelectTotalRial); const totalShipBroker = useSelector(OtherSelectTotalShipBroker); const totalBuyCost = useSelector(OtherSelectTotalbuyCost); const totalBuyProfit = useSelector(OtherSelectTotalbuyProfit); const userActivity = useSelector(activity); const userAddress = useSelector(userAddressAccess); const [loadingButton, setLoadingButton] = useState(false); const [countLoading, setCountLoading] = useState(false); const [showAddress, setShowAddress] = useState(false); const [chooseAddress, setChooseAddress] = useState<any>(1); const [descInput, setDescInput] = useState(""); const [discountInput, setDiscountInput] = useState(""); const [showDiscountInput, setShowDiscountInput] = useState(false); const [discountCodeError, setDiscountCodeError] = useState(false); const [discountCheck, setDiscountCheck] = useState(false); function continueOnCheckout() { if (!userActivity) { toast.error("ابتدا وارد شوید"); } else { const prevOtherStateCart = JSON?.parse( // @ts-ignore JSON.parse(localStorage.getItem("persist:root")).otherBasket ).cart; setTimeout(() => { dispatch(updateOtherCart(prevOtherStateCart)); }, 500); setTimeout(() => { setShowAddress(true); }, 1000); } } function sendAmazonBasketToApi() { if (userActivity) { setLoadingButton(true); const token = localStorage.getItem("token"); var myHeaders = new Headers(); myHeaders.append("Accept", "application/json"); myHeaders.append("Authorization", `Bearer ${token}`); var formdata = new FormData(); formdata.append("address_id", chooseAddress); formdata.append("description", descInput); for (let i = 0; i < OtherCart.length; i++) { formdata.append(`cart[${i}][link]`, OtherCart[i].link); formdata.append(`cart[${i}][count]`, OtherCart[i].count); formdata.append(`cart[${i}][weight_unit]`, OtherCart[i].weight_unit); formdata.append(`cart[${i}][firstweight]`, OtherCart[i].firstweight); formdata.append(`cart[${i}][exchange_id]`, OtherCart[i].exchange_id); formdata.append(`cart[${i}][region_id]`, OtherCart[i].region_id); formdata.append(`cart[${i}][image]`, OtherCart[i].image); formdata.append(`cart[${i}][name]`, OtherCart[i].name); formdata.append(`cart[${i}][cost]`, OtherCart[i].cost); formdata.append(`cart[${i}][description]`, OtherCart[i].description); } var requestOptions = { method: "POST", headers: myHeaders, body: formdata, }; fetch(`${process.env.NEXT_PUBLIC_API_ADDRESS}cart-store`, requestOptions) .then((response) => response.json()) .then((result) => { // console.log(result); if (result.status === 200) { // toast.success(result.message); dispatch(removeAllItemsFromOther([])); router.push(`/checkout/${result.data.code}`); } if (result.status === 401) { hotToast.custom((t) => ( <div className={`${ t.visible ? "animate-enter" : "animate-leave" } max-w-md w-full bg-white shadow-lg rounded-lg pointer-events-auto flex ring-1 ring-black ring-opacity-5`} > <div className="flex-1 w-0 p-4"> <div className="flex items-start"> <div className="flex-shrink-0 pt-0.5"> <img className="h-10 w-10 rounded-full" src="/assets/images/icons/logo2.png" alt="" /> </div> <div className="ml-3 flex-1"> <p className="text-sm font-IRANSansBold">کاربر گرامی!</p> <p className="mt-1 text-sm">{result.message}</p> </div> </div> </div> <div className="flex border-l border-gray-200"> <Link href="/dashboard/profile?callbackRoute=checkout" onClick={() => { toast.dismiss(t.id); }} className="text-sm text-[var(--base-blue)] font-IRANSansBold underline ml-4 flex items-center justify-center" > برو به پروفایل </Link> </div> </div> )); } }) .catch((error) => console.log("error", error)) .finally(() => setLoadingButton(false)); } else { toast.error("ابتدا وارد شوید"); } } function calculateCount( link: any, cost: any, weight_unit: any, exchange_id: any, region_id: any, firstweight: any, count: any ) { setCountLoading(true); var myHeaders = new Headers(); myHeaders.append("Accept", "application/json"); var formdata = new FormData(); formdata.append("price", cost); formdata.append("weight_unit", weight_unit); formdata.append("exchange_id", exchange_id); formdata.append("region_id", region_id); formdata.append("weight", firstweight); formdata.append("count", count); var requestOptions = { method: "POST", headers: myHeaders, body: formdata, }; fetch( `${process.env.NEXT_PUBLIC_API_ADDRESS}calculator-show`, requestOptions ) .then((response) => response.json()) .then((result) => { // console.log(result); if (result.status === 200) { dispatch(updateOtherCount({ link, ...result.data.priceRial })); } }) .catch((error) => console.log("error", error)) .finally(() => setCountLoading(false)); } function removeItemFromBasket(link: any) { dispatch(removeFromOtherBasket({ link })); } useEffect(() => { window.scrollTo({ top: 0, left: 0, behavior: "smooth" }); }, [showAddress]); if (OtherCart.length === 0) { return ( <div className="flex flex-col gap-[20px] items-center justify-center m-auto"> <img src="/assets/images/icons/ghost-404.png" alt="" /> <p> سبد سایر فروشگاه های شما خالی می باشد.</p> </div> ); } return ( <div className="flex flex-col md:flex-row bg-white rounded-2xl shadow-lg"> {showAddress ? ( <ChooseAddressForBasket setChooseAddress={setChooseAddress} setShowAddress={setShowAddress} chooseAddress={chooseAddress} amazonCart={OtherCart} descInput={descInput} setDescInput={setDescInput} userAddress={userAddress} checkout="other" setDiscountInput={setDiscountInput} setShowDiscountInput={setShowDiscountInput} setDiscountCodeError={setDiscountCodeError} setDiscountCheck={setDiscountCheck} /> ) : ( <OtherBasketItems OtherCart={OtherCart} calculateCount={calculateCount} removeItemFromBasket={removeItemFromBasket} /> )} <div className="checkout-content-single-payments"> <div className="product-invoice-container"> <div className="product-invoice-content-top"> <div className="flex flex-col gap-[10px] px-2"> <div className="flex items-center justify-between"> <p className="font-IRANSansBold"> قیمت کالا ها <span className="font-IRANSansBold"> {" "} ({OtherCart.length}) </span> </p> <span className="flex items-center gap-7 font-IRANSansBold"> {countLoading ? ( <span className={"dot-loader active"}></span> ) : ( totalRial.toLocaleString() )}{" "} {process.env.price} </span> </div> <div className="flex items-center justify-between text-[14px] text-[var(--text-gray)]"> <p>هزینه حمل</p> <span className="flex items-center gap-7"> {countLoading ? ( <span className={"dot-loader active"}></span> ) : ( totalShipBroker.toLocaleString() )}{" "} {process.env.price} </span> </div> <div className="flex items-center justify-between text-[14px] text-[var(--text-gray)]"> <p>هزینه خرید</p> <span className="flex items-center gap-7"> {countLoading ? ( <span className={"dot-loader active"}></span> ) : ( (totalBuyCost + totalBuyProfit).toLocaleString() )}{" "} {process.env.price} </span> </div> </div> </div> <div className="product-invoice-content-bottom"> <div className="flex flex-col gap-[10px] px-2"> <div className="flex items-center justify-between"> <p className="text-[var(--text-gray)]">قیمت کل به دلار</p> <span className="font-IRANSansBold"> {totalPrice.toFixed(2)}{" "} <span className="text-[13px] font-IRANSansBold">$</span> </span> </div> {showAddress ? ( <button onClick={sendAmazonBasketToApi} className="add-checkout-button" disabled={!chooseAddress || loadingButton} > {loadingButton ? ( <span className={ loadingButton ? "button-loader-white active" : "button-loader-white" } ></span> ) : null} <p> ثبت و نهایی کردن سفارش</p> </button> ) : ( <button onClick={continueOnCheckout} className="add-checkout-button" > <p>ادامه ثبت سفارش</p> </button> )} <div className="flex flex-col gap-2 border border-[var(--light-blue)] p-3 rounded-[8px] bg-[#EFF9FF]"> <div className="flex items-center gap-[5px] text-[14px]"> <svg width="21" height="20" viewBox="0 0 21 20" fill="none" xmlns="http://www.w3.org/2000/svg" > <g clipPath="url(#clip0_1129_22009)"> <path d="M16.3333 4.16634H14.5833C14.3899 3.22585 13.8782 2.3808 13.1344 1.77361C12.3906 1.16642 11.4602 0.83422 10.5 0.833008H4.66667C3.562 0.834331 2.50296 1.27374 1.72185 2.05486C0.940735 2.83597 0.501323 3.89501 0.5 4.99967L0.5 12.4997C0.502095 13.246 0.754615 13.9701 1.21711 14.5559C1.67961 15.1417 2.32533 15.5553 3.05083 15.7305C2.9723 16.1476 2.98572 16.5767 3.09016 16.988C3.19459 17.3993 3.38753 17.7829 3.6555 18.112C3.92347 18.441 4.26001 18.7077 4.64166 18.8932C5.0233 19.0788 5.44084 19.1789 5.86514 19.1864C6.28944 19.194 6.71029 19.1089 7.0983 18.937C7.48631 18.7652 7.83215 18.5107 8.11168 18.1914C8.3912 17.8721 8.59768 17.4957 8.71671 17.0883C8.83574 16.681 8.86445 16.2526 8.80083 15.833H12.2025C12.1811 15.9709 12.1696 16.1101 12.1683 16.2497C12.1683 17.0232 12.4756 17.7651 13.0226 18.3121C13.5696 18.8591 14.3115 19.1663 15.085 19.1663C15.8585 19.1663 16.6004 18.8591 17.1474 18.3121C17.6944 17.7651 18.0017 17.0232 18.0017 16.2497C18.0007 16.0754 17.9837 15.9016 17.9508 15.7305C18.676 15.555 19.3214 15.1412 19.7835 14.5555C20.2457 13.9697 20.498 13.2458 20.5 12.4997V8.33301C20.4987 7.22835 20.0593 6.16931 19.2782 5.38819C18.497 4.60708 17.438 4.16766 16.3333 4.16634ZM18.8333 8.33301V9.16634H14.6667V5.83301H16.3333C16.9964 5.83301 17.6323 6.0964 18.1011 6.56524C18.5699 7.03408 18.8333 7.66997 18.8333 8.33301ZM2.16667 12.4997V4.99967C2.16667 4.33663 2.43006 3.70075 2.8989 3.23191C3.36774 2.76307 4.00363 2.49967 4.66667 2.49967H10.5C11.163 2.49967 11.7989 2.76307 12.2678 3.23191C12.7366 3.70075 13 4.33663 13 4.99967V14.1663H3.83333C3.39131 14.1663 2.96738 13.9907 2.65482 13.6782C2.34226 13.3656 2.16667 12.9417 2.16667 12.4997ZM7.16667 16.2497C7.16667 16.5812 7.03497 16.8991 6.80055 17.1336C6.56613 17.368 6.24819 17.4997 5.91667 17.4997C5.58515 17.4997 5.2672 17.368 5.03278 17.1336C4.79836 16.8991 4.66667 16.5812 4.66667 16.2497C4.66718 16.1073 4.69343 15.9661 4.74417 15.833H7.08917C7.1399 15.9661 7.16615 16.1073 7.16667 16.2497ZM15.0833 17.4997C14.7518 17.4997 14.4339 17.368 14.1995 17.1336C13.965 16.8991 13.8333 16.5812 13.8333 16.2497C13.8337 16.1072 13.86 15.9661 13.9108 15.833H16.2558C16.3067 15.9661 16.333 16.1072 16.3333 16.2497C16.3333 16.5812 16.2016 16.8991 15.9672 17.1336C15.7328 17.368 15.4149 17.4997 15.0833 17.4997ZM17.1667 14.1663H14.6667V10.833H18.8333V12.4997C18.8333 12.9417 18.6577 13.3656 18.3452 13.6782C18.0326 13.9907 17.6087 14.1663 17.1667 14.1663Z" fill="#2FA9FF" /> </g> <defs> <clipPath id="clip0_1129_22009"> <rect width="20" height="20" fill="white" transform="translate(0.5)" /> </clipPath> </defs> </svg> <p className="font-IRANSansBold">ارسال رایگان</p> </div> <p className="text-[14px]"> هزینه ارسال داخل ایران در چارسوق رایگان میباشد </p> </div> </div> </div> </div> </div> </div> ); } export default CheckoutOther;