update 5 files

master
Reza_ashrafi 2 years ago
parent 30cc3dfa9b
commit 6bab87262e
  1. 31
      src/components/ButtonBetween/index.js
  2. 6
      src/redux/actions/config.js
  3. 8
      src/redux/reducers/config.js
  4. 8
      src/router.js
  5. 271
      src/views/Product/index.js

@ -1,6 +1,9 @@
import React from "react";
import { connect } from "react-redux";
//components
import Loading from "../Loading";
export const ButtonBetween = ({
item,
status,
@ -8,6 +11,7 @@ export const ButtonBetween = ({
width,
active,
toggle,
loading,
}) => {
return toggle ? (
<button
@ -17,13 +21,18 @@ export const ButtonBetween = ({
onClick={() => onClick()}
style={{ width, padding: "18px 8px" }}
>
<strong
className={`text-tiny ${
active ? "text-green-700" : "text-gray-700"
} font-semibold`}
>
{item}
</strong>
{loading ? (
<Loading size={2} color="bg-green-500" />
) : (
<strong
className={`text-tiny ${
active ? "text-green-700" : "text-gray-700"
} font-semibold`}
>
{item}
</strong>
)}
{status && (
<span
className={`pr-3 border-r border-solid ${
@ -42,7 +51,13 @@ export const ButtonBetween = ({
onClick={() => onClick()}
style={{ width, padding: "18px 8px" }}
>
<strong className="text-tiny text-green-700 font-semibold">{item}</strong>
{loading ? (
<Loading size={2} color="bg-green-500" />
) : (
<strong className="text-tiny text-green-700 font-semibold">
{item}
</strong>
)}
{status && (
<span className="pr-3 border-r border-solid border-green-600 text-tiny text-green-700 font-semibold">
{status}

@ -1,6 +1,12 @@
import proxy from "../proxy";
const config = {
setDevice: (data) => async (dispatch) =>
await dispatch({ type: "config/setDevice", data }),
getAvailableForSell:
(data = {}) =>
async (dispatch) =>
await proxy.get("config/availableForSell", data, { dispatch }),
};
export default config;

@ -1,5 +1,6 @@
const initialState = {
device: "mobile",
availableForSell: [],
};
export default function config(state = initialState, action) {
@ -10,6 +11,13 @@ export default function config(state = initialState, action) {
...state,
device: data,
};
case "config/availableForSell":
return {
...state,
loading: false,
availableForSell: data.productTypes,
error: null,
};
default:
return state;
}

@ -2,7 +2,7 @@ import React, { useEffect } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom";
import { Navigate } from "react-router-dom";
import { connect } from "react-redux";
import { publicApi, menu, config } from "./redux/actions";
import { publicApi, menu, config, userProduct } from "./redux/actions";
import Navbar from "./components/Navbar";
import BG from "./components/BG";
import BottomNavigation from "./components/BottomNavigation";
@ -44,8 +44,12 @@ function Router({
setMenu,
setDevice,
device,
getAvailableForSell,
getUserProducts
}) {
useEffect(() => {
getAvailableForSell();
getUserProducts();
const width = window.innerWidth;
if (width <= 640) {
setDevice("mobile");
@ -602,6 +606,8 @@ const mapDispatchToProps = {
setDesktopContentTransform: publicApi.setDesktopContentTransform,
setMenu: menu.set,
setDevice: config.setDevice,
getAvailableForSell: config.getAvailableForSell,
getUserProducts: userProduct.list
};
export default connect(mapStateToProps, mapDispatchToProps)(Router);

@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { toast } from "react-toastify";
import { book, userProduct, publicApi } from "../../redux/actions";
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";
@ -22,6 +22,7 @@ import arrow from "../../assets/icons/dropdown-blue.svg";
export const Product = ({
isMobile,
productType,
userProducts,
getInfo,
book,
grades,
@ -29,13 +30,60 @@ export const Product = ({
userId,
pushToCart,
headerOptions,
bookmarkLoading,
userProductLoading,
setHeaderOptions,
availableForSell,
setDialog,
}) => {
const [type, setType] = useState("physical");
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(() => {
getInfo({ id: location.getId(), vod: true });
if (!isMobile) {
@ -49,6 +97,12 @@ export const Product = ({
}
}, []);
useEffect(() => {
if (!userProductLoading) {
setWhichTypeAdded(null);
}
}, [userProductLoading]);
useEffect(() => {
if (book) {
setHeaderOptions({ ...headerOptions, productId: book?.id });
@ -92,7 +146,11 @@ export const Product = ({
{book?.pagesNum} <br /> صفحه
</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">
{"فیزیکی - دیجیتالی"} <br /> در دسترس
<span>{videoAvailableForSell ? "ویدئویی - " : ""}</span>
<span>{digitalAvailableForSell ? "دیجیتال - " : ""}</span>
<span>{physicalAvailableForSell ? "فیزیکی" : ""}</span>
<br /> در دسترس
</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">
@ -103,66 +161,147 @@ export const Product = ({
<h2 className="text-green7B text-base font-semibold mt-10 dark:text-greenBA">
نسخه محصول را انتخاب کنید
</h2>
<div className="w-full flex justify-between items-center mt-5">
<ButtonBetween
width="100%"
item={"خرید نسخه فیزیکی کتاب"}
status={separate(book?.product[1]?.price) + " " + "تومان"}
onClick={() =>
userId
? pushToCart({
productId: book?.product[1]?.id,
userId,
count: 1,
})
: toast.info("ابتدا وارد حساب کاربری خود شوید.")
}
/>
</div>
<div className="w-full flex justify-between items-center mt-4 gap-2">
<ButtonBetween
width="72%"
item={"خرید نسخه دیجیتال کتاب"}
status={separate(book?.product[0]?.price) + " " + "تومان"}
onClick={() =>
userId
? pushToCart({
productId: book?.product[0]?.id,
userId,
count: 1,
})
: toast.info("ابتدا وارد حساب کاربری خود شوید.")
}
/>
<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" }}
>
مشاهده نمونه
</a>
</div>
<div className="w-full flex justify-between items-center mt-4">
<ButtonBetween
width="72%"
item={"خرید نسخه ویدئویی کتاب"}
status={separate(book?.product[2]?.price) + " " + "تومان"}
onClick={() =>
userId
? pushToCart({
productId: book?.product[2]?.id,
userId,
count: 1,
})
: toast.info("ابتدا وارد حساب کاربری خود شوید.")
}
/>
<ButtonBetween
width="25%"
item={"پیش نمایش"}
onClick={() => navigation("/videos/" + book?.id)}
/>
</div>
{physicalProduct && physicalAvailableForSell ? (
<div className="w-full flex justify-between items-center mt-5 gap-2">
<ButtonBetween
width="72%"
item={"خرید نسخه فیزیکی کتاب"}
status={separate(physicalProduct?.price) + " " + "تومان"}
onClick={() => {
if (userId) {
if (physicalAvailabileInCart) {
setDialog({
text: window.t(
"این محصول قبلا به سبد خرید شما اضافه شده است."
),
type: "confirm",
accept: () => navigation("/cart"),
open: true,
});
} else {
setWhichTypeAdded("physical");
pushToCart({
productId: physicalProduct?.id,
userId: userId,
count: 1,
});
}
} else {
setDialog({
text: window.t(
"ابتدا میبایست وارد حساب کاربری خود شوید."
),
type: "confirm",
accept: () => navigation("/login"),
open: true,
});
}
}}
loading={userProductLoading && whichTypeAdded === "physical"}
/>
<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" }}
>
مشاهده نمونه
</a>
</div>
) : null}
{digitalProduct && digitalAvailableForSell ? (
<div className="w-full flex justify-between items-center mt-4 gap-2">
<ButtonBetween
width="72%"
item={"خرید نسخه دیجیتال کتاب"}
status={separate(digitalProduct?.price) + " " + "تومان"}
onClick={() => {
if (userId) {
if (digitalAvailabileInCart) {
setDialog({
text: window.t(
"این محصول قبلا به سبد خرید شما اضافه شده است."
),
type: "confirm",
accept: () => navigation("/cart"),
open: true,
});
} else {
setWhichTypeAdded("digital");
pushToCart({
productId: digitalProduct?.id,
userId: userId,
count: 1,
});
}
} else {
setDialog({
text: window.t(
"ابتدا میبایست وارد حساب کاربری خود شوید."
),
type: "confirm",
accept: () => navigation("/login"),
open: true,
});
}
}}
loading={userProductLoading && whichTypeAdded === "digital"}
/>
<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" }}
>
مشاهده نمونه
</a>
</div>
) : null}
{videoProduct && videoAvailableForSell ? (
<div className="w-full flex justify-between items-center mt-4">
<ButtonBetween
width="72%"
item={"خرید نسخه ویدئویی کتاب"}
status={separate(videoProduct?.price) + " " + "تومان"}
onClick={() => {
if (userId) {
if (videoAvailabileInCart) {
setDialog({
text: window.t(
"این محصول قبلا به سبد خرید شما اضافه شده است."
),
type: "confirm",
accept: () => navigation("/cart"),
open: true,
});
} else {
setWhichTypeAdded("video");
pushToCart({
productId: videoProduct?.id,
userId: userId,
count: 1,
});
}
} else {
setDialog({
text: window.t(
"ابتدا میبایست وارد حساب کاربری خود شوید."
),
type: "confirm",
accept: () => navigation("/login"),
open: true,
});
}
}}
loading={userProductLoading && whichTypeAdded === "video"}
/>
<ButtonBetween
width="25%"
item={"پیش نمایش"}
onClick={() => navigation("/videos/" + book?.id)}
/>
</div>
) : null}
<div className="w-full flex flex-col justify-between items-center mt-8">
<Header title="توضیحات" link="#" />
<p className="text-sm text-gray70 mt-2 dark:text-white leading-6">
@ -205,12 +344,16 @@ const mapStateToProps = (state) => ({
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);

Loading…
Cancel
Save