reza fixed buy way

temp
Reza_ashrafi 3 years ago
parent 83415ba2d9
commit b50071f0f2
  1. 6
      src/components/JolPlayer/index.js
  2. 2
      src/components/Navbar/index.js
  3. 11
      src/components/Product/index.js
  4. 102
      src/components/ProductImage/index.js
  5. 39
      src/components/ProductStatusCard/index.js
  6. 4
      src/components/ProductTab/index.js
  7. 8
      src/views/Home/Desktop/Part2/index.js
  8. 2
      src/views/Home/Desktop/Part4/index.js
  9. 4
      src/views/Home/Desktop/SalesContainer/index.js
  10. 2
      src/views/Home/Portrait/Private/Videos/index.js
  11. 49
      src/views/Product/Desktop/ProductOverAll/index.js
  12. 281
      src/views/Product/index.js
  13. 13
      src/views/ShoppingCart/Product/index.js
  14. 6
      src/views/ShoppingCart/index.js
  15. 40
      src/views/Video/components/Desktop/Videos.js
  16. 55
      src/views/Video/index.js
  17. 21
      src/views/Videos/components/MostViewedVideo.js
  18. 46
      src/views/Videos/components/NewestVideo.js
  19. 15
      src/views/Videos/index.js

@ -4,7 +4,6 @@ import JoLPlayer from "jol-player";
function Video({ fileIds, posterId, autoPlay }) {
const videoRef = useRef(null);
return (
<div
style={{
@ -20,7 +19,10 @@ function Video({ fileIds, posterId, autoPlay }) {
option={{
videoSrc: `https://dnvn.ir/api/v1/file/${fileIds}`,
width: "100%",
height: window.innerWidth > 1024 ? window.innerHeight - 200 : window.innerHeight / 3.6,
height:
window.innerWidth > 1024
? window.innerHeight - 200
: window.innerHeight / 3.6,
theme: "#4dd35b",
language: "en",
isShowMultiple: window.innerWidth > 700,

@ -322,7 +322,7 @@ const mapStateToProps = (state) => ({
isMobile: state.publicApi.isMobile,
headerOptions: state.publicApi.headerOptions,
isLogin: state.user.status,
cartProductsLength: state.userProduct.list?.length,
cartProductsLength: state.userProduct.list?.filter((product) => product.condition < 2)?.length,
});
const mapDispatchToProps = {

@ -1,4 +1,5 @@
import React, { useState } from "react";
import {Link} from 'react-router-dom';
import { connect } from "react-redux";
import StarRating from "../StarRating";
@ -50,7 +51,7 @@ const ProductDesign = ({
}) => {
const [isHovering, setIsHovering] = useState(false);
return (
<div
<Link to={'/products/' + product.id}
className={`flex flex-wrap sm:flex-nowrap justify-around`}
style={{ direction: "rtl" }}
>
@ -105,7 +106,7 @@ const ProductDesign = ({
<div className="px-2">
<div className="mt-4">
<h2
className={`leading-5 text-base 2xl:text-tiny font-normal py-2 text-right ${productTitleColor}`}
className={`leading-5 text-tiny font-normal py-2 text-right text-blue5F`}
>
{product?.product[1]?.name}
</h2>
@ -119,7 +120,7 @@ const ProductDesign = ({
)}
{productCat && (
<span
className={`text-sm py-1 font-normal ${productCatTextColor}`}
className={`text-sm py-1 font-normal text-blueC0`}
>
{"پایه" + " " + grades[product.gradeId]}
</span>
@ -128,7 +129,7 @@ const ProductDesign = ({
{/* star */}
{star && (
<div className="flex items-center mt-3">
<StarRating value={starRate} />
<StarRating value={starRate || 4} />
{/* <span className="text-xs text-productContent font-bold text-gray-500 mr-2">
بر اساس {numberOfRegards} بررسی
</span> */}
@ -203,7 +204,7 @@ const ProductDesign = ({
</div>
</div>
</div>
</div>
</Link>
);
};

@ -1,36 +1,70 @@
import React from "react";
import React, { useState, useEffect } from "react";
import "./index.scss";
import productImg from "./product-image.jpg";
const ProductImage = ({ images }) => {
const [list, setList] = useState([]);
const [activeImage, setActiveImage] = useState(null);
// console.log(images.length);
useEffect(() => {
if (images) {
let mylist = images?.split(",");
setList(() => mylist);
setActiveImage(() => mylist[0]);
console.log(images);
}
}, [images]);
return (
<div className="flex flex-row w-1/3 gap-2">
<div className="flex flex-col items-center justify-between w-1/5" style={{height : 'calc(100vw / 5)'}}>
{images.slice(0, 4).map((image, index) => (
<div className="relative" style={{ width : "calc(100vw / 5 / 4 - 4px)", height : "calc(100vw / 5 / 4 - 4px)"}}>
<img
key={index}
src={productImg}
alt=""
className={`rounded-sm w-full h-full`}
// style={{ height: "calc(100% - 8px)" }}
// style={{ height: "calc(100% - 8px)" }}
/>
{/* این خط پایین که نوشتم برای این است که ایندکس که جنسش استرینگ است رو به نامبر تبدیل کند */}
{Number(index) === 3 && (
<div className="absolute w-full h-full bg-black bg-opacity-30 left-0 top-0 flex justify-center items-center text-white">
<strong>+ {images.length - 3}</strong>
</div>
)}
</div>
))}
</div>
<img src={productImg} alt="" style={{ height : "calc(100vw / 5)", width : "calc(100vw / 5)"}} />
<div className="flex flex-row w-1/3 gap-2">
<div
className="flex flex-col items-center justify-between w-1/5"
style={{ height: "calc(100vw / 5)" }}
>
{list?.slice(0, 4)?.map((image, index) => (
<div
className={`relative flex justify-center items-center ${ activeImage === image ? 'bg-green-200' : 'bg-gray-200'}`}
style={{
width: "calc(100vw / 5 / 4 - 4px)",
height: "calc(100vw / 5 / 4 - 4px)",
}}
onClick={() => setActiveImage(image)}
>
<img
key={index}
src={`https://dnvn.ir/api/v1/file/${image}`}
alt=""
className={`rounded-sm w-full h-full`}
style={{
width: "calc(100vw / 5 / 4 * 2 / 3 - 12px)",
height: "calc(100vw / 5 / 4 - 12px)",
}}
// style={{ height: "calc(100% - 8px)" }}
/>
{/* این خط پایین که نوشتم برای این است که ایندکس که جنسش استرینگ است رو به نامبر تبدیل کند */}
{Number(index) === 3 && (
<div className="absolute w-full h-full bg-black bg-opacity-30 left-0 top-0 flex justify-center items-center text-white">
<strong>+ {images.length - 3}</strong>
</div>
)}
</div>
))}
</div>
<div
className="rounded-md bg-gray-200 flex justify-center items-center"
style={{ height: "calc(100vw / 5)", width: "calc(100vw / 5)" }}
>
<img
src={`https://dnvn.ir/api/v1/file/${activeImage}`}
alt=""
style={{
height: "calc(100vw / 5.5)",
width: "calc(100vw / 5.5 * 2 / 3)",
}}
/>
</div>
</div>
);
};
// {[0, 1, 2, 3, 4].map((item, index) => (
@ -38,23 +72,3 @@ const ProductImage = ({ images }) => {
// ))}
export default ProductImage;
ProductImage.defaultProps = {
images: [
{
image: productImg,
},
{
image: productImg,
},
{
image: productImg,
},
{
image: productImg,
},
{
image: productImg,
},
],
};

@ -1,5 +1,7 @@
import React from "react";
import {connect} from 'react-redux';
import { connect } from "react-redux";
import { userProduct } from "../../redux/actions";
import { toast } from "react-toastify";
import Button from "../Button";
import arrow from "./arrow-icon.svg";
@ -10,7 +12,16 @@ import shield from "./shield-tick.svg";
import tick from "./tick-circle.svg";
import shop from "./icon-shop.svg";
const ProductStatusCard = ({ items, productPrice, discountPrice, isDark }) => {
const ProductStatusCard = ({
items,
price,
discountPrice,
isDark,
id,
userId,
isLogin,
pushToCart,
}) => {
return (
<section className="w-full">
<div className="bg-grayF9 rounded-md px-4 py-2 divide-y divide-solid divide-gray-200">
@ -41,7 +52,7 @@ const ProductStatusCard = ({ items, productPrice, discountPrice, isDark }) => {
))}
<div className="flex flex-col items-center py-3">
<p className="text-xl text-blue-600">
{productPrice}
{price}
<span className="text-sm text-gray-700 font-light">تومان</span>
</p>
<p className="text-xs font-light text-gray-600 mt-2">
@ -51,13 +62,21 @@ const ProductStatusCard = ({ items, productPrice, discountPrice, isDark }) => {
</p>
</div>
<Button
title=صافه کردن به سبد خرید"
title=ضافه کردن به سبد خرید"
backgroundColor={isDark ? "bg-blueC0" : "bg-blueC0"}
border={{ color: isDark ? "#ffffff55" : "#196EC055", width: "1px" }}
width="100%"
color={"text-white"}
selectable={true}
onClick={() => {}}
onClick={() =>
isLogin
? pushToCart({
productId: id,
userId: userId,
count: 1,
})
: toast.info("ابتدا وارد حساب کاربری خود شوید.")
}
/>
</div>
<div className="bg-grayF9 rounded px-4 py-2 mt-4 flex flex-row items-center">
@ -80,9 +99,15 @@ const ProductStatusCard = ({ items, productPrice, discountPrice, isDark }) => {
const mapStateToProps = (state) => ({
isDark: state.publicApi.isDark,
})
isLogin: state.user.status,
userId: state.user.status.id,
});
export default connect(mapStateToProps)(ProductStatusCard);
const mapDispatchToProps = {
pushToCart: userProduct.add,
};
export default connect(mapStateToProps, mapDispatchToProps)(ProductStatusCard);
ProductStatusCard.defaultProps = {
items: [

@ -2,7 +2,7 @@ import React, { useState } from "react";
import Table from "./table";
const ProductTab = ({ tabs }) => {
const [selectedTab, setSelectedTab] = useState(tabs[0]);
const [selectedTab, setSelectedTab] = useState(tabs[1]);
return (
<section className="mt-10 flex flex-col w-full">
@ -11,7 +11,7 @@ const ProductTab = ({ tabs }) => {
{tabs.map((tab, index) => (
<li
className={`text-sm cursor-pointer hover:text-blue-400 py-4 transition-all duration-500 ${
selectedTab === tab ? "text-blue-600 border-b-4 border-solid border-blueC0" : "border-b-4 border-solid border-transparent"
selectedTab?.title === tab?.title ? "text-blue-600 border-b-4 border-solid border-blueC0" : "border-b-4 border-solid border-transparent"
}`}
onClick={() => setSelectedTab(tab)}
key={index}

@ -24,10 +24,10 @@ const Part2 = ({ books, grades }) => {
}
}
>
<div className="w-full flex justify-between items-center">
<div className="w-full flex justify-between items-center mb-4">
<div className="flex items-center text-4xl font-black text-blue52">
<div className="w-6 h-6 bg-blue-300 ml-4 rounded-full"></div>
<h1>کتاب های جدید</h1>
<h1 className="text-2xl text-blue5F">کتاب های جدید</h1>
</div>
<div>
<Link to="/products">
@ -58,14 +58,14 @@ const Part2 = ({ books, grades }) => {
transition={0.5}
rightArrow={
<img
className="absolute top-1/2 transform -translate-y-1/2 cursor-pointer p-5"
className="absolute top-1/2 transform -translate-y-1/2 cursor-pointer p-2"
src={arrow}
alt=""
/>
}
leftArrow={
<img
className="absolute top-1/2 transform -translate-y-1/2 -translate-x-5 cursor-pointer -rotate-180 p-5"
className="absolute top-1/2 transform -translate-y-1/2 -translate-x-5 cursor-pointer -rotate-180 p-2"
src={arrow}
alt=""
/>

@ -60,7 +60,7 @@ const Part4 = () => {
<div className="w-full flex justify-between items-center">
<div className="flex items-center text-4xl font-black text-blue52">
<div className="w-6 h-6 bg-blue-300 ml-4 rounded-full"></div>
<h1>جدیدترین دوره های ویدیویی</h1>
<h1 className="text-2xl text-blue5F">جدیدترین دوره های ویدیویی</h1>
</div>
<div>
<Link to="/products">

@ -47,7 +47,7 @@ const SalesContainer = ({ books }) => {
transition={0.5}
rightArrow={
<img
className="absolute top-1/2 transform -translate-y-1/2 cursor-pointer p-5"
className="absolute top-1/2 transform -translate-y-1/2 cursor-pointer p-2"
src={arrow}
alt=""
// onClick={(e) => e.stopPropagation()}
@ -55,7 +55,7 @@ const SalesContainer = ({ books }) => {
}
leftArrow={
<img
className="absolute top-1/2 transform -translate-y-1/2 -translate-x-5 cursor-pointer -rotate-180 p-5"
className="absolute top-1/2 transform -translate-y-1/2 -translate-x-5 cursor-pointer -rotate-180 p-2"
src={arrow}
alt=""
// onClick={(e) => e.stopPropagation()}

@ -14,7 +14,7 @@ function Videos({ list, getList, grades, isDark, isMobile }) {
const Book = ({ book }) => {
return (
<li className="flex flex-col">
<Link to={"/products/" + book.name}>
<Link to={"/products/" + book.id}>
<img
src={`https://dnvn.ir/api/v1/file/${book.fileIds}`}
alt=""

@ -1,5 +1,6 @@
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
import { toast } from "react-toastify";
import { book, userProduct, publicApi } from "../../../../redux/actions";
import proxy from "../../../../redux/proxy";
@ -27,24 +28,22 @@ export const ProductOverAll = ({
headerOptions,
setHeaderOptions,
}) => {
const [type, setType] = useState("physical");
const [type, setType] = useState("1");
return (
<div className="w-full">
<header className={`w-full flex flex-row justify-between gap-5`}>
<ProductImages />
<ProductImages images={book?.fileIds} />
<div className="flex flex-col w-1/2 divide-y divide-solid divide-gray-200">
<div className="w-full flex flex-col pr-2 py-2 border-0">
<h1 className="text-blue5F mb-3 font-semibold text-xl dark:text-white">
{type === "digital"
? book?.product[0]?.name
: book?.product[1]?.name}
<h1 className="text-blue5F mb-3 font-semibold text-lg dark:text-white">
{book?.product[type]?.name}
</h1>
<div className="text-blueC0 text-xs dark:text-greenBA">
<div className="text-blueC0 text-tiny dark:text-greenBA">
{"پایه" + " " + grades[book?.gradeId]}
</div>
<div className="flex justify-end">
<div className="flex justify-end items-center">
<div className="p-2">
<StarRating />
<StarRating value={book?.rate || 4} />
</div>
<div className="p-2 border-0 border-solid border-r border-gray-100 text-sm text-gray-400">
بیش از 160 نفر امتیاز داده اند
@ -68,9 +67,9 @@ export const ProductOverAll = ({
}}
width="38%"
color={isDark ? "text-white" : "text-blueC0"}
active={type === "physical"}
active={type === "1"}
selectable={true}
onClick={() => setType("physical")}
onClick={() => setType("1")}
borderType="dashed"
customStyle=""
twPaddings="py-4 px-12"
@ -85,9 +84,10 @@ export const ProductOverAll = ({
}}
width="38%"
selectable={true}
active={type === "digital"}
active={type === "0"}
color={isDark ? "text-white" : "text-blueC0"}
onClick={() => setType("digital")}
onClick={() => setType("0")}
borderType="dashed"
radius={false}
twPaddings="py-4 px-12"
/>
@ -107,27 +107,18 @@ export const ProductOverAll = ({
</div>
</div>
<div className="flex py-4">
<Button
title="مشاهده دوره ویدیویی این محصول >"
backgroundColor={isDark ? "bg-transparent" : "bg-blue-100'"}
border={{
color: isDark ? "#ffffff55" : "#196EC055",
width: "2px",
}}
color={isDark ? "text-white" : "text-blue52"}
selectable={true}
onClick={() => setType("physical")}
customStyle=" bg-blue-100"
twPaddings="py-4 px-32"
radius={false}
/>
<Link
to={"/videos/" + book?.id}
className="bg-blueFF1 text-blueC0 text-tiny rounded-sm border border-solid border-blueC0 w-2/3 py-4 text-center"
>
مشاهده دوره ویدیویی این محصول
</Link>
</div>
</div>
<div className="flex flex-col w-1/3">
<ProductStatusCard />
<ProductStatusCard price={book?.product[type]?.price} id={book?.product[type]?.id} />
</div>
</header>
</div>
);
};

@ -42,144 +42,155 @@ export const Product = ({
<>
{/* Portrait */}
{isMobile ? (
<div className="w-full flex flex-col bg-transparent px-4">
<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-md"
/>
<div className="flex flex-1 flex-col pr-2 pt-2">
<h1 className="text-blue5F mb-3 font-semibold text-sm dark:text-white">
{type === "digital"
? book?.product[0]?.name
: book?.product[1]?.name}
</h1>
<div className="text-blueC0 text-xs dark:text-greenBA">
{"پایه" + " " + grades[book?.gradeId]}
<div className="w-full flex flex-col bg-transparent px-4">
<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-md"
/>
<div className="flex flex-1 flex-col pr-2 pt-2">
<h1 className="text-blue5F mb-3 font-semibold text-sm dark:text-white">
{type === "digital"
? book?.product[0]?.name
: book?.product[1]?.name}
</h1>
<div className="text-blueC0 text-xs dark:text-greenBA">
{"پایه" + " " + grades[book?.gradeId]}
</div>
</div>
</header>
<ul
className="list-none flex flex-row divide-x items-center mt-4"
style={{ direction: "ltr" }}
>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-xs font-medium text-blueC0 dark:text-white">
{book?.pagesNum} <br /> صفحه
</li>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-xs font-medium text-blueC0 dark:text-white">
{"فیزیکی - دیجیتالی"} <br /> در دسترس
</li>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-xs font-medium text-blueC0 dark:text-white">
{book?.rate} <br /> امتیاز
</li>
</ul>
<h2 className="text-blueC0 text-sm font-semibold mt-7 dark:text-greenBA">
نسخه محصول را انتخاب کنید
</h2>
<div className="w-full flex flex-row justify-between items-center mt-4">
<Button
title="نسخه فیزیکی"
backgroundColor={isDark ? "bg-transparent" : "bg-white"}
border={{
color: isDark ? "#ffffff55" : "#196EC055",
width: "1px",
}}
width="49%"
color={isDark ? "text-white" : "text-blueC0"}
active={type === "physical"}
selectable={true}
onClick={() => setType("physical")}
/>
<Button
title="نسخه دیجیتال"
backgroundColor={isDark ? "bg-transparent" : "bg-white"}
border={{
color: isDark ? "#ffffff55" : "#196EC055",
width: "1px",
}}
width="49%"
selectable={true}
active={type === "digital"}
color={isDark ? "text-white" : "text-blueC0"}
onClick={() => setType("digital")}
/>
</div>
<div className="w-full flex flex-row justify-between items-center mt-4">
<Button
onClick={() =>
proxy.status()
? pushToCart({
productId:
type === "digital"
? book?.product[0]?.id
: book?.product[1]?.id,
userId: userId,
count: 1,
})
: toast.info("ابتدا وارد حساب کاربری خود شوید.")
}
title={
"خرید با قیمت" +
" " +
(type === "digital"
? book?.product[0]?.price
: book?.product[1]?.price) +
" " +
"تومان"
}
backgroundColor="bg-blueC0"
border={{ color: "#196EC055", width: "1px" }}
width="65%"
color="text-white"
/>
<Button
title="مشاهده نمونه"
backgroundColor={isDark ? "bg-transparent" : "bg-white"}
border={{
color: isDark ? "#ffffff55" : "#196EC055",
width: "1px",
}}
width="33%"
color={isDark ? "text-white" : "text-blueC0"}
onClick={() => {}}
/>
</div>
<div className="w-full flex flex-row justify-between items-center mt-4">
<Button
title="مشاهده دوره ویدئویی این محصول"
backgroundColor="bg-blueC0"
border={{ color: "#196EC055", width: "0px" }}
bgOpacity="bg-opacity-10"
width="100%"
color={isDark ? "text-white" : "text-blueC0"}
onClick={() => {}}
/>
</div>
<div className="w-full flex flex-col justify-between items-center mt-4">
<Header title="توضیحات" link="#" />
<p className="text-xs text-gray1 mt-2 dark:text-white">
خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ
ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ
ﻫﺮﮔﺰ ﺩﺯﺩﯼ ﻧﮑﻦ ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ
ﻫﺮﮔﺰ ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﺍﺩﺍﻣﻪ ﺩﺍﺩ :
ﺩﺭ ﺯﻧﺪﮔﯽ ﺩﺭﻭﻍ ﻧﮕﻮ ﭼﺮﺍ ﮐﻪ ﺍﮔﺮ ﮔﻔﺘﯽ ﺻﺪﺍﻗﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺧﯿﺎﻧﺖ ﻧﮑﻦ ﮐﻪ
ﺍﮔﺮ ﮐﺮﺩﯼ ﻋﺸﻖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺧﺸﻮﻧﺖ ﻧﮑﻦ ﺍﮔﺮ ﮐﺮﺩﯼ ﻣﺤﺒﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ،
ﻧﺎ ﺣﻖ ﻧﮕﻮ ﺍﮔﺮ ﮔﻔﺘﯽ ﺣﻖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺑﯽ ﺣﯿﺎﯾﯽ ﻧﮑﻦ ﺍﮔﺮ ﮐﺮﺩﯼ ﺷﺮﺍﻓﺖ ﺭﺍ
ﺩﺯﺩﯾﺪﻩ ﺍی... ﭘﺲ ﺩﺭ ﺯﻧﺪﮔﯽ ﻓﻘﻂ ﺩﺯﺩﯼ نکن{" "}
</p>
</div>
<div className="w-full flex flex-col justify-between items-center mt-4">
<Header title="امتیازات و نظرات" link="#" />
<Rate />
</div>
<div
className="flex flex-row w-full pb-4 mt-6"
style={{ overflowX: "scroll" }}
>
{[0, 1, 2, 2].map((comment, index) => (
<Comment key={index} />
))}
</div>
</header>
<ul
className="list-none flex flex-row divide-x items-center mt-4"
style={{ direction: "ltr" }}
>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-xs font-medium text-blueC0 dark:text-white">
{book?.pagesNum} <br /> صفحه
</li>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-xs font-medium text-blueC0 dark:text-white">
{"فیزیکی - دیجیتالی"} <br /> در دسترس
</li>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-xs font-medium text-blueC0 dark:text-white">
{book?.rate} <br /> امتیاز
</li>
</ul>
<h2 className="text-blueC0 text-sm font-semibold mt-7 dark:text-greenBA">
نسخه محصول را انتخاب کنید
</h2>
<div className="w-full flex flex-row justify-between items-center mt-4">
<Button
title="نسخه فیزیکی"
backgroundColor={isDark ? "bg-transparent" : "bg-white"}
border={{ color: isDark ? "#ffffff55" : "#196EC055", width: "1px" }}
width="49%"
color={isDark ? "text-white" : "text-blueC0"}
active={type === "physical"}
selectable={true}
onClick={() => setType("physical")}
/>
<Button
title="نسخه دیجیتال"
backgroundColor={isDark ? "bg-transparent" : "bg-white"}
border={{ color: isDark ? "#ffffff55" : "#196EC055", width: "1px" }}
width="49%"
selectable={true}
active={type === "digital"}
color={isDark ? "text-white" : "text-blueC0"}
onClick={() => setType("digital")}
/>
</div>
<div className="w-full flex flex-row justify-between items-center mt-4">
<Button
onClick={() =>
proxy.status()
? pushToCart({
productId:
type === "digital"
? book?.product[0]?.id
: book?.product[1]?.id,
userId: userId,
count: 1,
})
: toast.info("ابتدا وارد حساب کاربری خود شوید.")
}
title={
"خرید با قیمت" +
" " +
(type === "digital"
? book?.product[0]?.price
: book?.product[1]?.price) +
" " +
"تومان"
}
backgroundColor="bg-blueC0"
border={{ color: "#196EC055", width: "1px" }}
width="65%"
color="text-white"
/>
<Button
title="مشاهده نمونه"
backgroundColor={isDark ? "bg-transparent" : "bg-white"}
border={{ color: isDark ? "#ffffff55" : "#196EC055", width: "1px" }}
width="33%"
color={isDark ? "text-white" : "text-blueC0"}
onClick={() => {}}
/>
</div>
<div className="w-full flex flex-row justify-between items-center mt-4">
<Button
title="مشاهده دوره ویدئویی این محصول"
backgroundColor="bg-blueC0"
border={{ color: "#196EC055", width: "0px" }}
bgOpacity="bg-opacity-10"
width="100%"
color={isDark ? "text-white" : "text-blueC0"}
onClick={() => {}}
/>
</div>
<div className="w-full flex flex-col justify-between items-center mt-4">
<Header title="توضیحات" link="#" />
<p className="text-xs text-gray1 mt-2 dark:text-white">
خالد حسینی تو رمان باد بادک باز مینویسه : ﻣﺮﺩ ﺁﻫﺴﺘﻪ ﺩﺭ ﮔﻮﺵ ﻓﺮﺯﻧﺪ
ﺗﺎﺯﻩ ﺑﻪ ﺑﻠﻮﻍ ﺭﺳﯿﺪﻩ ﺍﺵ ﺑﺮﺍﯼ ﭘﻨﺪ ﭼﻨﯿﻦ ﻧﺠﻮﺍ ﮐﺮﺩ : ﭘﺴﺮﻡ ﺩﺭ ﺯﻧﺪﮔﯽ ﻫﺮﮔﺰ
ﺩﺯﺩﯼ ﻧﮑﻦ ﭘﺴﺮ ﻣﺘﻌﺠﺐ ﻣﺒﻬﻮﺕ ﺑﻪ ﭘﺪﺭ ﻧﮕﺎﻩ ﮐﺮﺩ ﺑﺪﯾﻦ ﻣﻌﻨﺎ ﮐﻪ ﺍﻭ ﻫﺮﮔﺰ
ﺩﺳﺖ ﮐﺞ ﻧﺪﺍﺷﺘﻪ ﭘﺪﺭ ﺑﻪ ﻧﮕﺎﻩ ﻣﺘﻌﺠﺐ ﻓﺮﺯﻧﺪ ﻟﺒﺨﻨﺪﯼ ﺯﺩ ﺍﺩﺍﻣﻪ ﺩﺍﺩ : ﺩﺭ
ﺯﻧﺪﮔﯽ ﺩﺭﻭﻍ ﻧﮕﻮ ﭼﺮﺍ ﮐﻪ ﺍﮔﺮ ﮔﻔﺘﯽ ﺻﺪﺍﻗﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺧﯿﺎﻧﺖ ﻧﮑﻦ ﮐﻪ ﺍﮔﺮ
ﮐﺮﺩﯼ ﻋﺸﻖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺧﺸﻮﻧﺖ ﻧﮑﻦ ﺍﮔﺮ ﮐﺮﺩﯼ ﻣﺤﺒﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﻧﺎ ﺣﻖ
ﻧﮕﻮ ﺍﮔﺮ ﮔﻔﺘﯽ ﺣﻖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ ﺍﯼ، ﺑﯽ ﺣﯿﺎﯾﯽ ﻧﮑﻦ ﺍﮔﺮ ﮐﺮﺩﯼ ﺷﺮﺍﻓﺖ ﺭﺍ ﺩﺯﺩﯾﺪﻩ
ﺍی... ﭘﺲ ﺩﺭ ﺯﻧﺪﮔﯽ ﻓﻘﻂ ﺩﺯﺩﯼ نکن{" "}
</p>
</div>
<div className="w-full flex flex-col justify-between items-center mt-4">
<Header title="امتیازات و نظرات" link="#" />
<Rate />
</div>
<div
className="flex flex-row w-full pb-4 mt-6"
style={{ overflowX: "scroll" }}
>
{[0, 1, 2, 2].map((comment, index) => (
<Comment key={index} />
))}
) : (
<div className="flex flex-col items-center justify-center">
<DesktopProductLayout />
</div>
</div>) :<div className="flex flex-col items-center justify-center">
<DesktopProductLayout />
</div>
}
)}
</>
);
};
@ -189,7 +200,7 @@ const mapStateToProps = (state) => ({
grades: state.publicApi.grades,
isMobile: state.publicApi.isMobile,
isDark: state.publicApi.isDark,
userId: state.user.status.id,
userId: state.user.status?.id,
});
const mapDispatchToProps = {

@ -139,9 +139,20 @@ function Product({ product, grades, pushToCart, isMobile }) {
&nbsp;{product?.product?.price}&nbsp;&nbsp;تومان
</strong>
<img
onClick={() =>
pushToCart(
{
productId: product?.productId,
userId: product?.userId,
count: product?.productType === 1 ? -1 : -product?.count,
},
{},
{ id: product?.factorId }
)
}
src={deleteIcon}
alt="delete"
className="border border-red-800 border-solid p-1 w-8 bg-red-100 rounded-md mr-4"
className="border border-red-800 border-solid p-1 w-8 bg-red-100 rounded-md mr-4 cursor-pointer"
/>
</div>
</div>

@ -50,7 +50,7 @@ function ShoppingCart({
</strong>
</header>
<ul className="w-full mt-2 list-none p-0">
{list.map((product, index) => (
{list.map((product, index) => product.condition < 2 && (
<Product key={index} product={product} />
))}
</ul>
@ -147,7 +147,7 @@ function ShoppingCart({
</div>
) : (
<div
className={`w-full flex flex-row relative gap-10 px-5 mt-10 ${
className={`w-full flex flex-row relative gap-10 px-5 mt-10 pb-20 ${
desktopContentTransform ? "top-24" : ""
}`}
>
@ -172,7 +172,7 @@ function ShoppingCart({
/>
<PriceStatus
name="مالیات بر ارزش افزوده"
value={factorInfo?.sumPrice * 0.009}
value={Math.floor(factorInfo?.sumPrice * 0.009)}
type="error"
/>
</div>

@ -1,31 +1,46 @@
import React from "react";
import React, {useState, useEffect} from "react";
import "../../../../components/ProductImage/index.scss";
import productImg from "../../../../components/ProductImage/product-image.jpg";
const Videos = ({ videos }) => {
const [list, setList] = useState([]);
const [activeVideo, setActiveVideo] = useState([]);
useEffect(() => {
if (videos) {
let mylist = videos?.split(",");
setList(() => mylist);
setActiveVideo(() => mylist[0]);
console.log(videos);
}
}, [videos]);
return (
<div className="flex flex-row gap-5">
<div
className="flex flex-col items-start justify-between"
// style={{ height: "calc(100vh / 2 * 9 / 16)" }}
>
{videos.slice(0, 4).map((video, index) => (
{list?.slice(0, 4).map((video, index) => (
<div
className="relative rounded-md"
className={`relative rounded-md flex justify-center items-center ${activeVideo === video ? 'bg-green-200' : 'bg-gray-200'}`}
style={{
width: "calc(100vh / 5.5 - 8px)",
height: "calc(100vh / 5.5 - 8px)",
}}
key={index}
>
<img
key={index}
src={productImg}
src={`https://dnvn.ir/api/v1/file/${video}`}
alt=""
className={`rounded-sm w-full h-full`}
// style={{ height: "calc(100% - 8px)" }}
// style={{ height: "calc(100% - 8px)" }}
style={{
width: "calc(100vh / 5.5 * 2 / 3 - 12px)",
height: "calc(100vh / 5.5 - 20px)",
}}
/>
{/* این خط پایین که نوشتم برای این است که ایندکس که جنسش استرینگ است رو به نامبر تبدیل کند */}
{Number(index) === 3 && (
@ -51,16 +66,3 @@ const Videos = ({ videos }) => {
export default Videos;
Videos.defaultProps = {
videos: [
{
image: productImg,
},
{
image: productImg,
},
{
image: productImg,
},
],
};

@ -1,6 +1,8 @@
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { publicApi } from "../../redux/actions";
import {toast} from 'react-toastify';
import { Link } from "react-router-dom";
import { publicApi, userProduct } from "../../redux/actions";
import location from "../../utils/location";
import Divider from "../../components/Divider";
import Season from "./components/Season";
@ -15,6 +17,9 @@ import poster from "../../assets/images/poster.svg";
import tickIcon from "../../components/ProductStatusCard/tick-circle.svg";
function Video({
isLogin,
pushToCart,
userId,
product = {
id: 0,
type: "کتاب ها",
@ -63,7 +68,7 @@ function Video({
const [type, setType] = useState(0);
useEffect(() => {
getBook({ bookId: 19 });
getBook({ bookId: Number(location.getId()) });
setHeaderOptions(headerOptions);
}, []);
@ -86,14 +91,14 @@ function Video({
}}
>
<img
src={product.imageUrl}
src={`https://dnvn.ir/api/v1/file/${book?.fileIds}`}
className="rounded-md absolute left-2 top-1/2 transform -translate-y-1/2"
style={{ width: 70, height: 100 }}
/>
</div>
<div className="flex flex-col flex-1 justify-between pr-2">
<div className="flex flex-col">
<strong className="mt-2 text-blue5F text-lg dark:text-white">
<strong className="mt-2 text-blue5F text-base dark:text-white font-normal">
{book?.name}
</strong>
<span className="text-blueC0 text-sm mb-1 dark:text-greenBA mt-2">
@ -113,7 +118,7 @@ function Video({
<div className="flex flex-col w-11/12 min-h-screen mx-auto pb-20">
<header className="w-full flex flex-row gap-12">
<div className="w-9/12">
<Videos />
<Videos videos={book?.fileIds} />
<ProductTab
tabs={[
{
@ -147,11 +152,11 @@ function Video({
{book?.name}
</h1>
<div className="text-blueC0 text-sm dark:text-greenBA">
{"پایه" + " " + (grades[book?.gradeId] || "پایه دوازدهم")}
{"پایه" + " " + grades[book?.gradeId]}
</div>
<div className="flex justify-end">
<div className="p-2">
<StarRating />
<StarRating value={book?.rate || 4} />
</div>
<div className="p-2 border-0 border-solid border-r border-gray-100 text-sm text-gray-400">
بیش از 160 نفر امتیاز داده اند
@ -159,7 +164,7 @@ function Video({
</div>
</div>
<div className="bg-grayF9 w-full flex flex-col rounded-md divide-y divide-solid divide-gray-200 mb-4">
<div className="flex flex-row justify-center items-center w-full gap-5 py-3">
<div className="flex flex-row justify-center items-center w-full gap-5 my-5">
<img src={tickIcon} alt="" className="w-9" />
<p className="text-blue52 text-sm font-light">{`توسعه خرید توسط ${
book?.recommendedPeople || 4234
@ -167,16 +172,14 @@ function Video({
</div>
<div className="flex flex-col w-full py-4 px-4">
<div className="flex flex-row items-center justify-center gap-2">
<strong className="text-blueC0 text-xl">
{book?.price || "56/894/000"}
</strong>
<strong className="text-blueC0 text-xl">{book?.price}</strong>
<span className="text-sm text-gray-500">تومان</span>
</div>
<p className="text-gray-500 text-xs text-center mt-2 mb-4">
با خرید این کالا 540.000 صرفه جویی کنید
</p>
<Button
title=صافه کردن به سبد خرید"
title=ضافه کردن به سبد خرید"
backgroundColor={isDark ? "bg-blueC0" : "bg-blueC0"}
border={{
color: isDark ? "#ffffff55" : "#196EC055",
@ -185,19 +188,24 @@ function Video({
width="100%"
color={"text-white"}
selectable={true}
onClick={() => {}}
onClick={() =>
isLogin
? pushToCart({
productId: book?.id,
userId: userId,
count: 1,
})
: toast.info("ابتدا وارد حساب کاربری خود شوید.")
}
/>
</div>
</div>
<Button
title="مشاهده دوره ویدئویی این محصول"
backgroundColor="bg-blueC0"
border={{ color: "#196EC055", width: "0px" }}
bgOpacity="bg-opacity-10"
width="100%"
color={isDark ? "text-white" : "text-blueC0"}
onClick={() => {}}
/>
<Link
to={"/products/" + book?.id}
className="bg-blueFF1 text-blueC0 text-sm rounded-md border border-solid border-blueC01 w-full py-4 text-center"
>
مشاهده کتاب این محصول
</Link>
</div>
</header>
</div>
@ -210,11 +218,14 @@ const mapStateToProps = (state) => ({
book: state.publicApi.bookInfo,
seasons: state.publicApi.categories,
grades: state.publicApi.grades,
isLogin: state.user.status,
userId: state.user.status.id,
});
const mapDispatchToProps = {
setHeaderOptions: publicApi.setHeaderOptions,
getBook: publicApi.bookInfo,
pushToCart: userProduct.add,
};
export default connect(mapStateToProps, mapDispatchToProps)(Video);

@ -3,7 +3,7 @@ import { Link } from "react-router-dom";
import Header from "../../../components/Header";
import posterImage from "../../../assets/images/poster.svg";
function MostViewedVideo({}) {
function MostViewedVideo({videos, grades}) {
const Video = ({ video }) => {
return (
<Link
@ -13,7 +13,7 @@ function MostViewedVideo({}) {
<div
className="w-full flex flex-row flex-1 justify-between items-center relative overflow-hidden"
style={{
backgroundImage: `url(${video.poster})`,
backgroundImage: `url(${posterImage})`,
backgroundSize: "100% 100%",
repeat: "no-repeat",
minWidth: "calc(100vw / 1.4)",
@ -21,7 +21,7 @@ function MostViewedVideo({}) {
}}
>
<img
src={video.imageUrl}
src={`https://dnvn.ir/api/v1/file/${video.fileIds}`}
className="rounded-md h-full absolute left-2 top-1/2 transform -translate-y-1/2"
style={{
width: "calc(100vw / 7)",
@ -29,7 +29,7 @@ function MostViewedVideo({}) {
}}
/>
</div>
<strong className="text-lg mt-1 text-blue5F dark:text-white">
<strong className="text-tiny mt-1 text-blue5F dark:text-white font-normal">
{video.name}
</strong>
<div className="w-full flex flex-row justify-between items-center mt-3">
@ -37,7 +37,7 @@ function MostViewedVideo({}) {
{video.price}
</strong>
<span className="text-blueC0 text-sm dark:text-white">
{"پایه" + " " + video.grade}
{"پایه" + " " + grades[video.gradeId]}
</span>
</div>
</Link>
@ -47,17 +47,10 @@ function MostViewedVideo({}) {
<div className="w-full flex flex-col">
<Header title="پربازدیدترین" link="/videos/video" />
<div className="w-full flex flex-row overflow-x-scroll pb-4">
{[0, 1, 2].map((video, index) => (
{videos.map((video, index) => (
<Video
key={index}
video={{
id: 0,
name: "ریاضی",
price: "145.000 تومان",
grade: "4",
imageUrl: "https://dnvn.ir/api/v1/file/2105",
poster: posterImage,
}}
video={video}
/>
))}
</div>

@ -1,27 +1,32 @@
import React from "react";
import {Link} from 'react-router-dom';
import { Link } from "react-router-dom";
import Header from "../../../components/Header";
import posterImage from "../../../assets/images/poster.svg";
const NewestVideo = () => {
const NewestVideo = ({ videos, grades }) => {
const Video = ({ video }) => {
return (
<Link
to={'/videos/' + video.id}
className="flex flex-col items-start mb-4 shadow-md p-1.5 rounded-md"
style={{width: 'calc(100vw / 2.2)'}}
to={"/videos/" + video.id}
className="flex flex-col items-start mb-4 shadow-md p-2 rounded-md overflow-hidden"
style={{ width: "calc(100vw / 2.2)" }}
>
<img
src={video.poster}
className="w-full rounded-md"
/>
<strong
className="text-base mt-2 text-blue5F dark:text-white"
>
<div className="w-full bg-gray-200 py-2 rounded-t-md">
<img
src={`https://dnvn.ir/api/v1/file/${video.fileIds}`}
className="rounded-md mx-auto"
style={{
height: "calc(100vh / 7)",
width: "calc(100vh / 7 * 2 / 3)",
}}
/>
</div>
<strong className="text-base mt-2 text-blue5F dark:text-white font-normal">
{video.name}
</strong>
<span className="text-blueC0 text-sm mt-2 dark:text-greenBA">
{"پایه" + " " + video.grade}
{"پایه" + " " + grades[video.gradeId]}
</span>
</Link>
);
@ -30,19 +35,8 @@ const NewestVideo = () => {
<div className="w-full flex flex-col">
<Header title="جدیدترین دورهها" link="/videos/video" />
<div className="w-full flex flex-row flex-wrap justify-between overflow-x-scroll mt-3">
{[0, 1, 2, 3].map((video, index) => (
<Video
key={index}
video={{
id : 0,
name: "ریاضی",
price: "145.000 تومان",
grade: "4",
imageUrl: "https://dnvn.ir/api/v1/file/2105",
poster: posterImage,
}}
key={index}
/>
{videos.map((video, index) => (
<Video key={index} video={video} />
))}
</div>
</div>

@ -1,6 +1,6 @@
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { publicApi } from "../../redux/actions";
import { publicApi, book } from "../../redux/actions";
import Search from "../../components/Search";
import VerticalGradeFilter from "./components/VerticalGradeFilter";
import Divider from "../../components/Divider";
@ -9,10 +9,11 @@ import NewestVideo from "./components/NewestVideo";
//assets
import searchLight from "../../assets/icons/search-light.svg";
function Videos({ headerOptions, setHeaderOptions }) {
function Videos({ headerOptions, setHeaderOptions, getList, videos, grades }) {
const [search, setSearch] = useState("");
useEffect(() => {
setHeaderOptions(headerOptions);
getList();
}, []);
return (
<div className="flex flex-col">
@ -31,20 +32,24 @@ function Videos({ headerOptions, setHeaderOptions }) {
<Divider type={"vertical"} />
</div>
<div className="pr-4">
<MostViewedVideo />
<MostViewedVideo videos={videos} grades={grades} />
</div>
<div className="px-4 flex flex-col">
<Divider type={"vertical"} />
<NewestVideo />
<NewestVideo videos={videos} grades={grades} />
</div>
</div>
);
}
const mapStateToProps = (state) => ({});
const mapStateToProps = (state) => ({
videos : state.book.list,
grades: state.publicApi.grades,
});
const mapDispatchToProps = {
setHeaderOptions: publicApi.setHeaderOptions,
getList : book.list
};
export default connect(mapStateToProps, mapDispatchToProps)(Videos);

Loading…
Cancel
Save