reza added cart api

master
RezaAshrafi77 3 years ago
parent 3cd90d8e03
commit 75016e9540
  1. 1
      src/App.js
  2. 7
      src/AppRouter.js
  3. 4
      src/Redux/actions/public.js
  4. 2
      src/Redux/actions/userProduct.js
  5. 6
      src/Redux/reducers/public.js
  6. 10
      src/Redux/reducers/userProduct.js
  7. 125
      src/views/Cart/Table/index.js
  8. 268
      src/views/Cart/index.js
  9. 211
      src/views/Contact/index.js
  10. 45
      src/views/Product/AddToCart/index.js
  11. 19
      src/views/Product/AddToCart/index.scss
  12. 4
      src/views/Product/Comment/index.js
  13. 153
      src/views/Product/Gallery/index.js
  14. 264
      src/views/Product/index.js
  15. 50
      src/views/Products/Product/index.js
  16. 38
      src/views/Products/Product/index.scss
  17. 6
      src/views/Products/index.js

@ -3,6 +3,7 @@ import AppRouter from "./AppRouter";
import store from "./Redux/store"; import store from "./Redux/store";
import { Provider } from "react-redux"; import { Provider } from "react-redux";
import "bootstrap/dist/css/bootstrap.min.css"; import "bootstrap/dist/css/bootstrap.min.css";
import "react-toastify/dist/ReactToastify.css";
class App extends Component { class App extends Component {
render() { render() {

@ -89,8 +89,11 @@ class AppRouter extends Component {
<Route exact path={"/products"}> <Route exact path={"/products"}>
<Products /> <Products />
</Route> </Route>
<Route exact path={"/products/:id"}> <Route exact path={"/products/digital/:id"}>
<Product /> <Product page="digital" />
</Route>
<Route exact path={"/products/physical/:id"}>
<Product page="physical" />
</Route> </Route>
<Route exact path={"/qr"}> <Route exact path={"/qr"}>
<QR /> <QR />

@ -8,6 +8,10 @@ const publicApi = {
await dispatch({ type: "public/faq/activate", data: data }), await dispatch({ type: "public/faq/activate", data: data }),
searchFaq: (data) => async (dispatch) => searchFaq: (data) => async (dispatch) =>
await dispatch({ type: "public/faq/search", data: data }), await dispatch({ type: "public/faq/search", data: data }),
getContactData:
(data = {}, history) =>
async (dispatch) =>
await proxy.get("public/contact", data, { history, dispatch }),
}; };
export default publicApi; export default publicApi;

@ -17,7 +17,7 @@ const userProduct = {
add: add:
(data = {}, data2 = {}) => (data = {}, data2 = {}) =>
async (dispatch) => { async (dispatch) => {
await proxy.post("userProduct/add", data); await proxy.post("userProduct/add", data, { dispatch });
await proxy.get("userProduct/list", data2, { dispatch }); await proxy.get("userProduct/list", data2, { dispatch });
}, },
del: del:

@ -1,9 +1,10 @@
const initialState = { const initialState = {
homeData: [], homeData: [],
faqList: [], faqList: [],
loading: false, loading: true,
error: null, error: null,
searchResult: [], searchResult: [],
contactData: null,
}; };
export default function publicApi(state = initialState, action) { export default function publicApi(state = initialState, action) {
let { type, data } = action; let { type, data } = action;
@ -35,10 +36,13 @@ export default function publicApi(state = initialState, action) {
item.description.indexOf(data) !== -1 item.description.indexOf(data) !== -1
), ),
}; };
case "public/contact":
return { ...state, loading: false, error: null, contactData: data };
case "loading": case "loading":
return { ...state, loading: true }; return { ...state, loading: true };
case "error": case "error":
return { ...state, loading: false, error: data.message }; return { ...state, loading: false, error: data.message };
default: default:
return state; return state;
} }

@ -1,11 +1,14 @@
import { toast } from "react-toastify";
const initialState = { const initialState = {
loading: false, loading: false,
error: null, error: null,
list: null, list: null,
info: null, info: null,
sum: null,
}; };
export default function userProduct(state = initialState, action) { export default function userProduct(state = initialState, action) {
let { type, data } = action; let { type, data, message } = action;
switch (type) { switch (type) {
case "userProduct/list": case "userProduct/list":
return { ...state, loading: false, list: data, error: null }; return { ...state, loading: false, list: data, error: null };
@ -14,13 +17,16 @@ export default function userProduct(state = initialState, action) {
case "userProduct/update": case "userProduct/update":
return { ...state, loading: false, error: null }; return { ...state, loading: false, error: null };
case "userProduct/add": case "userProduct/add":
return { ...state, loading: false, error: null }; console.log(data);
toast.success("درخواست شما با موفقیت انجام شد.");
return { ...state, loading: false, error: null, sum: data.payPrice };
case "userProduct/delete": case "userProduct/delete":
return { ...state, loading: false, error: null }; return { ...state, loading: false, error: null };
///////////// /////////////
case "loading": case "loading":
return { ...state, loading: true }; return { ...state, loading: true };
case "error": case "error":
toast.error(data.message);
return { ...state, loading: false, error: data.message }; return { ...state, loading: false, error: data.message };
default: default:
return state; return state;

@ -1,4 +1,7 @@
import React from "react"; import React from "react";
import { connect } from "react-redux";
import { userProduct } from "~/Redux/actions";
import { makeStyles } from "@material-ui/core/styles"; import { makeStyles } from "@material-ui/core/styles";
import Table from "@material-ui/core/Table"; import Table from "@material-ui/core/Table";
import TableBody from "@material-ui/core/TableBody"; import TableBody from "@material-ui/core/TableBody";
@ -56,7 +59,7 @@ const fontSize = {
}, },
}; };
export default function BasicTable(props) { function BasicTable(props) {
const classes = useStyles(); const classes = useStyles();
const { list, handleCounter, handleDelete } = props; const { list, handleCounter, handleDelete } = props;
const sum = () => { const sum = () => {
@ -91,7 +94,10 @@ export default function BasicTable(props) {
<Item <Item
data={row} data={row}
key={i} key={i}
handleCounter={handleCounter} // handleCounter={handleCounter}
pushToCart={props.pushToCart}
info={props.info}
id={props.id}
handleDelete={handleDelete} handleDelete={handleDelete}
/> />
))} ))}
@ -100,7 +106,9 @@ export default function BasicTable(props) {
<span style={{ color: "grey" }}>{sum()} محصول</span> <span style={{ color: "grey" }}>{sum()} محصول</span>
</TableCell> </TableCell>
<TableCell align="center"> <TableCell align="center">
<span style={{ color: "grey" }}>مبلغ کل {totalPrice()}</span> <span style={{ color: "grey" }}>
مبلغ کل {props.payPrice}
</span>
</TableCell> </TableCell>
</TableRow> </TableRow>
</TableBody> </TableBody>
@ -123,7 +131,10 @@ export default function BasicTable(props) {
<Item <Item
data={row} data={row}
key={i} key={i}
handleCounter={handleCounter} // handleCounter={handleCounter}
pushToCart={props.pushToCart}
info={props.info}
id={props.id}
handleDelete={handleDelete} handleDelete={handleDelete}
/> />
))} ))}
@ -132,7 +143,9 @@ export default function BasicTable(props) {
<span style={{ color: "grey" }}></span> <span style={{ color: "grey" }}></span>
</TableCell> </TableCell>
<TableCell align="center"> <TableCell align="center">
<span style={{ color: "grey" }}>مبلغ کل {totalPrice()}</span> <span style={{ color: "grey" }}>
مبلغ کل {props.payPrice}
</span>
</TableCell> </TableCell>
<TableCell align="center" component="th" scope="row"> <TableCell align="center" component="th" scope="row">
<span style={{ color: "grey" }}>{sum()} محصول</span> <span style={{ color: "grey" }}>{sum()} محصول</span>
@ -149,33 +162,31 @@ export default function BasicTable(props) {
); );
} }
// id: 1,
// title: "ریاضیات گسسته خیلی پیشرفته",
// subTitle: "در این قسمت توضیح بسیار کوتاهی قرار می گیرد",
// options: "بستههای الحاقی: کیف، کفش و کوله پشتی",
// image: book1,
// slicePrice: 300000,
// number: 1,
// price: 2500000,
const Item = (props) => { const Item = (props) => {
const { data, handleCounter, handleDelete } = props; const { data, pushToCart, handleDelete, info, id } = props;
return ( return (
<> <>
{window.innerWidth < 1000 ? ( {window.innerWidth < 1000 ? (
<TableRow key={data.name}> <TableRow key={data.product.book.name}>
<TableCell align="right" component="th" scope="row"> <TableCell align="right" component="th" scope="row">
<div className="mobile-cart-table-product d-flex align-items-center"> <div className="mobile-cart-table-product d-flex align-items-center">
<img src={data.image} alt={data.title} /> <img
src={`https://dnvn.ir/api/v1/file/${data.product.book.fileIds}`}
alt={data.product.book.name}
/>
<div className="mobile-cart-table-product__info d-flex flex-column p-1"> <div className="mobile-cart-table-product__info d-flex flex-column p-1">
<strong style={{ fontSize: fontSize.mobile.info.strong }}> <strong style={{ fontSize: fontSize.mobile.info.strong }}>
{data.title} {`کتاب ${
data.product.productType === "1" ? "دیجیتال" : "فیزیکی"
}` +
" " +
data.product.book.name}
</strong> </strong>
<p style={{ fontSize: fontSize.mobile.info.p }}> <p style={{ fontSize: fontSize.mobile.info.p }}>
{data.subTitle} {data.product.book.category}
</p> </p>
<span style={{ fontSize: fontSize.mobile.info.span }}> <span style={{ fontSize: fontSize.mobile.info.span }}>
{data.options} {data.product.book.item || "هیچی"}
</span> </span>
<div className="mobile-cart-table-product__info--delete d-flex align-items-center align-self-end"> <div className="mobile-cart-table-product__info--delete d-flex align-items-center align-self-end">
<DeleteOutlineOutlinedIcon <DeleteOutlineOutlinedIcon
@ -199,27 +210,35 @@ const Item = (props) => {
<div className="mobile-cart-table-price d-flex flex-column align-items-center"> <div className="mobile-cart-table-price d-flex flex-column align-items-center">
<div className="mobile-cart-table-price__price d-flex flex-column justify-content-center align-items-center"> <div className="mobile-cart-table-price__price d-flex flex-column justify-content-center align-items-center">
<strong style={{ fontSize: fontSize.mobile.price.strong }}> <strong style={{ fontSize: fontSize.mobile.price.strong }}>
{data.price} {data.product.book.price || "1000"}
</strong> </strong>
<span style={{ fontSize: fontSize.mobile.price.span }}> <span style={{ fontSize: fontSize.mobile.price.span }}>
{data.slicePrice} قیمت هر واحد {data.product.book.subPrice || "100"} قیمت هر واحد
</span> </span>
</div> </div>
<div className="mobile-cart-table-price__counter d-flex justify-content-around align-items-center"> <div className="mobile-cart-table-price__counter d-flex justify-content-around align-items-center">
<button <button
onClick={() => handleCounter("increase", data.id)} onClick={() =>
pushToCart({
productId: data.productId,
userId: id,
count: 1,
})
}
style={{ fontSize: fontSize.mobile.counter.button }} style={{ fontSize: fontSize.mobile.counter.button }}
> >
+ +
</button> </button>
<span style={{ fontSize: fontSize.mobile.counter.span }}> <span style={{ fontSize: fontSize.mobile.counter.span }}>
{data.number} {data.count}
</span> </span>
<button <button
onClick={() => onClick={() =>
data.number > 1 pushToCart({
? handleCounter("decrease", data.id) productId: data.productId,
: handleDelete(data.id) userId: id,
count: -1,
})
} }
style={{ fontSize: fontSize.mobile.counter.button }} style={{ fontSize: fontSize.mobile.counter.button }}
> >
@ -231,19 +250,26 @@ const Item = (props) => {
</TableRow> </TableRow>
) : null} ) : null}
{window.innerWidth > 1000 ? ( {window.innerWidth > 1000 ? (
<TableRow key={data.name}> <TableRow key={data.product.book.name}>
<TableCell align="right" component="th" scope="row"> <TableCell align="right" component="th" scope="row">
<div className="cart-item__info d-flex"> <div className="cart-item__info d-flex">
<img src={data.image} alt={data.title} /> <img
src={`https://dnvn.ir/api/v1/file/${data.product.book.fileIds}`}
alt={data.product.book.name}
/>
<div className="d-flex flex-column justify-content-center"> <div className="d-flex flex-column justify-content-center">
<strong style={{ fontSize: fontSize.desktop.info.strong }}> <strong style={{ fontSize: fontSize.desktop.info.strong }}>
{data.title} {`کتاب ${
data.product.productType === "1" ? "دیجیتال" : "فیزیکی"
}` +
" " +
data.product.book.name}
</strong> </strong>
<p style={{ fontSize: fontSize.desktop.info.p }}> <p style={{ fontSize: fontSize.desktop.info.p }}>
{data.subTitle} {data.product.book.category}
</p> </p>
<span style={{ fontSize: fontSize.desktop.info.span }}> <span style={{ fontSize: fontSize.desktop.info.span }}>
{data.options}بسته الحاقی: {data.product.book.items || "چیزی وارد نشده"}بسته الحاقی:
</span> </span>
</div> </div>
</div> </div>
@ -251,10 +277,10 @@ const Item = (props) => {
<TableCell> <TableCell>
<div className="cart-item__price d-flex flex-column justify-content-center align-items-center"> <div className="cart-item__price d-flex flex-column justify-content-center align-items-center">
<strong style={{ fontSize: fontSize.desktop.price.strong }}> <strong style={{ fontSize: fontSize.desktop.price.strong }}>
{data.price} تومان {data.product.book.price || "1000"} تومان
</strong> </strong>
<span style={{ fontSize: fontSize.desktop.price.span }}> <span style={{ fontSize: fontSize.desktop.price.span }}>
{data.slicePrice} قیمت هر واحد {data.product.book.subPrice || "100"} قیمت هر واحد
</span> </span>
</div> </div>
</TableCell> </TableCell>
@ -262,19 +288,27 @@ const Item = (props) => {
<div className="cart-item__counter d-flex align-items-center"> <div className="cart-item__counter d-flex align-items-center">
<div className="cart-item__counter--box d-flex justify-content-around align-items-center"> <div className="cart-item__counter--box d-flex justify-content-around align-items-center">
<button <button
onClick={() => handleCounter("increase", data.id)} onClick={() =>
pushToCart({
productId: data.productId,
userId: id,
count: 1,
})
}
style={{ fontSize: fontSize.desktop.counter.button }} style={{ fontSize: fontSize.desktop.counter.button }}
> >
+ +
</button> </button>
<span style={{ fontSize: fontSize.desktop.counter.span }}> <span style={{ fontSize: fontSize.desktop.counter.span }}>
{data.number} {data.count}
</span> </span>
<button <button
onClick={() => onClick={() =>
data.number > 1 pushToCart({
? handleCounter("decrease", data.id) productId: data.productId,
: handleDelete(data.id) userId: id,
count: -1,
})
} }
style={{ fontSize: fontSize.desktop.counter.button }} style={{ fontSize: fontSize.desktop.counter.button }}
> >
@ -287,10 +321,10 @@ const Item = (props) => {
<div className="cart-item__delete d-flex align-items-center justify-content-center"> <div className="cart-item__delete d-flex align-items-center justify-content-center">
<DeleteOutlineOutlinedIcon <DeleteOutlineOutlinedIcon
style={{ color: "#FC120A", fontSize: 30, marginLeft: 5 }} style={{ color: "#FC120A", fontSize: 30, marginLeft: 5 }}
onClick={() => handleDelete(data.id)} // onClick={() => handleDelete(data.id)}
/> />
<span <span
onClick={() => handleDelete(data.id)} // onClick={() => handleDelete(data.id)}
style={{ fontSize: fontSize.desktop.delete.span }} style={{ fontSize: fontSize.desktop.delete.span }}
> >
حذف حذف
@ -302,3 +336,12 @@ const Item = (props) => {
</> </>
); );
}; };
export default connect(
(state) => ({
loading: state.userProduct.loading,
info: state.book.info,
id: state.user.status.id,
}),
{ pushToCart: userProduct.add }
)(BasicTable);

@ -1,10 +1,15 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { connect } from "react-redux";
import { userProduct } from "~/Redux/actions";
import { ToastContainer } from "react-toastify";
import Navbar from "../Home/Navbar/index"; import Navbar from "../Home/Navbar/index";
import Footer from "../Home/Footer/index"; import Footer from "../Home/Footer/index";
import Table from "./Table/index"; import Table from "./Table/index";
import DiscoutCode from "./Discount/index"; import DiscoutCode from "./Discount/index";
import DeliveryMethod from "./DeliveryMethod/index"; import DeliveryMethod from "./DeliveryMethod/index";
import Factor from "./Factor/index"; import Factor from "./Factor/index";
import Loader from "~/components/Loader/index";
import sciense_6 from "../../assets/images/sciense-6.png"; import sciense_6 from "../../assets/images/sciense-6.png";
@ -33,7 +38,7 @@ const fontSize = {
input: window.innerWidth > maxMobileSize ? 16 : window.innerWidth / 20, input: window.innerWidth > maxMobileSize ? 16 : window.innerWidth / 20,
}, },
}; };
export default class Cart extends Component { class Cart extends Component {
state = { state = {
selectedDelivery: { name: "", price: 0 }, selectedDelivery: { name: "", price: 0 },
discount: 0, discount: 0,
@ -72,6 +77,10 @@ export default class Cart extends Component {
], ],
}; };
componentDidMount() {
this.props.getList();
}
handleCounter = (type, id) => { handleCounter = (type, id) => {
if (type === "increase") { if (type === "increase") {
this.setState((prevState) => ({ this.setState((prevState) => ({
@ -104,140 +113,173 @@ export default class Cart extends Component {
}; };
render() { render() {
const { list, payPrice } = this.props;
return ( return (
<> <>
{window.innerWidth > 1000 ? ( {window.innerWidth > 1000 ? (
<> list ? (
<div className="cart d-flex flex-column"> <>
<Navbar /> <div className="cart d-flex flex-column">
<div <Navbar />
className="d-flex" <div
style={{ width: "100%", flex: 1, marginBottom: 10 }} className="d-flex"
> style={{ width: "100%", flex: 1, marginBottom: 10 }}
<section className="cart__right d-flex flex-column"> >
<header> <section className="cart__right d-flex flex-column">
<h1 style={{ fontSize: fontSize.desktop.h1 }}>سبد خرید</h1> <header>
</header> <h1 style={{ fontSize: fontSize.desktop.h1 }}>
<Table سبد خرید
list={this.state.list} </h1>
handleCounter={this.handleCounter} </header>
handleDelete={this.handleDelete} <Table
/> list={list}
{this.state.totalPrice ? ( handleCounter={this.handleCounter}
<div className="cart__right--price d-flex justify-content-end"> handleDelete={this.handleDelete}
<div className="d-flex ml-2">جمع کل سبد خرید</div> payPrice={payPrice}
<div className="d-flex"> />
<strong>{this.state.totalPrice} تومان </strong> </section>
<section className="cart__left d-flex flex-column p-3">
<header className="cart__left--header d-flex flex-column">
<h2 style={{ fontSize: fontSize.desktop.h2 }}>
روشهای ارسال
</h2>
<div className="d-flex justify-content-between">
{this.props.payMethods.map((item, i) => (
<DeliveryMethod data={item} key={i} parent={this} />
))}
</div>
</header>
<DiscoutCode />
<Factor parent={this} />
<div className="cart__totalPrice d-flex align-items-center justify-content-center">
<h3 style={{ fontSize: fontSize.mobile.h2 }}>
جمع کل
<br />
سبد خرید
</h3>
<div className="d-flex align-items-center">
<strong style={{ fontSize: fontSize.mobile.h1 }}>
{payPrice}
</strong>
<span style={{ fontSize: fontSize.mobile.h3 }}>
تومان
</span>
</div> </div>
</div> </div>
) : null} <div className="cart__left--header d-flex flex-column mt-3">
</section> <h2 style={{ fontSize: fontSize.desktop.h2 }}>
<section className="cart__left d-flex flex-column p-3"> روشهای ارسال
<header className="cart__left--header d-flex flex-column"> </h2>
<h2 style={{ fontSize: fontSize.desktop.h2 }}> <p style={{ fontSize: fontSize.desktop.p }}>
روشهای ارسال با توجه به شرایط یکی از دو گزینه زیر را انتخاب کنید
</h2> </p>
<div className="d-flex justify-content-between"> <div className="d-flex justify-content-between">
{this.props.payMethods.map((item, i) => ( {this.props.payMethods.map((item, i) => (
<DeliveryMethod data={item} key={i} parent={this} /> <DeliveryMethod data={item} key={i} parent={this} />
))} ))}
</div> </div>
</header>
<DiscoutCode />
<Factor parent={this} />
<div className="cart__totalPrice d-flex align-items-center justify-content-center">
<h3 style={{ fontSize: fontSize.mobile.h2 }}>
جمع کل
<br />
سبد خرید
</h3>
<div className="d-flex align-items-center">
<strong style={{ fontSize: fontSize.mobile.h1 }}>
{this.totalPrice()}
</strong>
<span style={{ fontSize: fontSize.mobile.h3 }}>
تومان
</span>
</div>
</div>
<div className="cart__left--header d-flex flex-column mt-3">
<h2 style={{ fontSize: fontSize.desktop.h2 }}>
روشهای ارسال
</h2>
<p style={{ fontSize: fontSize.desktop.p }}>
با توجه به شرایط یکی از دو گزینه زیر را انتخاب کنید
</p>
<div className="d-flex justify-content-between">
{this.props.payMethods.map((item, i) => (
<DeliveryMethod data={item} key={i} parent={this} />
))}
</div> </div>
</div> <button className="cart__left--submit">پرداخت</button>
<button className="cart__left--submit">پرداخت</button> </section>
</section> </div>
</div> </div>
<Footer />
</>
) : (
<div
className="d-flex justify-content-center align-items-center"
style={{ height: "100vh", width: "100vw" }}
>
<Loader />
</div> </div>
<Footer /> )
</>
) : null} ) : null}
{window.innerWidth < 1000 ? ( {window.innerWidth < 1000 ? (
<div className="mobile-cart d-flex flex-column"> list ? (
<Navbar /> <div className="mobile-cart d-flex flex-column">
<h1 style={{ fontSize: fontSize.mobile.h1 }}>سبد خرید</h1> <Navbar />
<div className="d-flex"> <h1 style={{ fontSize: fontSize.mobile.h1 }}>سبد خرید</h1>
<Table <div className="d-flex">
list={this.state.list} <Table
handleCounter={this.handleCounter} list={this.state.list}
handleDelete={this.handleDelete} handleCounter={this.handleCounter}
/> handleDelete={this.handleDelete}
</div> />
<div className="mobile-cart__payMethods d-flex flex-column"> </div>
<h2 style={{ fontSize: fontSize.mobile.h2 }}>روشهای ارسال</h2> <div className="mobile-cart__payMethods d-flex flex-column">
<p style={{ fontSize: fontSize.mobile.p }}> <h2 style={{ fontSize: fontSize.mobile.h2 }}>روشهای ارسال</h2>
با توجه به شرایط یکی از دو گزینه زیر را انتخاب کنید <p style={{ fontSize: fontSize.mobile.p }}>
</p> با توجه به شرایط یکی از دو گزینه زیر را انتخاب کنید
</p>
<div className="d-flex justify-content-between"> <div className="d-flex justify-content-between">
{this.props.payMethods.map((item, i) => ( {this.props.payMethods.map((item, i) => (
<DeliveryMethod data={item} key={i} parent={this} /> <DeliveryMethod data={item} key={i} parent={this} />
))} ))}
</div>
</div> </div>
</div> <DiscoutCode parent={this} />
<DiscoutCode parent={this} /> <Factor parent={this} />
<Factor parent={this} /> <div className="mobile-cart__totalPrice d-flex align-items-center justify-content-center">
<div className="mobile-cart__totalPrice d-flex align-items-center justify-content-center"> <h3 style={{ fontSize: fontSize.mobile.h2 }}>
<h3 style={{ fontSize: fontSize.mobile.h2 }}> جمع کل
جمع کل <br />
<br /> سبد خرید
سبد خرید </h3>
</h3> <div className="d-flex align-items-center">
<div className="d-flex align-items-center"> <strong style={{ fontSize: fontSize.mobile.h1 }}>
<strong style={{ fontSize: fontSize.mobile.h1 }}> {this.totalPrice()}
{this.totalPrice()} </strong>
</strong> <span style={{ fontSize: fontSize.mobile.h3 }}>تومان</span>
<span style={{ fontSize: fontSize.mobile.h3 }}>تومان</span> </div>
</div> </div>
</div> <div className="mobile-cart__payMethods d-flex flex-column">
<div className="mobile-cart__payMethods d-flex flex-column"> <h2 style={{ fontSize: fontSize.mobile.h2 }}>روشهای ارسال</h2>
<h2 style={{ fontSize: fontSize.mobile.h2 }}>روشهای ارسال</h2> <p style={{ fontSize: fontSize.mobile.p }}>
<p style={{ fontSize: fontSize.mobile.p }}> با توجه به شرایط یکی از دو گزینه زیر را انتخاب کنید
با توجه به شرایط یکی از دو گزینه زیر را انتخاب کنید </p>
</p>
<div className="d-flex justify-content-between"> <div className="d-flex justify-content-between">
{this.props.payMethods.map((item, i) => ( {this.props.payMethods.map((item, i) => (
<DeliveryMethod data={item} key={i} parent={this} /> <DeliveryMethod data={item} key={i} parent={this} />
))} ))}
</div>
</div> </div>
<button className="mobile-cart__submit">پرداخت</button>
</div>
) : (
<div
className="d-flex justify-content-center align-items-center"
style={{ height: "100vh", width: "100vw" }}
>
<Loader />
</div> </div>
<button className="mobile-cart__submit">پرداخت</button> )
</div>
) : null} ) : null}
<ToastContainer
position="bottom-right"
autoClose={1500}
hideProgressBar={true}
newestOnTop={true}
closeOnClick
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</> </>
); );
} }
} }
export default connect(
(state) => ({
list: state.userProduct.list,
payPrice: state.userProduct.sum,
}),
{ getList: userProduct.list }
)(Cart);
Cart.defaultProps = { Cart.defaultProps = {
payMethods: [ payMethods: [
{ {

@ -1,4 +1,7 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { connect } from "react-redux";
import { publicApi } from "~/Redux/actions";
import Navbar from "../Home/Navbar/index"; import Navbar from "../Home/Navbar/index";
import Footer from "../Home/Footer/index"; import Footer from "../Home/Footer/index";
import Input from "./Input/index"; import Input from "./Input/index";
@ -7,6 +10,7 @@ import location from "../../assets/icons/location.png";
import home from "../../assets/icons/home.png"; import home from "../../assets/icons/home.png";
import contact from "../../assets/icons/contact.png"; import contact from "../../assets/icons/contact.png";
import Location from "./Location/Location"; import Location from "./Location/Location";
import Loader from "~/components/Loader/index";
import "./index.scss"; import "./index.scss";
@ -25,116 +29,151 @@ const fontSize = {
span: window.innerWidth > maxMobileSize ? 15 : window.innerWidth / 32, span: window.innerWidth > maxMobileSize ? 15 : window.innerWidth / 32,
}, },
}; };
export default class Contact extends Component {
class Contact extends Component {
componentDidMount() {
this.props.getContactData();
}
render() { render() {
const { loading, contactData } = this.props;
return ( return (
<> <>
{window.innerWidth > 1000 ? ( {window.innerWidth > 1000 ? (
<> !loading ? (
<div className="contact d-flex flex-column align-items-center"> <>
<Navbar page={"contact"} /> <div className="contact d-flex flex-column align-items-center">
<div className="contact__forms d-flex"> <Navbar page={"contact"} />
<div className="contact__forms--right d-flex flex-column"> <div className="contact__forms d-flex">
<h1 style={{ fontSize: fontSize.desktop.h1 }}>تماس با ما</h1> <div className="contact__forms--right d-flex flex-column">
<p style={{ fontSize: fontSize.desktop.p }}> <h1 style={{ fontSize: fontSize.desktop.h1 }}>
برای ارتباط با دنیای شگفت انگیز دانوین از فرم زیر استفاده تماس با ما
کنید و پس از انتخاب دپارتمان مد نظر پیام خود را ارسال کنید. </h1>
</p>
<Input label={"نامونام خانوادگی"} name={"name"} />
<Input label={"شماره تماس"} name={"mobile"} />
<Select options={["همه", "پرفروش"]} />
<Input label={"موضوع پیام"} name={"subject"} />
<textarea
placeholder="متن پیام"
name="description"
rows="5"
></textarea>
<button>ارسال</button>
</div>
<div className="contact__forms--left d-flex flex-column">
<div className="contact__location d-flex align-items-center">
<img src={location} alt="آدرس" className="m-1" />
<p style={{ fontSize: fontSize.desktop.p }}> <p style={{ fontSize: fontSize.desktop.p }}>
تهران خیابان انقلاب اسلامی بن بست سروش پلاک 2 طبقه چهار برای ارتباط با دنیای شگفت انگیز دانوین از فرم زیر استفاده
کنید و پس از انتخاب دپارتمان مد نظر پیام خود را ارسال
کنید.
</p> </p>
<Input label={"نامونام خانوادگی"} name={"name"} />
<Input label={"شماره تماس"} name={"mobile"} />
<Select options={["همه", "پرفروش"]} />
<Input label={"موضوع پیام"} name={"subject"} />
<textarea
placeholder="متن پیام"
name="description"
rows="5"
></textarea>
<button>ارسال</button>
</div> </div>
<div <div className="contact__forms--left d-flex flex-column">
className="d-flex align-items-center mt-1" <div className="contact__location d-flex align-items-center">
style={{ width: "55%", justifyContent: "space-between" }} <img src={location} alt="آدرس" className="m-1" />
> <p style={{ fontSize: fontSize.desktop.p }}>
<div className="d-flex align-items-center"> {contactData.address}
<span style={{ fontSize: fontSize.desktop.span }}> </p>
02163462405
</span>
<img src={contact} alt="تماس" className="m-1" />
</div> </div>
<div className="d-flex align-items-center"> <div
<span style={{ fontSize: fontSize.desktop.span }}> className="d-flex align-items-center mt-1"
Info@Danovin.ir style={{ width: "55%", justifyContent: "space-between" }}
</span> >
<img src={home} alt="خانه" className="m-1" /> <div className="d-flex align-items-center">
<span style={{ fontSize: fontSize.desktop.span }}>
{contactData.cellphone}
</span>
<img src={contact} alt="تماس" className="m-1" />
</div>
<div className="d-flex align-items-center">
<span style={{ fontSize: fontSize.desktop.span }}>
{contactData.email}
</span>
<img src={home} alt="خانه" className="m-1" />
</div>
</div>
<div className="contact__map d-flex align-items-center mt-3">
<Location />
</div> </div>
</div>
<div className="contact__map d-flex align-items-center mt-3">
<Location />
</div> </div>
</div> </div>
</div> </div>
<Footer />
</>
) : (
<div
className="d-flex justify-content-center align-items-center"
style={{ height: "100vh", width: "100vw" }}
>
<Loader />
</div> </div>
<Footer /> )
</>
) : null} ) : null}
{window.innerWidth < 1000 ? ( {window.innerWidth < 1000 ? (
<div className="mobile-contact d-flex flex-column align-items-center"> !loading ? (
<Navbar page={"contact"} /> <div className="mobile-contact d-flex flex-column align-items-center">
<div className="mobile-contact__form d-flex flex-column"> <Navbar page={"contact"} />
<h1 style={{ fontSize: fontSize.mobile.h1 }}>تماس با ما</h1> <div className="mobile-contact__form d-flex flex-column">
<p style={{ fontSize: fontSize.mobile.p }}> <h1 style={{ fontSize: fontSize.mobile.h1 }}>تماس با ما</h1>
برای ارتباط با دنیای شگفت انگیز دانوین از فرم زیر استفاده کنید و
پس از انتخاب دپارتمان مد نظر پیام خود را ارسال کنید.
</p>
<Input label={"نامونام خانوادگی"} name={"name"} />
<Input label={"شماره تماس"} name={"mobile"} />
<Select options={["همه", "پرفروش"]} />
<Input label={"موضوع پیام"} name={"subject"} />
<textarea
placeholder="متن پیام"
name="description"
rows="5"
></textarea>
<button>ارسال</button>
</div>
<div className="mobile-contact__address d-flex flex-column">
<div className="mobile-contact__address--location d-flex align-items-center">
<img src={location} alt="آدرس" className="m-1" />
<p style={{ fontSize: fontSize.mobile.p }}> <p style={{ fontSize: fontSize.mobile.p }}>
تهران خیابان انقلاب اسلامی بن بست سروش پلاک 2 طبقه چهار برای ارتباط با دنیای شگفت انگیز دانوین از فرم زیر استفاده کنید
و پس از انتخاب دپارتمان مد نظر پیام خود را ارسال کنید.
</p> </p>
<Input label={"نامونام خانوادگی"} name={"name"} />
<Input label={"شماره تماس"} name={"mobile"} />
<Select options={["همه", "پرفروش"]} />
<Input label={"موضوع پیام"} name={"subject"} />
<textarea
placeholder="متن پیام"
name="description"
rows="5"
></textarea>
<button>ارسال</button>
</div> </div>
<div <div className="mobile-contact__address d-flex flex-column">
className="d-flex align-items-center mt-1" <div className="mobile-contact__address--location d-flex align-items-center">
style={{ width: "55%", justifyContent: "space-between" }} <img src={location} alt="آدرس" className="m-1" />
> <p style={{ fontSize: fontSize.mobile.p }}>
<div className="d-flex align-items-center"> تهران خیابان انقلاب اسلامی بن بست سروش پلاک 2 طبقه چهار
<span style={{ fontSize: fontSize.mobile.span }}> </p>
02163462405
</span>
<img src={contact} alt="تماس" className="m-1" />
</div> </div>
<div className="d-flex align-items-center"> <div
<span style={{ fontSize: fontSize.mobile.span }}> className="d-flex align-items-center mt-1"
Info@Danovin.ir style={{ width: "55%", justifyContent: "space-between" }}
</span> >
<img src={home} alt="خانه" className="m-1" /> <div className="d-flex align-items-center">
<span style={{ fontSize: fontSize.mobile.span }}>
02163462405
</span>
<img src={contact} alt="تماس" className="m-1" />
</div>
<div className="d-flex align-items-center">
<span style={{ fontSize: fontSize.mobile.span }}>
Info@Danovin.ir
</span>
<img src={home} alt="خانه" className="m-1" />
</div>
</div>
<div className="mobile-contact__address--map d-flex align-items-center mt-3">
<Location />
</div> </div>
</div>
<div className="mobile-contact__address--map d-flex align-items-center mt-3">
{/* <Location /> */}
</div> </div>
</div> </div>
</div> ) : (
<div
className="d-flex justify-content-center align-items-center"
style={{ height: "100vh", width: "100vw" }}
>
<Loader />
</div>
)
) : null} ) : null}
</> </>
); );
} }
} }
export default connect(
(state) => ({
loading: state.publicApi.loading,
contactData: state.publicApi.contactData,
}),
{ getContactData: publicApi.getContactData }
)(Contact);

@ -1,4 +1,9 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { connect } from "react-redux";
import { userProduct } from "~/Redux/actions";
import { Link } from "react-router-dom";
import Loader from "~/components/Loader/index";
import "./index.scss"; import "./index.scss";
import document_red from "~/assets/icons/document-red.png"; import document_red from "~/assets/icons/document-red.png";
@ -18,8 +23,8 @@ const fontSize = {
}, },
}; };
export default function AddToCart(props) { function AddToCart(props) {
const { price, off, supportItems } = props; const { price, off, supportItems, page, loading, info } = props;
return ( return (
<> <>
{window.innerWidth > 1000 ? ( {window.innerWidth > 1000 ? (
@ -43,16 +48,37 @@ export default function AddToCart(props) {
مشاهده نمونه کتاب مشاهده نمونه کتاب
<img src={document_red} /> <img src={document_red} />
</button> </button>
<button <Link
to={`/products/${
page === "digital"
? `physical/${window.location.pathname.slice(
window.location.pathname.lastIndexOf("/") + 1,
window.location.pathname.length
)}`
: `digital/${window.location.pathname.slice(
window.location.pathname.lastIndexOf("/") + 1,
window.location.pathname.length
)}`
}`}
style={{ fontSize: fontSize.desktop.button }} style={{ fontSize: fontSize.desktop.button }}
className="product-addtocart__box--digitalButton" className="product-addtocart__box--digitalButton"
> >
خرید نسخه دیجیتال {page === "digital" ? "کتاب فیزیکی" : "نسخه دیجیتال"}
<img src={ebook_blue} /> <img src={ebook_blue} />
</button> </Link>
<button <button
style={{ fontSize: fontSize.desktop.button }} style={{ fontSize: fontSize.desktop.button }}
className="product-addtocart__box--addButton" className="product-addtocart__box--addButton"
onClick={() =>
props.pushToCart({
productId:
page === "digital"
? info.product[0].id
: info.product[1].id,
userId: props.id,
count: 1,
})
}
> >
افزودن به سبد خرید افزودن به سبد خرید
<img src={basket_white} /> <img src={basket_white} />
@ -79,3 +105,12 @@ export default function AddToCart(props) {
</> </>
); );
} }
export default connect(
(state) => ({
loading: state.userProduct.loading,
info: state.book.info,
id: state.user.status.id,
}),
{ pushToCart: userProduct.add }
)(AddToCart);

@ -26,6 +26,22 @@
} }
} }
} }
a {
font-family: numeralLight;
border-radius: 7px;
margin-bottom: 10px;
padding: 10px;
position: relative;
letter-spacing: -1px;
text-decoration: none;
text-align: center;
img {
position: absolute;
left: 13px;
top: 13px;
transform: scale(0.9);
}
}
button { button {
font-family: numeralLight; font-family: numeralLight;
border-radius: 7px; border-radius: 7px;
@ -39,6 +55,9 @@
top: 13px; top: 13px;
transform: scale(0.9); transform: scale(0.9);
} }
&:focus {
outline: none;
}
} }
&--sampleButton { &--sampleButton {
color: #ff1616; color: #ff1616;

@ -26,7 +26,7 @@ export default function Comment(props) {
{window.innerWidth < 1000 ? ( {window.innerWidth < 1000 ? (
<div className="mobile-comment d-flex flex-column"> <div className="mobile-comment d-flex flex-column">
<strong style={{ fontSize: fontSize.mobile.strong }}> <strong style={{ fontSize: fontSize.mobile.strong }}>
{comment.username} {comment.username || "حسین"}
</strong> </strong>
<p style={{ fontSize: fontSize.mobile.p }}>{comment.text}</p> <p style={{ fontSize: fontSize.mobile.p }}>{comment.text}</p>
<span style={{ fontSize: fontSize.mobile.span }}> <span style={{ fontSize: fontSize.mobile.span }}>
@ -40,7 +40,7 @@ export default function Comment(props) {
className="comment__user" className="comment__user"
style={{ fontSize: fontSize.desktop.strong }} style={{ fontSize: fontSize.desktop.strong }}
> >
{comment.username} {comment.username || "حسین"}
</strong> </strong>
<p className="comment__text" style={{ fontSize: fontSize.desktop.p }}> <p className="comment__text" style={{ fontSize: fontSize.desktop.p }}>
{comment.text} {comment.text}

@ -1,87 +1,112 @@
import React, { Component, useState } from 'react'; import React, { Component, useState } from "react";
import MoreHorizIcon from '@material-ui/icons/MoreHoriz'; import MoreHorizIcon from "@material-ui/icons/MoreHoriz";
import Video from '../../QR/VideoBox/React-video-js-player/index'; import Video from "../../QR/VideoBox/React-video-js-player/index";
import Modal from './Modal/index'; import Modal from "./Modal/index";
import './index.scss'; import "./index.scss";
export default function Gallery(props) { export default function Gallery(props) {
const [selectedMedia,setSelectedMedia] = useState(props.gallery[1]); const [selectedMedia, setSelectedMedia] = useState(props.gallery[0]);
const [modal, setModal] = useState(null); const [modal, setModal] = useState(null);
return( return (
<> <>
{ {window.innerWidth > 1000 ? (
window.innerWidth > 1000 ?
<section className="product-gallery d-flex flex-column"> <section className="product-gallery d-flex flex-column">
<div className="product-gallery__top"> <div className="product-gallery__top">
{ {selectedMedia ? (
selectedMedia ?
<> <>
{ {selectedMedia.type === "image" ? (
selectedMedia.type === 'image' ? <img
<img src={selectedMedia.value} alt={'عکس'} /> : null src={`https://dnvn.ir/api/v1/file/${selectedMedia.id}`}
} alt={"عکس"}
{ />
selectedMedia.type === 'film' ? ) : null}
<Video /> : null {selectedMedia.type === "film" ? <Video /> : null}
} </>
</> : null ) : null}
}
</div> </div>
<div className="product-gallery__list d-flex"> <div className="product-gallery__list d-flex">
{ {props.gallery.length > 3 ? (
props.gallery.length > 3 ?
<> <>
<Item active={selectedMedia === props.gallery[0]} item={props.gallery[0]} key={props.gallery[0].id} more={false} setSelectedMedia={setSelectedMedia} setModal={setModal} /> <Item
<Item active={selectedMedia === props.gallery[1]} item={props.gallery[1]} key={props.gallery[1].id} more={false} setSelectedMedia={setSelectedMedia} setModal={setModal} /> active={selectedMedia === props.gallery[0]}
<Item active={selectedMedia === props.gallery[2]} item={props.gallery[2]} key={props.gallery[2].id} more={true} setSelectedMedia={setSelectedMedia} setModal={setModal} /> item={props.gallery[0]}
</> : key={props.gallery[0].id}
more={false}
setSelectedMedia={setSelectedMedia}
setModal={setModal}
/>
<Item
active={selectedMedia === props.gallery[1]}
item={props.gallery[1]}
key={props.gallery[1].id}
more={false}
setSelectedMedia={setSelectedMedia}
setModal={setModal}
/>
<Item
active={selectedMedia === props.gallery[2]}
item={props.gallery[2]}
key={props.gallery[2].id}
more={true}
setSelectedMedia={setSelectedMedia}
setModal={setModal}
/>
</>
) : (
<> <>
{ {props.gallery.map((item, i) => (
props.gallery.map((item, i) => ( <Item
<Item active={selectedMedia === item} item={item} key={item.id} more={false} setSelectedMedia={setSelectedMedia} setModal={setModal} /> active={selectedMedia === item}
)) item={item}
} key={item.id}
more={false}
setSelectedMedia={setSelectedMedia}
setModal={setModal}
/>
))}
</> </>
} )}
</div> </div>
{ {modal ? (
modal ? <Modal first={modal} gallery={props.gallery} setModal={setModal} />
<Modal first={modal} gallery={props.gallery} setModal={setModal} /> : null ) : null}
} </section>
</section> : null ) : null}
}
</> </>
); );
} }
const Item = (props) => { const Item = (props) => {
const {item, more, setSelectedMedia, setModal, active} = props; const { item, more, setSelectedMedia, setModal, active } = props;
return( return (
<> <>
{ {window.innerWidth > 1000 ? (
window.innerWidth > 1000 ? <div
<div style={{ border: active ? '4px solid #1BBC6E' : ''}} className="product-gallery-item d-flex"> style={{ border: active ? "4px solid #1BBC6E" : "" }}
{ className="product-gallery-item d-flex"
item.type === 'image' ? >
<img src={item.value} alt={'عکس'} /> : null {item.type === "image" ? (
} <img src={`https://dnvn.ir/api/v1/file/${item.id}`} alt={"عکس"} />
{ ) : null}
item.type === 'film' ? {item.type === "film" ? (
<Video /> : null <Video fileId={`https://dnvn.ir/api/v1/file/${item.id}`} />
} ) : null}
{ {!more ? (
!more ? <div
<div className="product-gallery-item__cover" onClick={() => setSelectedMedia(item)}> className="product-gallery-item__cover"
onClick={() => setSelectedMedia(item)}
</div> : ></div>
<div className="product-gallery-item__cover product-gallery-item__more d-flex justify-content-center align-items-center" onClick={() => setModal(item)}> ) : (
<MoreHorizIcon style={{ fontSize: 60, color: 'white'}} /> <div
className="product-gallery-item__cover product-gallery-item__more d-flex justify-content-center align-items-center"
onClick={() => setModal(item)}
>
<MoreHorizIcon style={{ fontSize: 60, color: "white" }} />
</div> </div>
} )}
</div> : null </div>
} ) : null}
</> </>
); );
} };

@ -1,4 +1,6 @@
import React, { Component } from "react"; import React, { Component } from "react";
import { ToastContainer } from "react-toastify";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { book } from "~/Redux/actions"; import { book } from "~/Redux/actions";
@ -14,12 +16,6 @@ import HomeScroll from "../Home/HomeScroll/index";
import HomeSlider from "../Home/HomeSlider/index"; import HomeSlider from "../Home/HomeSlider/index";
import Loader from "~/components/Loader/index"; import Loader from "~/components/Loader/index";
import sciense_7 from "~/assets/images/sciense-7.png";
import sciense_6 from "~/assets/images/sciense-6.png";
import sciense_8 from "~/assets/images/sciense-8.png";
import sciense_9 from "~/assets/images/sciense-9.png";
import zist_10 from "~/assets/images/zist-10.png";
import film from "~/assets/Video/film.mp4";
import product_shipping from "~/assets/icons/product-shipping.png"; import product_shipping from "~/assets/icons/product-shipping.png";
import product_cash_back from "~/assets/icons/product-cash-back.png"; import product_cash_back from "~/assets/icons/product-cash-back.png";
import product_support from "~/assets/icons/product-support.png"; import product_support from "~/assets/icons/product-support.png";
@ -51,29 +47,40 @@ class Product extends Component {
window.location.pathname.length window.location.pathname.length
), ),
}); });
this.props.getList();
} }
render() { render() {
const { product, sameProducts, supportItems, info } = this.props; const { product, sameProducts, supportItems, info, page, loading, list } =
this.props;
return ( return (
<> <>
{window.innerWidth > 1000 ? ( {window.innerWidth > 1000 ? (
this.props.info ? ( info ? (
<> <>
<div className="product d-flex flex-column"> <div className="product d-flex flex-column">
<Navbar /> <Navbar />
<Breadcrumbs /> <Breadcrumbs />
<header className="product__header d-flex mt-4"> <header className="product__header d-flex mt-4">
<Gallery gallery={product.gallery} /> <Gallery gallery={info.files} />
<Info <Info
subTitle={product.subTitle} subTitle={info.category}
title={product.title} title={
description={product.description} page === "digital"
? info.product[0].name
: info.product[1].name
}
description={info.description || "توضیحات محصول خالیست"}
/> />
<AddToCart <AddToCart
supportItems={supportItems} supportItems={supportItems}
price={product.price} price={
off={product.off} page === "digital"
? info.product[0].price
: info.product[1].price
}
// off={product.off}
page={page}
/> />
</header> </header>
<div className="product__comments d-flex flex-column"> <div className="product__comments d-flex flex-column">
@ -88,10 +95,12 @@ class Product extends Component {
</div> </div>
<div className="product__comments--list d-flex flex-column"> <div className="product__comments--list d-flex flex-column">
<Comment comment={product.comments[0]} /> {info.comment.length > 0 ? (
<Comment comment={info.comment[0]} />
) : null}
</div> </div>
</div> </div>
<Identifier item={sameProducts} /> {0 ? <Identifier item={[]} /> : null}
</div> </div>
<Footer /> <Footer />
</> </>
@ -105,7 +114,7 @@ class Product extends Component {
) )
) : null} ) : null}
{window.innerWidth < 1000 ? ( {window.innerWidth < 1000 ? (
this.props.info ? ( info ? (
<> <>
<div className="mobile-product d-flex flex-column"> <div className="mobile-product d-flex flex-column">
<Navbar /> <Navbar />
@ -200,6 +209,17 @@ class Product extends Component {
</div> </div>
) )
) : null} ) : null}
<ToastContainer
position="bottom-right"
autoClose={1500}
hideProgressBar={true}
newestOnTop={true}
closeOnClick
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</> </>
); );
} }
@ -209,8 +229,10 @@ export default connect(
(state) => ({ (state) => ({
info: state.book.info, info: state.book.info,
// status: state.user.status, // status: state.user.status,
loading: state.book.loading,
list: state.book.list,
}), }),
{ getInfo: book.info } { getInfo: book.info, getList: book.list }
)(Product); )(Product);
Product.defaultProps = { Product.defaultProps = {
@ -219,175 +241,6 @@ Product.defaultProps = {
{ title: "پشتیبانی 24 ساعته ", icon: product_support }, { title: "پشتیبانی 24 ساعته ", icon: product_support },
{ title: "ضمانت بازگشت ", icon: product_cash_back }, { title: "ضمانت بازگشت ", icon: product_cash_back },
], ],
sameProducts: {
type: window.innerWidth > 1000 ? "slider" : "scroll",
title: "محصولات مرتبط",
moreText: "لیست کتابها",
height: window.innerWidth > 1000 ? 470 : 320,
design: window.innerWidth > 1000 ? "simple" : "product",
number: window.innerWidth > 1000 ? 4 : 2.8,
data: [
{
id: 0,
image: sciense_6,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه دهم ابتدایی",
price: "78.000",
oldPrice: "",
date: new Date(),
},
{
id: 1,
image: sciense_7,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه ششم ابتدایی",
price: "39.000",
oldPrice: "59.000",
date: new Date(),
},
{
id: 2,
image: sciense_8,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه ششم ابتدایی",
price: "21.000",
oldPrice: "",
},
{
id: 3,
image: sciense_9,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه دهم ابتدایی",
price: "",
oldPrice: "",
},
{
id: 4,
image: zist_10,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه هفتم ابتدایی",
price: "59.000",
oldPrice: "",
},
{
id: 5,
image: sciense_6,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه دهم ابتدایی",
price: "78.000",
oldPrice: "",
date: new Date(),
},
{
id: 6,
image: sciense_7,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه ششم ابتدایی",
price: "39.000",
oldPrice: "59.000",
date: new Date(),
},
{
id: 7,
image: sciense_8,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه ششم ابتدایی",
price: "21.000",
oldPrice: "",
date: new Date(),
},
{
id: 8,
image: sciense_9,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه دهم ابتدایی",
price: "",
oldPrice: "",
date: new Date(),
},
{
id: 9,
image: zist_10,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه هفتم ابتدایی",
price: "59.000",
oldPrice: "",
date: new Date(),
},
],
},
product: {
id: 1,
image: sciense_7,
title: "منفجر کردن مغز خود را به ما بسپارید",
subTitle: "پایه ششم ابتدایی",
price: "39.000",
off: "30%",
oldPrice: "59.000",
date: new Date(),
abstraction:
"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشت",
modules: [
"پک هدیه شامل یک عدد جلد سخت",
"عینک واقعیت مجازی",
"کارت گرافیک مناسب جهت اجرای بازی",
],
tips: [
"پک هدیه شامل یک عدد جلد سخت",
"عینک واقعیت مجازی",
"کارت گرافیک مناسب جهت اجرای بازی",
],
gallery: [
{ id: 0, value: film, type: "film" },
{ id: 1, value: sciense_6, type: "image" },
{ id: 2, value: sciense_7, type: "image" },
{ value: sciense_8, type: "image" },
],
description:
"لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشت",
comments: [
{
id: 0,
username: "محمدرضا",
date: new Date(),
text: "عالی بود. ممنون از سایت زیباتون",
score: 4,
reply: "ممنون از شما که به ما اعتماد کردید",
},
{
id: 1,
username: "محمدرضا",
date: new Date(),
text: "عالی بود. ممنون از سایت زیباتون",
score: 2.5,
reply: "",
},
{
id: 2,
username: "محمدرضا",
date: new Date(),
text: "عالی بود. ممنون از سایت زیباتون",
score: 5,
reply: "",
},
{
id: 3,
username: "محمدرضا",
date: new Date(),
text: "عالی بود. ممنون از سایت زیباتون",
score: 3.7,
reply: "",
},
{
id: 4,
username: "محمدرضا",
date: new Date(),
text: "عالی بود. ممنون از سایت زیباتون",
score: 2,
reply: "",
},
],
},
}; };
const Item = (props) => { const Item = (props) => {
@ -397,25 +250,36 @@ const Item = (props) => {
const Identifier = (props) => { const Identifier = (props) => {
return ( return (
<> <>
{props.item.type === "scroll" ? ( {window.innerWidth < 1000 ? (
<HomeScroll <HomeScroll
number={props.item.number} number={2.5}
height={props.item.height} // height={props.item.height}
title={props.item.title} title={"محصولات مشابه"}
data={props.item.data} data={props.item}
designType={props.item.design} designType={"product"}
moreText={props.item.moreText} moreText={"ّبیشتر"}
/> />
) : null} ) : null}
{props.item.type === "slider" ? ( {window.innerWidth > 1000 ? (
<HomeSlider <HomeSlider
designType={props.item.design} designType={"simple"}
number={props.item.number} number={"4"}
height={props.item.height} // height={props.item.height}
title={props.item.title} title={"محصولات مشابه"}
data={props.item.data} data={props.item}
/> />
) : null} ) : null}
<ToastContainer
position="bottom-right"
autoClose={1500}
hideProgressBar={true}
newestOnTop={true}
closeOnClick
rtl={true}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</> </>
); );
}; };

@ -37,36 +37,54 @@ export default class Product extends Component {
</div> </div>
<div className="mobile-products-product__links d-flex mt-2"> <div className="mobile-products-product__links d-flex mt-2">
<Link <Link
to={`/products/${product.id}`} to={`/products/physical/${product.id}`}
style={{ fontSize: fontSize.mobile.a }} style={{ fontSize: fontSize.mobile.a }}
className="mobile-products-product__links--physical" className="mobile-products-product__links--physical"
> >
اطلاعات بیشتر کتاب
{/* {!product.status.digital ? ( {/* {!product.status.digital ? (
<img src={basket} alt="افزودن به سبد خرید" /> <img src={basket} alt="افزودن به سبد خرید" />
) : null} */} ) : null} */}
</Link> </Link>
</div>
</div>
) : null}
{window.innerWidth > 1000 ? (
<article className="products-product d-flex flex-column align-items-center">
<Link to={`/products/${product.id}`}>
<img
src={`https://dnvn.ir/api/v1/file/${product.fileIds}`}
alt={product.name}
/>
<h1 style={{ fontSize: fontSize.desktop.h1 }}>{product.name}</h1>
<Link <Link
to={`/products/${product.id}`} to={`/products/digital/${product.id}`}
style={{ fontSize: fontSize.mobile.a }} style={{ fontSize: fontSize.mobile.a }}
className="products-product--physical" className="mobile-products-product__links--ar"
> >
اطلاعات بیشتر نسخه دیجیتال
{/* {!product.status.digital ? ( {/* {!product.status.digital ? (
<img src={basket} alt="افزودن به سبد خرید" /> <img src={basket} alt="افزودن به سبد خرید" />
) : null} */} ) : null} */}
</Link> </Link>
</div>
</div>
) : null}
{window.innerWidth > 1000 ? (
<article className="products-product d-flex flex-column align-items-center">
<img
src={`https://dnvn.ir/api/v1/file/${product.fileIds}`}
alt={product.name}
/>
<h1 style={{ fontSize: fontSize.desktop.h1 }}>{product.name}</h1>
<Link
to={`/products/physical/${product.id}`}
style={{ fontSize: fontSize.mobile.a }}
className="products-product--physical"
>
کتاب
{/* {!product.status.digital ? (
<img src={basket} alt="افزودن به سبد خرید" />
) : null} */}
</Link>
<Link
to={`/products/digital/${product.id}`}
style={{ fontSize: fontSize.mobile.a }}
className="products-product--ar"
>
نسخه دیجیتال
{/* {!product.status.digital ? (
<img src={basket} alt="افزودن به سبد خرید" />
) : null} */}
</Link> </Link>
</article> </article>
) : null} ) : null}

@ -3,24 +3,21 @@
padding: 10px; padding: 10px;
margin-bottom: 20px; margin-bottom: 20px;
text-align: center; text-align: center;
a {
&:hover {
}
img {
width: 100%; width: 100%;
text-decoration: none; height: 200px;
&:hover { border-radius: 30px;
} }
img { h1 {
width: 100%; font-family: numeralBold;
height: 200px; margin-top: 15px;
border-radius: 30px; color: #02a1a6;
} letter-spacing: -1px;
h1 { text-align: center;
font-family: numeralBold; margin-bottom: 15px;
margin-top: 15px;
color: #02a1a6;
letter-spacing: -1px;
text-align: center;
margin-bottom: 15px;
}
} }
&--physical { &--physical {
background-color: #7fc75d; background-color: #7fc75d;
@ -30,6 +27,13 @@
font-family: numeralMedium; font-family: numeralMedium;
text-decoration: none; text-decoration: none;
} }
&--ar {
border: 1px solid #7fc75d;
padding: 5px 3px;
border-radius: 7px;
color: #7fc75d;
margin-top: 10px;
}
} }
@media screen and (max-width: 350px) { @media screen and (max-width: 350px) {

@ -58,11 +58,11 @@ class Products extends Component {
render() { render() {
const { dateFilters, degreeFilters, firstFilters } = this.state; const { dateFilters, degreeFilters, firstFilters } = this.state;
const { loading, list } = this.props; const { loading, list, page } = this.props;
return ( return (
<> <>
{window.innerWidth > 1000 ? ( {window.innerWidth > 1000 ? (
!loading ? ( list ? (
<> <>
<div className="products d-flex flex-column"> <div className="products d-flex flex-column">
<Navbar page={"products"} /> <Navbar page={"products"} />
@ -90,7 +90,7 @@ class Products extends Component {
) )
) : null} ) : null}
{window.innerWidth < 1000 ? ( {window.innerWidth < 1000 ? (
!loading ? ( list ? (
<> <>
<div className="mobile-products d-flex flex-column"> <div className="mobile-products d-flex flex-column">
<Navbar page={"products"} /> <Navbar page={"products"} />

Loading…
Cancel
Save