You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

293 lines
11 KiB

import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { toast } from "react-toastify";
import { book, userProduct, publicApi, dialog } from "../../redux/actions";
import { Link, useNavigate } from "react-router-dom";
import proxy from "../../redux/proxy";
import location from "../../utils/location";
import separate from "../../utils/separate";
//components
import Button from "../../components/Button";
import Header from "../../components/Header";
import Comment from "./Comment";
import Rate from "./Rate";
import DesktopProductLayout from "./Desktop";
import Loading from "../../components/Loading";
import ButtonBetween from "../../components/ButtonBetween";
//assets
import arrow from "../../assets/icons/dropdown-blue.svg";
export const Product = ({
isMobile,
productType,
userProducts,
getInfo,
book,
grades,
isDark,
userId,
pushToCart,
headerOptions,
userProductLoading,
setHeaderOptions,
availableForSell,
setDialog,
}) => {
const [whichTypeAdded, setWhichTypeAdded] = React.useState(null);
const [desktopContentTransform, setDesktopContentTransform] = useState(false);
const navigation = useNavigate();
const physicalAvailableForSell = React.useMemo(() => {
return availableForSell?.find((product) => product === 2);
}, [availableForSell]);
const digitalAvailableForSell = React.useMemo(() => {
return availableForSell?.find((product) => product === 1);
}, [availableForSell]);
const videoAvailableForSell = React.useMemo(() => {
return availableForSell?.find((product) => product === 4);
}, [availableForSell]);
const physicalProduct = React.useMemo(() => {
return book?.product?.find((product) => product?.productType === 2);
}, [book]);
const digitalProduct = React.useMemo(() => {
return book?.product?.find((product) => product?.productType === 1);
}, [book]);
const videoProduct = React.useMemo(() => {
return book?.product?.find((product) => product?.productType === 4);
}, [book]);
const physicalAvailabileInCart = React.useMemo(() => {
return userProducts?.find(
(product) =>
product?.productId === physicalProduct?.id && product?.condition < 2
);
}, [userProducts, book]);
const digitalAvailabileInCart = React.useMemo(() => {
return userProducts?.find(
(product) =>
product?.productId === digitalProduct?.id && product?.condition < 2
);
}, [userProducts, book]);
const videoAvailabileInCart = React.useMemo(() => {
return userProducts?.find(
(product) =>
product?.productId === videoProduct?.id && product?.condition < 2
);
}, [userProducts, book]);
useEffect(() => {
if(!isMobile){
setHeaderOptions(headerOptions);
}
getInfo({ id: location.getId(), vod: true });
if (!isMobile) {
window.addEventListener("scroll", () => {
if (window.scrollY >= 64) {
setDesktopContentTransform(() => true);
} else {
setDesktopContentTransform(() => false);
}
});
}
}, []);
useEffect(() => {
if (!userProductLoading) {
setWhichTypeAdded(null);
}
}, [userProductLoading]);
useEffect(() => {
if (book && isMobile) {
setHeaderOptions({ ...headerOptions, productId: book?.id });
window.scroll({ top: 0, behavior: "smooth" });
}
}, [book]);
return (
<>
{/* Portrait */}
{isMobile ? (
<div className="w-full flex flex-col bg-transparent px-4 pb-24">
{!book && (
<div className="w-full h-screen flex justify-center items-center bg-white bg-opacity-20 backdrop-filter backdrop-blur-xl fixed left-0 top-0 z-50">
<Loading size={4} color="bg-green-400" />
</div>
)}
<header
className={`w-full flex ${
productType === "book" ? "flex-row" : "flex-col"
}`}
>
<img
src={`https://dnvn.ir/api/v1/file/${book?.fileIds}`}
alt=""
className="w-5/12 rounded-sm object-contain"
/>
<div className="flex flex-1 flex-col pr-2 pt-2">
<h1 className="text-blue5F mb-3 font-semibold text-base dark:text-white">
{book?.name}
</h1>
<div className="text-green7B text-tiny dark:text-greenBA">
{window.t("پایه") + " " + grades[book?.gradeId]}
</div>
</div>
</header>
<ul
className="list-none flex divide-x items-center mt-5"
style={{ direction: "ltr" }}
>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white">
{book?.pagesNum} <br /> {window.t("صفحه")}
</li>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white">
{window.t("فیزیکی - دیجیتالی")}
<br /> {window.t("در دسترس")}
</li>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white">
{book?.rate} <br />
{window.t("امتیاز")}
</li>
{book?.rate ? (
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white">
{book?.rate} <br /> امتیاز
</li>
) : null}
</ul>
<h2 className="text-green7B text-base font-semibold mt-10 dark:text-greenBA">
{window.t("نسخه محصول را انتخاب کنید")}
</h2>
<div className="w-full flex flex-row justify-between items-center mt-5">
<ButtonBetween
width="100%"
item={window.t("خرید نسخه فیزیکی کتاب")}
status={
separate(book?.product[1]?.price) + " " + window.t("تومان")
}
onClick={() =>
userId
? pushToCart({
productId: book?.product[1]?.id,
userId,
count: 1,
})
: toast.info(window.t("ابتدا وارد حساب کاربری خود شوید"))
}
/>
</div>
<div className="w-full flex flex-row justify-between items-center mt-4 gap-2">
<ButtonBetween
width="72%"
item={window.t("خرید نسخه دیجیتال کتاب")}
status={
separate(book?.product[0]?.price) + " " + window.t("تومان")
}
onClick={() =>
userId
? pushToCart({
productId: book?.product[0]?.id,
userId,
count: 1,
})
: toast.info(window.t("ابتدا وارد حساب کاربری خود شوید."))
}
/>
<a
href={`https://dnvn.ir/xpdf/${book?.sampleFileId}`}
className="flex-1 border-2 border-solid text-sm border-green-500 bg-green-50 bg-opacity-70 rounded-sm font-bold text-green-700 text-center"
style={{ padding: "18px 0px" }}
>
{window.t("مشاهده نمونه")}
</a>
</div>
<div className="w-full flex flex-row justify-between items-center mt-4">
<ButtonBetween
width="72%"
item={window.t("خرید نسخه ویدئویی کتاب")}
status={
separate(book?.product[2]?.price) + " " + window.t("تومان")
}
onClick={() =>
userId
? pushToCart({
productId: book?.product[2]?.id,
userId,
count: 1,
})
: toast.info(window.t("ابتدا وارد حساب کاربری خود شوید."))
}
/>
<ButtonBetween
width="25%"
item={window.t("پیش نمایش")}
onClick={() => navigation("/videos/" + book?.id)}
/>
</div>
<div className="w-full flex flex-col justify-between items-center mt-8">
<Header title={window.t("توضیحات")} link="#" />
<p className="text-sm text-gray70 mt-2 dark:text-white leading-6">
خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ
ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ
ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ
ﻫﺮﮔﺰ ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﺍﺩﺍﻣﻪ ﺩﺍﺩ :
ﺩﺭ ﺯﻧﺪﮔﯽ ﺩﺭﻭﻍ ﻧﮕﻮ ﭼﺮﺍ ﮐﻪ ﺍﮔﺮ ﮔﻔﺘﯽ ﺻﺪﺍﻗﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺧﯿﺎﻧﺖ ﻧﮑﻦ ﮐﻪ
ﺍﮔﺮ ﮐﺮﺩﯼ ﻋﺸﻖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺧﺸﻮﻧﺖ ﻧﮑﻦ ﺍﮔﺮ ﮐﺮﺩﯼ ﻣﺤﺒﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ،
ﻧﺎ ﺣﻖ ﻧﮕﻮ ﺍﮔﺮ ﮔﻔﺘﯽ ﺣﻖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺑﯽ ﺣﯿﺎﯾﯽ ﻧﮑﻦ ﺍﮔﺮ ﮐﺮﺩﯼ ﺷﺮﺍﻓﺖ ﺭﺍ
ﺩﺯﺩﯾﺪﻩ ﺍی... ﭘﺲ ﺩﺭ ﺯﻧﺪﮔﯽ ﻓﻘﻂ ﺩﺯﺩﯼ نکن
</p>
</div>
<div className="w-full flex flex-col justify-between items-center mt-10">
<Header title={window.t("امتیازات و نظرات")} link="#" />
<Rate value={book?.rate || 0} />
</div>
<div
className="flex w-full pb-4 mt-10 no-scrollbar"
style={{ overflowX: "scroll" }}
>
{book?.comment?.map((comment, index) => (
<Comment comment={comment} key={index} />
))}
</div>
</div>
) : (
<div className="flex flex-col items-center justify-center lg:py-24">
<DesktopProductLayout physicalProduct={physicalProduct} rate={book?.rate || 0} />
</div>
)}
</>
);
};
const mapStateToProps = (state) => ({
book: state.book.info,
grades: state.publicApi.grades,
isMobile: state.publicApi.isMobile,
isDark: state.publicApi.isDark,
userId: state.user.status?.id,
bookmarkLoading: state.userFavorite.loading,
availableForSell: state.config.availableForSell,
userProduct: state.userProduct.list,
userProductLoading: state.userProduct.loading,
});
const mapDispatchToProps = {
getInfo: book.info,
pushToCart: userProduct.add,
setHeaderOptions: publicApi.setHeaderOptions,
setDialog: dialog.set,
};
export default connect(mapStateToProps, mapDispatchToProps)(Product);
Product.defaultProps = {
productType: "book",
};