reza added some options

temp
Reza_ashrafi 3 years ago
parent d4a7e5b8c7
commit 133361b9e0
  1. 4
      src/App.scss
  2. 8
      src/components/Footer/Bazar.svg
  3. 8
      src/components/Footer/IOS.svg
  4. 181
      src/components/Footer/index.js
  5. 3
      src/components/Input/index.js
  6. 2
      src/components/Navbar/index.js
  7. 55
      src/components/Product/index.js
  8. 6
      src/components/Select/index.js
  9. 8
      src/components/VodProduct/index.js
  10. 23
      src/redux/reducers/content.js
  11. 1
      src/redux/reducers/index.js
  12. 22
      src/redux/reducers/public.js
  13. 97
      src/views/Address/index.js
  14. 4
      src/views/Dashboard/index.js
  15. 46
      src/views/Dashboard/layouts/Main/UserItems/ProductSuggestion/index.js
  16. 30
      src/views/Dashboard/layouts/Main/UserItems/index.js
  17. 18
      src/views/Dashboard/layouts/Main/index.js
  18. 11
      src/views/Home/Desktop/index.js
  19. 57
      src/views/Home/Portrait/Private/MyBooks/index.js
  20. 54
      src/views/Home/Portrait/Private/Videos/index.js
  21. 8
      src/views/Products/index.js
  22. 6
      src/views/Products/layouts/Main.js

@ -18,6 +18,10 @@
direction: rtl; direction: rtl;
} }
.scrolling-carousel button{
display: none;
}
@font-face { @font-face {
font-family: Black; font-family: Black;
src: url("./assets/font/IranSansX/Farsi/Black.ttf"); src: url("./assets/font/IranSansX/Farsi/Black.ttf");

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 6.6 KiB

@ -1,59 +1,70 @@
import React from "react"; import React from "react";
import { Link } from "react-router-dom";
import _ from "lodash"; import _ from "lodash";
// import enamadlogo from './enamad-pic.svg'; // import enamadlogo from './enamad-pic.svg';
import callIcon from '../../assets/icons/vuesax-linear-call-calling.svg'; import callIcon from "../../assets/icons/vuesax-linear-call-calling.svg";
import samandehi from './samandehi-pic.svg'; import samandehi from "./samandehi-pic.svg";
import iosIcon from "./IOS.svg";
import bazarIcon from "./Bazar.svg";
import lightBlueLine from "./light-blue-line.svg"; import lightBlueLine from "./light-blue-line.svg";
const FooterDesign1 = ({ color, bg, items, hasHeader }) => {
const FooterDesign1 = ({ color, bg, links, hasHeader }) => {
const enamad = const enamad =
'<a referrerpolicy="origin" target="_blank" href="https://trustseal.enamad.ir/?id=224965&amp;Code=x8oNSO7tTnqAniyPpPyN"><img referrerpolicy="origin" src="https://Trustseal.eNamad.ir/logo.aspx?id=224965&amp;Code=x8oNSO7tTnqAniyPpPyN" alt="" style="cursor:pointer" id="x8oNSO7tTnqAniyPpPyN"></a>'; '<a referrerpolicy="origin" target="_blank" href="https://trustseal.enamad.ir/?id=224965&amp;Code=x8oNSO7tTnqAniyPpPyN"><img referrerpolicy="origin" src="https://Trustseal.eNamad.ir/logo.aspx?id=224965&amp;Code=x8oNSO7tTnqAniyPpPyN" alt="" style="cursor:pointer" id="x8oNSO7tTnqAniyPpPyN"></a>';
return ( return (
<> <>
{hasHeader ? {hasHeader ? (
<div className=" bg-gray-100 flex items-center justify-center py-6 text-blue52"> <div className=" bg-gray-100 w-full">
<div className="w-11/12 mx-auto flex items-center justify-between py-6 text-blue52">
<div className="flex items-center">
<div className="flex items-center ml-8 ">
<img src={callIcon} className="p-2" />
<div>
<h1 className="text-2xl mb-4 font-bold">
<span className=" text-blueC0 font-black">7</span> روز هفته{" "}
<span className="text-blueC0 font-black">24</span> ساعته
</h1>
<p className="text-lg font-light text-blue5F">
منتظر شنیدن صدای گرمتان هستیم
</p>
</div>
</div>
<div className="flex items-center ml-8 "> <div className="mr-8 text-lg font-black transform translate-y-0.5">
<img src={callIcon} className="p-2" /> <h1 className="text-left mb-5">654412 021</h1>
<div> <h1>Info[at]danovin.ir</h1>
<h1 className="text-2xl text-bold mb-2 font-black"> </div>
<span className=" text-blueC0">7</span> روز هفته <span className="font-black text-blueC0">24</span> ساعته </div>
</h1> <div className="flex items-center">
<p className="text-lg font-light text-blue-700">منتظر شنیدن صدای گرمتان هستیم</p> <img src={iosIcon} alt="" className="cursor-pointer" />
<a href="http://danovin.ir/app.apk" download>
<img src={bazarIcon} alt="" className="mr-6" />
</a>
</div> </div>
</div> </div>
<div className="mr-8 text-lg font-black">
<h1 className="text-left mb-2">654412 021</h1>
<h1>Info[at]danovin.ir</h1>
</div>
</div> </div>
: null} ) : null}
<footer <footer
className={`flex flex-col bg-gray-200 py-16 md:flex-row justify-around items-start md:items-start relative shadow-md ${bg}`} className={`flex flex-col bg-gray-200 py-16 md:flex-row justify-around items-start md:items-start relative shadow-md ${bg}`}
> >
<div className="w-11/12 flex justify-between"> <div className="w-11/12 flex justify-between">
<div className="flex items-start"> <div className="flex flex-row gap-10">
<> {items.map((item, index) => (
{ <div className="flex flex-col" key={index}>
links.map((section, index) => <ul className={index != 0 ? 'mr-16' : ''} key={index}> <strong className="text-xl text-gray70">{item.name}</strong>
{ <ul className="flex flex-col mt-0">
section.map((link, index) => <li {item.links.map((link, index) => (
className={`font-light text-md leading-7 hover:font-bold ${color}`} <li className="mt-6">
key={index} <Link className="text-gray70 text-base" to={link.link} key={index}>
> {link.name}
<a href="" className={`${index == 0 ? ' text-lg font-bold' : ''}`}>{link}</a> </Link>
</li>) </li>
} ))}
</ul>) </ul>
} </div>
</> ))}
</div> </div>
<div className="flex items-center justify-between mt-10 md:mt-0"> <div className="flex items-center justify-between mt-10 md:mt-0">
<div <div
@ -61,10 +72,12 @@ const FooterDesign1 = ({ color, bg, links, hasHeader }) => {
__html: enamad, __html: enamad,
}} }}
className="w-28 p-2 rounded-md bg-gray-300 mx-6" className="w-28 p-2 rounded-md bg-gray-300 mx-6"
> ></div>
<img
</div> src={samandehi}
<img src={samandehi} alt="" className="w-28 p-2 rounded-md bg-gray-300 mr-6" /> alt=""
className="w-28 p-2 rounded-md bg-gray-300 mr-6"
/>
</div> </div>
</div> </div>
{/* line {/* line
@ -73,7 +86,6 @@ const FooterDesign1 = ({ color, bg, links, hasHeader }) => {
alt="" alt=""
className="hidden sm:block absolute bottom-5 left-20" className="hidden sm:block absolute bottom-5 left-20"
/> */} /> */}
</footer> </footer>
</> </>
); );
@ -82,26 +94,71 @@ const FooterDesign1 = ({ color, bg, links, hasHeader }) => {
export default FooterDesign1; export default FooterDesign1;
FooterDesign1.defaultProps = { FooterDesign1.defaultProps = {
links: [ items: [
["لینک های اصلی", "فروشگاه", "درباره ما", "پرسش های متوالی"], {
[ name: "لینکهای اصلی",
"خدمات مشتریان", links: [
"شرایط و ضوابط استفاده", {
" راهنمای خرید", name: "فروشگاه",
"همکاری تجاری" link: "/products",
], },
[ {
"کاربری", name: "دربارهما",
"حساب کاربری", link: "/about-us",
"سبد خرید", },
"داشبورد کاربری" {
], name: "پرسشهای متداول",
[ link: "/faq",
"رضایت مشتریان", },
"رسیدگی به شکایات", ],
"پیگیری سفارشات" },
], {
name: "خدمات مشتریان",
links: [
{
name: "شرایط و ضوابط استفاده",
link: "#",
},
{
name: "راهنمای خرید",
link: "#",
},
{
name: "همکاری تجاری",
link: "#",
},
],
},
{
name: "کاربری",
links: [
{
name: "حساب کاربری",
link: "#",
},
{
name: "سبد خرید",
link: "/cart",
},
{
name: "داشبورد کاربری",
link: "/dashboard",
},
],
},
{
name: "رضایت مشتریان",
links: [
{
name: "رسیدگی به شکایات",
link: "/contact-us",
},
{
name: "پیگیری سفارشات",
link: "/orders",
},
],
},
], ],
bg: "bg-white", bg: "bg-white",
color: "text-gray-600", color: "text-gray-600",

@ -52,6 +52,7 @@ export default function Input(props) {
["input flex flex-col relative my-2 dark:bg-opacity-10 w-full", langDetector(lang, "fa", "en")], ["input flex flex-col relative my-2 dark:bg-opacity-10 w-full", langDetector(lang, "fa", "en")],
" " " "
)} )}
style={{width}}
> >
{/* <label {/* <label
className={_.join( className={_.join(
@ -92,7 +93,7 @@ export default function Input(props) {
], ],
" " " "
)} )}
style={{ direction: direction, width , }} style={{ direction: direction }}
onChange={(e) => onChange={(e) =>
onChange(name, (e.target.value = regex(e.target.value))) onChange(name, (e.target.value = regex(e.target.value)))
} }

@ -258,7 +258,7 @@ function Navbar({
{/* <img src={profileIcon} alt="" className="w-5 h-5" /> */} {/* <img src={profileIcon} alt="" className="w-5 h-5" /> */}
</div> </div>
)} )}
{1 && ( {!isLogin && (
<Link <Link
to="/signup" to="/signup"
className="bg-blueC0 text-white rounded-md px-4 py-3 text-sm mr-7 hover:bg-opacity-90 shadow-sm" className="bg-blueC0 text-white rounded-md px-4 py-3 text-sm mr-7 hover:bg-opacity-90 shadow-sm"

@ -1,7 +1,7 @@
import React, { useState } from "react"; import React, { useState } from "react";
import {Link} from 'react-router-dom'; import { Link } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import separate from '../../utils/separate'; import separate from "../../utils/separate";
import StarRating from "../StarRating"; import StarRating from "../StarRating";
// import Tag from "../Tag"; // import Tag from "../Tag";
// import ReactTooltip from "react-tooltip"; // import ReactTooltip from "react-tooltip";
@ -47,28 +47,27 @@ const ProductDesign = ({
productHolderHoverBorder, productHolderHoverBorder,
hoverMode, hoverMode,
starRate, starRate,
imageSize imageSize,
}) => { }) => {
const [isHovering, setIsHovering] = useState(false); const [isHovering, setIsHovering] = useState(false);
return ( return (
<Link to={'/products/' + product.id} <Link
className={`flex flex-wrap sm:flex-nowrap justify-around`} to={"/products/" + product.id}
className={`flex flex-wrap sm:flex-nowrap justify-around group`}
style={{ direction: "rtl" }} style={{ direction: "rtl" }}
> >
<div className="w-full flex flex-wrap items-center justify-around px-4"> <div className="w-full flex flex-wrap items-center justify-around">
<div <div
className={`w-full sm:w-60 md:w-72 rounded-lg transition-all p-2 my-3 ${productHolderBorder} ${ className={`w-full sm:w-60 md:w-72 rounded-lg p-2 my-3 hover:bg-grayF4 transition-all duration-500`}
hoverMode == "blue" ? "hover:bg-grayF4" : null
} ${productHolderBorderColor} hover:${productHolderHoverBorder} hover:`}
onMouseEnter={() => setIsHovering(true)} onMouseEnter={() => setIsHovering(true)}
onMouseLeave={() => setIsHovering(false)} onMouseLeave={() => setIsHovering(false)}
> >
{/* product image */} {/* product image */}
<div className="w-full relative"> <div className="w-full relative">
{/* icons on image */} {/* icons on image */}
<div className="absolute left-0 top-10"> <div className="w-full absolute left-0 top-10">
{discountPricePercent && ( {discountPricePercent && (
<div className="bg-discountPriceBg bg-white w-full p-2 px-3"> <div className="w-full bg-white p-2 px-3">
<p className="text-discountPriceTitle font-bold text-md text-blueC0"> <p className="text-discountPriceTitle font-bold text-md text-blueC0">
23<span>%</span> 23<span>%</span>
</p> </p>
@ -87,24 +86,22 @@ const ProductDesign = ({
</div> </div>
{/* img */} {/* img */}
<div <div
className={`w-11/12 flex bg-grayF4 p-0 justify-center rounded-lg`} className={`w-full flex bg-grayF4 p-0 justify-center rounded-lg group`}
> >
{verticalImg && ( <img
<img src={`https://dnvn.ir/api/v1/file/${product.fileIds}`}
src={`https://dnvn.ir/api/v1/file/${product.fileIds}`} alt=""
alt="" style={{
className="rounded-lg cursor-pointer py-5" height: `calc(100vh / ${imageSize})`,
style={{ width: `calc(100vh / ${imageSize} * 2 / 3.5)`,
height: `calc(100vh / ${imageSize})`, }}
width: `calc(100vh / ${imageSize} * 2 / 3.5)`, className="rounded-lg cursor-pointer py-5"
}} />
/>
)}
</div> </div>
</div> </div>
{/* product content */} {/* product content */}
<div className="px-2"> <div className="w-full px-2">
<div className="mt-4"> <div className="w-full mt-4">
<h2 <h2
className={`leading-5 text-tiny font-normal py-2 text-right text-blue5F`} className={`leading-5 text-tiny font-normal py-2 text-right text-blue5F`}
> >
@ -119,9 +116,7 @@ const ProductDesign = ({
</p> </p>
)} )}
{productCat && ( {productCat && (
<span <span className={`text-sm py-1 font-normal text-blueC0`}>
className={`text-sm py-1 font-normal text-blueC0`}
>
{"پایه" + " " + grades[product.gradeId]} {"پایه" + " " + grades[product.gradeId]}
</span> </span>
)} )}
@ -137,9 +132,7 @@ const ProductDesign = ({
)} )}
{/* price */} {/* price */}
{priceHolder && ( {priceHolder && (
<div <div className={`flex items-center justify-between mt-2`}>
className={`flex items-center justify-between mt-2 ${priceDirection}`}
>
<div className="mt-2"> <div className="mt-2">
<div <div
className={`${ className={`${

@ -8,14 +8,14 @@ function Select({
borderColor, borderColor,
backgroundColor, backgroundColor,
onChange, onChange,
name, name
}) { }) {
return ( return (
<div <div
className={`inline-block relative w-1/2 group ${margin} ${backgroundColor}`} className={`inline-block w-1/2 relative group ${margin} ${backgroundColor}`}
> >
<select <select
className={`text-gray70 text-xs block appearance-none bg-transparent w-full border border-solid px-4 py-3 pr-3 rounded-md leading-tight focus:outline-none focus:border-blueC0 focus:text-blueC0 ${borderColor}`} className={`text-gray70 text-tiny block appearance-none bg-transparent w-full border border-solid px-4 py-3 pr-3 rounded-md leading-tight focus:outline-none focus:border-blueC0 focus:text-blueC0 ${borderColor}`}
onChange={(e) => onChange(name, e.target.value)} onChange={(e) => onChange(name, e.target.value)}
> >
{options.map((option, index) => ( {options.map((option, index) => (

@ -145,9 +145,9 @@ const VodProduct = ({
{"دوره ویدیویی" + " " + video?.name} {"دوره ویدیویی" + " " + video?.name}
</h2> </h2>
{console.log(video?.gradeId)} {console.log(video?.gradeId)}
{/* <span className={`text-sm font-light text-blueC0`}> <span className={`text-sm font-light text-blueC0`}>
{ 'پایه' + ' ' + grades[video?.gradeId]} { 'پایه' + ' ' + grades[video?.gradeId]}
</span> */} </span>
</div> </div>
{productContent && ( {productContent && (
<p <p
@ -185,12 +185,12 @@ const VodProduct = ({
</p> </p>
)} */} )} */}
</div> </div>
<p {/* <p
className={`text-base font-semibold text-left`} className={`text-base font-semibold text-left`}
> >
{separate(video?.price) + ' '} {separate(video?.price) + ' '}
<span>تومان</span> <span>تومان</span>
</p> </p> */}
</div> </div>
{/* add to cart */} {/* add to cart */}
{addToCartHolder && ( {addToCartHolder && (

@ -0,0 +1,23 @@
import { toast } from "react-toastify";
const initialState = {
loading: false,
video: null,
listVOD: [],
};
export default function content(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "content/listVOD":
return {...state, loading: false, listVOD : data };
case "content/infoVOD":
return {...state, loading: false, video : data };
case "content/loading":
return { ...state, loading: true };
case "content/error":
toast.error(data.message);
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -4,6 +4,7 @@ export { default as user } from "./user";
export { default as book } from "./book"; export { default as book } from "./book";
export { default as blog } from "./blog"; export { default as blog } from "./blog";
export { default as product } from "./product"; export { default as product } from "./product";
export { default as content } from "./content";
export { default as userAddress } from "./userAddress"; export { default as userAddress } from "./userAddress";
export { default as faq } from "./faq"; export { default as faq } from "./faq";
export { default as file } from "./file"; export { default as file } from "./file";

@ -12,8 +12,8 @@ const initialState = {
arList: [], arList: [],
blogList: [], blogList: [],
blog: null, blog: null,
province: null, province: ["استان"],
city: null, city: ["شهر"],
departmans: [ departmans: [
{ {
id: 0, id: 0,
@ -62,6 +62,8 @@ const initialState = {
}, },
desktopContentTransform: false, desktopContentTransform: false,
overLayer: false, overLayer: false,
provinces: [],
cities : []
}; };
const grades = [ const grades = [
@ -170,9 +172,21 @@ export default function publicApi(state = initialState, action) {
case "public/setSubscribe": case "public/setSubscribe":
return { ...state, loading: false, error: null, selectedSubscribe: data }; return { ...state, loading: false, error: null, selectedSubscribe: data };
case "public/province": case "public/province":
return { ...state, loading: false, error: null, province: data }; return {
...state,
loading: false,
error: null,
province: [...state.province, ...data.map((item) => item.name)],
provinces : data
};
case "public/city": case "public/city":
return { ...state, loading: false, error: null, city: data }; return {
...state,
loading: false,
error: null,
city: [...state.city, ...data.map((item) => item.name)],
cities : data,
};
case "public/selectMenu": case "public/selectMenu":
return { ...state, loading: false, error: null, selectedMenu: data }; return { ...state, loading: false, error: null, selectedMenu: data };
case "public/VOD/homePage": case "public/VOD/homePage":

@ -1,13 +1,26 @@
import React, {useState} from "react"; import React, { useState, useEffect } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi } from "../../redux/actions";
import onInput from "../../utils/onInput";
import Input from "../../components/Input"; import Input from "../../components/Input";
import Select from "../../components/Select";
export const Address = ({}) => { export const Address = ({ city, province, getCity, getProvince }) => {
const [addressFields, setAddressFields] = useState({}); const [addressFields, setAddressFields] = useState({});
const onChange = (name, value) => {
} useEffect(() => {
if (province.length <= 1) {
getProvince();
}
}, []);
useEffect(() => {
if (addressFields?.provinceId) {
getCity({ provinceId: addressFields?.provinceId });
}
}, [addressFields]);
const onChange = (name, value) => {};
const Header = ({ title, text }) => { const Header = ({ title, text }) => {
return ( return (
@ -30,9 +43,9 @@ export const Address = ({}) => {
/> />
<div className="flex flex-row items-center gap-5 w-full"> <div className="flex flex-row items-center gap-5 w-full">
<Input <Input
width={{width : '50%'}} width="50%"
label={"نام"} label={"نام"}
regex={val => val} regex={(val) => val}
name="firstName" name="firstName"
onChange={(name, value) => onChange(name, value)} onChange={(name, value) => onChange(name, value)}
value={addressFields?.firstName} value={addressFields?.firstName}
@ -40,6 +53,7 @@ export const Address = ({}) => {
direction="rtl" direction="rtl"
/> />
<Input <Input
width="50%"
label={"نام خانوادگی"} label={"نام خانوادگی"}
regex={(val) => val} regex={(val) => val}
name="lastName" name="lastName"
@ -49,13 +63,78 @@ export const Address = ({}) => {
direction="rtl" direction="rtl"
/> />
</div> </div>
<br />
<br />
<Header
title="شماره تماس"
text="( شماره موبایل و شماره تلفن ثابت خود را
به همراه پیش شماره وارد کنید )"
/>
<div className="flex flex-row items-center gap-5 w-full">
<Input
width="50%"
label={"شماره موبایل"}
regex={(val) => onInput.numberOnly(val)}
name="cellphone"
onChange={(name, value) => onChange(name, value)}
value={addressFields?.cellphone}
align="text-right"
direction="ltr"
/>
<Input
width="50%"
label={"شماره تلفن"}
regex={(val) => onInput.numberOnly(val)}
name="tellphone"
onChange={(name, value) => onChange(name, value)}
value={addressFields?.lastName}
align="text-right"
direction="ltr"
/>
</div>
<br />
<br />
<Header
title="آدرس"
text="( لطفا نام استان و شهرستان و آدرس
خود را با دقت تکمیل نمایید )"
/>
<div className="flex flex-row items-center gap-5 w-full mt-3">
<Select
options={province}
name="provinceId"
onChange={(name, value) => onChange(name, value)}
/>
<Select
options={city}
name="cityId"
onChange={(name, value) => onChange(name, value)}
/>
</div>
<br />
<Input
width="50%"
label={"کد پستی"}
regex={(val) => onInput.numberOnly(val)}
name="tellphone"
onChange={(name, value) => onChange(name, value)}
value={addressFields?.lastName}
align="text-right"
direction="ltr"
/>
</div> </div>
</div> </div>
); );
}; };
const mapStateToProps = (state) => ({}); const mapStateToProps = (state) => ({
province: state.publicApi.province,
city: state.publicApi.city,
});
const mapDispatchToProps = {}; const mapDispatchToProps = {
getProvince: publicApi.getProvince,
getCity: publicApi.getCity,
};
export default connect(mapStateToProps, mapDispatchToProps)(Address); export default connect(mapStateToProps, mapDispatchToProps)(Address);

@ -7,9 +7,9 @@ export const Dashboard = ({ isMobile }) => {
return isMobile ? ( return isMobile ? (
<div className=""></div> <div className=""></div>
) : ( ) : (
<div className="h-screen w-full bg-grayF9 py-5"> <div className="w-full bg-grayF9 py-5">
<div className="gap-5 w-11/12 h-full mx-auto flex flex-row bg-transparent"> <div className="gap-5 w-11/12 h-full mx-auto flex flex-row bg-transparent">
<Sidebar /> {/* <Sidebar /> */}
<Main /> <Main />
</div> </div>
</div> </div>

@ -0,0 +1,46 @@
import React from "react";
import { Link } from "react-router-dom";
import { Carousel } from "@trendyol-js/react-carousel";
import Product from '../../../../../../components/Product';
import arrow from "../../../../../../assets/icons/slider-arrow.svg";
function Suggestion({ products, grades, isMobile }) {
return (
<div className="flex flex-col mt-8 px-4">
<strong className="text-blueC0 dark:text-white font-bold text-sm lg:text-base">
پیشنهادات ما به شما
</strong>
{products.length > 0 && (
<div className="relative w-full" style={{ direction: "ltr" }}>
<Carousel
show={Math.round(window.innerWidth / 300)}
slide={2}
swiping={true}
useArrowKeys={true}
transition={0.5}
rightArrow={
<img
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-2"
src={arrow}
alt=""
/>
}
>
{products.map((product, index) => (
<Product key={index} product={product} imageSize={4.5} />
))}
</Carousel>
</div>
)}
</div>
);
}
export default Suggestion;

@ -1,21 +1,35 @@
import React from "react"; import React, {useEffect} from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import {book} from '../../../../../redux/actions';
import MyBooks from "../../../../Home/Portrait/Private/MyBooks"; import MyBooks from "../../../../Home/Portrait/Private/MyBooks";
import Videos from "../../../../Home/Portrait/Private/Videos"; import Videos from "../../../../Home/Portrait/Private/Videos";
import ProductSuggestion from './ProductSuggestion';
export const UserItems = ({list, grades, getList, isMobile}) => {
export const UserItems = ({}) => { useEffect(() => {
if(list.length <= 0){
getList();
}
},[]);
return ( return (
<div className="flex-1 flex flex-col overflow-y-scroll"> <div className="w-full flex flex-col lg:pt-20">
<MyBooks /> <MyBooks books={list} grades={grades} />
<Videos /> <br/>
<Videos videos={list} grades={grades} />
<ProductSuggestion products={list} grades={grades} isMobile={isMobile} />
</div> </div>
); );
}; };
const mapStateToProps = (state) => ({}); const mapStateToProps = (state) => ({
list : state.book.list,
grades: state.publicApi.grades,
isMobile: state.publicApi.isMobile
});
const mapDispatchToProps = {}; const mapDispatchToProps = {
getList : book.list,
};
export default connect(mapStateToProps, mapDispatchToProps)(UserItems); export default connect(mapStateToProps, mapDispatchToProps)(UserItems);

@ -1,20 +1,26 @@
import React, { useState } from "react"; import React, { useState, useEffect } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import {publicApi} from '../../../../redux/actions';
import Orders from "../../../Orders"; import Orders from "../../../Orders";
import UserItems from "../Main/UserItems"; import UserItems from "../Main/UserItems";
export const Main = ({}) => { export const Main = ({setHeaderOptions}) => {
useEffect(() => {
setHeaderOptions({shown: true});
},[]);
const views = { const views = {
orders: <Orders />, // orders: <Orders />,
userItems: <UserItems /> userItems: <UserItems />
}; };
const [page, setPage] = useState("orders"); const [page, setPage] = useState("userItems");
return <div className="flex-1 py-2.5 overflow-y-scroll">{views[page]}</div>; return <div className="w-full py-2.5">{views[page]}</div>;
}; };
const mapStateToProps = (state) => ({}); const mapStateToProps = (state) => ({});
const mapDispatchToProps = {}; const mapDispatchToProps = {
setHeaderOptions: publicApi.setHeaderOptions,
};
export default connect(mapStateToProps, mapDispatchToProps)(Main); export default connect(mapStateToProps, mapDispatchToProps)(Main);

@ -1,8 +1,5 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { Link } from "react-router-dom";
import filterIcon from "../../../assets/images/vuesax-linear-filter-tick.svg";
import Banners from "../../../components/Banners";
import SalesContainer from "./SalesContainer"; import SalesContainer from "./SalesContainer";
import { book, publicApi, product } from "../../../redux/actions"; import { book, publicApi, product } from "../../../redux/actions";
@ -10,9 +7,8 @@ import Part2 from "./Part2";
import HomeImg from "../../../assets/images/HomeImg.png"; import HomeImg from "../../../assets/images/HomeImg.png";
import Part4 from "./Part4"; import Part4 from "./Part4";
import Design2D from "../../../components/Design2D"; import Design2D from "../../../components/Design2D";
import { get } from "lodash";
const DesktopHome = ({ grades, getBooks, books, getVODs, listVOD }) => { const DesktopHome = ({ grades, getBooks, books }) => {
const banners = [ const banners = [
{ {
flex: 4, flex: 4,
@ -57,7 +53,6 @@ const DesktopHome = ({ grades, getBooks, books, getVODs, listVOD }) => {
useEffect(() => { useEffect(() => {
getBooks(); getBooks();
getVODs();
},[]); },[]);
return ( return (
@ -76,7 +71,7 @@ const DesktopHome = ({ grades, getBooks, books, getVODs, listVOD }) => {
<div className="mb-16"> <div className="mb-16">
<img src={HomeImg} /> <img src={HomeImg} />
</div> </div>
<Part4 books={listVOD} grades={grades} /> <Part4 books={books} grades={grades} />
</div> </div>
); );
}; };
@ -88,12 +83,10 @@ const mapStateToProps = (state) => ({
gradeFilterBooks: state.book.gradeFilterBooks, gradeFilterBooks: state.book.gradeFilterBooks,
selectedGrade: state.book.selectedGrade, selectedGrade: state.book.selectedGrade,
grades: state.publicApi.grades, grades: state.publicApi.grades,
listVOD: state.product.listVOD
}); });
const mapDispatchToProps = { const mapDispatchToProps = {
getBooks: book.list, getBooks: book.list,
getVODs: product.listVOD,
gradeFilter: book.gradeFilter, gradeFilter: book.gradeFilter,
setHeaderOptions: publicApi.setHeaderOptions, setHeaderOptions: publicApi.setHeaderOptions,
}; };

@ -1,17 +1,13 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
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 { ScrollingCarousel } from "@trendyol-js/react-carousel";
import Progress from '../../../../../components/Progress'; import Progress from "../../../../../components/Progress";
function MyBooks({ list, getList, grades, isMobile }) { function MyBooks({ books, getList, grades, isMobile }) {
useEffect(() => { const Book = ({ book }) => {
getList();
}, []);
const Book = ({ book}) => {
return ( return (
<li className="flex flex-col"> <li className="flex flex-col lg:ml-6 lg:p-2 lg:border lg:border-solid lg:border-gray-200 lg:shadow-md lg:rounded-md">
<Link to={"/products/" + book.id}> <Link to={"/products/" + book.id}>
<img <img
src={`https://dnvn.ir/api/v1/file/${book.fileIds}`} src={`https://dnvn.ir/api/v1/file/${book.fileIds}`}
@ -21,11 +17,15 @@ function MyBooks({ list, getList, grades, isMobile }) {
height: isMobile ? "" : "calc(100vh / 5)", height: isMobile ? "" : "calc(100vh / 5)",
width: isMobile ? "" : "calc(100vh / 5 * 3 / 4)", width: isMobile ? "" : "calc(100vh / 5 * 3 / 4)",
minHeight: isMobile ? "calc(100vh / 5)" : "", minHeight: isMobile ? "calc(100vh / 5)" : "",
minWidth: isMobile ? "calc(100vh / 5 * 3 / 4)" : "" minWidth: isMobile ? "calc(100vh / 5 * 3 / 4)" : "",
}} }}
/> />
<h2 className="mt-2 text-sm lg:text-tiny font-semibold text-blue5F dark:text-white lg:mt-4">{book.name}</h2> <h2 className="mt-2 text-sm lg:text-tiny font-semibold text-blue5F dark:text-white lg:mt-4">
<p className="font-medium text-blueC0 dark:text-greenBA text-xs lg:text-sm mt-1 lg:mt-2">{`پایه ${grades[book.gradeId]}`}</p> {book.name}
</h2>
<p className="font-medium text-blueC0 dark:text-greenBA text-xs lg:text-sm mt-1 lg:mt-2">{`پایه ${
grades[book.gradeId]
}`}</p>
<Progress percent={60} /> <Progress percent={60} />
</Link> </Link>
</li> </li>
@ -33,24 +33,33 @@ function MyBooks({ list, getList, grades, isMobile }) {
}; };
return ( return (
<div className="w-full px-4 mb-5"> <div className="px-4 mb-5" style={{maxWidth: '100%'}}>
<div className="w-full flex flex-col rounded-md pt-4 lg:py-5 px-2 lg:px-4 bg-blueFF1 dark:bg-gray2077 overflow-hidden"> <div className="w-full flex flex-col rounded-md pt-4 lg:py-5 px-2 lg:px-4 bg-blueFF1 dark:bg-gray2077 overflow-hidden">
<strong className="text-blueC0 dark:text-white font-bold text-sm lg:text-base">کتابهای من</strong> <strong className="text-blueC0 dark:text-white font-bold text-sm lg:text-base">
<ul className="list-none w-full overflow-x-scroll pt-2 flex flex-row lg:pt-5 lg:flex-wrap lg:overflow-y-scroll gap-3 lg:gap-10"> کتابهای من
{list?.slice(0,5)?.map((book, index) => ( </strong>
<Book book={book} key={index} /> {isMobile ? (
))} <ul className="list-none w-full overflow-x-scroll pt-2 flex flex-row lg:pt-5 lg:flex-wrap lg:overflow-y-scroll gap-3 lg:gap-10">
</ul> {books?.slice(0, 5)?.map((book, index) => (
<Book book={book} key={index} />
))}
</ul>
) : (
<div className="w-full scrolling-carousel mt-4 pb-2">
<ScrollingCarousel className="py-3">
{books?.map((book, index) => (
<Book book={book} key={index} />
))}
</ScrollingCarousel>
</div>
)}
</div> </div>
</div> </div>
); );
} }
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
list: state.book.list, isMobile: state.publicApi.isMobile,
grades : state.publicApi.grades,
isMobile: state.publicApi.isMobile
}); });
export default connect(mapStateToProps, { getList: book.list })(MyBooks); export default connect(mapStateToProps)(MyBooks);

@ -1,37 +1,33 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { ScrollingCarousel } from "@trendyol-js/react-carousel";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { book } from "../../../../../redux/actions";
import Progress from "../../../../../components/Progress"; import Progress from "../../../../../components/Progress";
import arrowBlueIcon from "../../../../../assets/icons/arrow-right-blue.svg"; import arrowBlueIcon from "../../../../../assets/icons/arrow-right-blue.svg";
import arrowWhiteIcon from "../../../../../assets/icons/arrow-left-white.svg"; import arrowWhiteIcon from "../../../../../assets/icons/arrow-left-white.svg";
function Videos({ list, getList, grades, isDark, isMobile }) { function Videos({ videos, grades, isDark, isMobile }) {
useEffect(() => { const Video = ({ video }) => {
getList();
}, []);
const Book = ({ book }) => {
return ( return (
<li className="flex flex-col"> <li className="flex flex-col lg:ml-6 lg:p-2 lg:border lg:border-solid lg:border-gray-200 lg:shadow-md lg:rounded-md">
<Link to={"/products/" + book.id}> <Link to={"/products/" + video.id}>
<img <img
src={`https://dnvn.ir/api/v1/file/${book.fileIds}`} src={`https://dnvn.ir/api/v1/file/${video.posterId}`}
alt="" alt=""
className="rounded-sm" className="rounded-sm"
style={{ style={{
height: isMobile ? "" : "calc(100vw / 8 * 2 / 4)", height: isMobile ? "" : "calc(100vw / 8 * 2 / 4)",
width: isMobile ? "" : "calc(100vw / 8 )", width: isMobile ? "" : "calc(100vw / 8 )",
maxHeight: isMobile ? "calc(100vw / 2 * 2 / 3)" : "", maxHeight: isMobile ? "calc(100vw / 2 * 2 / 3)" : "",
minWidth: isMobile ? "calc(100vw / 2)" : "" minWidth: isMobile ? "calc(100vw / 2)" : "",
}} }}
/> />
<h2 className="mt-2 text-sm font-semibold text-blue5F dark:text-white lg:mt-4 lg:text-tiny"> <h2 className="mt-2 text-sm font-normal text-blue5F dark:text-white lg:mt-4 lg:text-tiny lg:mb-5">
{book.name} {'دوره ویدئویی' + ' ' + video.name}
</h2> </h2>
<p className="font-medium text-blueC0 dark:text-greenBA text-xs mt-1 lg:mt-2 lg:text-sm">{`پایه ${ {/* <p className="font-medium text-blueC0 dark:text-greenBA text-xs mt-1 lg:mt-2 lg:text-sm">{`پایه ${
grades[book.gradeId] grades[video.gradeId]
}`}</p> }`}</p> */}
<Progress percent={60} /> <Progress percent={60} />
</Link> </Link>
</li> </li>
@ -39,7 +35,7 @@ function Videos({ list, getList, grades, isDark, isMobile }) {
}; };
return ( return (
<div className="w-full px-4"> <div className="w-full px-4">
<div className="w-full flex flex-col py-4 lg:px-3 overflow-hidden lg:border lg:border-solid lg:border-gray-200 rounded-md"> <div className="w-full flex flex-col py-4 lg:px-3 overflow-hidden lg:border lg:border-solid lg:border-gray-200 rounded-md lg:bg-blueFF1">
<header className="w-full flex flex-row justify-between items-center"> <header className="w-full flex flex-row justify-between items-center">
<strong className="text-blueC0 dark:text-white font-bold text-sm lg:text-base"> <strong className="text-blueC0 dark:text-white font-bold text-sm lg:text-base">
دورههای ویدئویی شما دورههای ویدئویی شما
@ -50,21 +46,27 @@ function Videos({ list, getList, grades, isDark, isMobile }) {
className={`transform lg:hidden ${isDark ? "w-7" : "rotate-180"}`} className={`transform lg:hidden ${isDark ? "w-7" : "rotate-180"}`}
/> />
</header> </header>
<ul className="list-none w-full overflow-x-scroll pt-3 gap-3 lg:gap-5 flex flex-row lg:pt-5 lg:flex-wrap lg:overflow-y-scroll"> {isMobile ? (
{list.slice(0,5)?.map((book, index) => ( <ul className="list-none w-full overflow-x-scroll pt-3 gap-3 lg:gap-5 flex flex-row lg:pt-5 lg:flex-wrap lg:overflow-y-scroll">
<Book book={book} key={index} /> {videos.slice(0, 5)?.map((video, index) => (
))} <Video video={video} key={index} />
</ul> ))}
</ul>
) : (
<ScrollingCarousel className="mt-6 pb-3">
{videos?.map((video, index) => (
<Video video={video} key={index} />
))}
</ScrollingCarousel>
)}
</div> </div>
</div> </div>
); );
} }
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
list: state.book.list,
grades: state.publicApi.grades,
isDark: state.publicApi.isDark, isDark: state.publicApi.isDark,
isMobile: state.publicApi.isMobile isMobile: state.publicApi.isMobile,
}); });
export default connect(mapStateToProps, { getList: book.list })(Videos); export default connect(mapStateToProps)(Videos);

@ -5,14 +5,12 @@ import Search from "../../components/Search";
import Select from "../../components/Select"; import Select from "../../components/Select";
import Sidebar from "./layouts/Sidebar"; import Sidebar from "./layouts/Sidebar";
import Main from "./layouts/Main"; import Main from "./layouts/Main";
import { book, publicApi, product } from "../../redux/actions"; import { book, publicApi } from "../../redux/actions";
//assets //assets
import searchLight from "../../assets/icons/search-light.svg"; import searchLight from "../../assets/icons/search-light.svg";
export const Products = ({ export const Products = ({
getVODs,
listVOD,
isDark, isDark,
isMobile, isMobile,
books, books,
@ -37,7 +35,6 @@ export const Products = ({
useEffect(() => { useEffect(() => {
getList(); getList();
getVODs();
setHeaderOptions(headerOptions); setHeaderOptions(headerOptions);
}, []); }, []);
@ -164,8 +161,6 @@ export const Products = ({
<Sidebar onChange={onChange} /> <Sidebar onChange={onChange} />
<Main <Main
filter={filter} filter={filter}
listVOD={listVOD}
getVODs={getVODs}
books={books} books={books}
grades={grades} grades={grades}
/> />
@ -192,7 +187,6 @@ const mapDispatchToProps = {
getList: book.list, getList: book.list,
gradeFilter: book.gradeFilter, gradeFilter: book.gradeFilter,
setHeaderOptions: publicApi.setHeaderOptions, setHeaderOptions: publicApi.setHeaderOptions,
getVODs: product.listVOD,
}; };
export default connect(mapStateToProps, mapDispatchToProps)(Products); export default connect(mapStateToProps, mapDispatchToProps)(Products);

@ -11,7 +11,6 @@ import posterImage from "../../../assets/images/poster.svg";
import arrow from "../../../assets/icons/slider-arrow.svg"; import arrow from "../../../assets/icons/slider-arrow.svg";
export const Main = ({ export const Main = ({
listVOD,
books, books,
grades, grades,
gradeFilter, gradeFilter,
@ -62,7 +61,7 @@ export const Main = ({
))} ))}
</ul> </ul>
</div> </div>
{listVOD?.length > 0 && ( {books?.length > 0 && (
<div className="relative w-full" style={{ direction: "ltr" }}> <div className="relative w-full" style={{ direction: "ltr" }}>
<Carousel <Carousel
show={Math.round(window.innerWidth / 500)} show={Math.round(window.innerWidth / 500)}
@ -86,7 +85,7 @@ export const Main = ({
/> />
} }
> >
{listVOD?.map((video, index) => ( {books?.map((video, index) => (
<VodProduct <VodProduct
video={video} video={video}
key={index} key={index}
@ -141,7 +140,6 @@ const mapDispatchToProps = {
getList: book.list, getList: book.list,
gradeFilter: book.gradeFilter, gradeFilter: book.gradeFilter,
setHeaderOptions: publicApi.setHeaderOptions, setHeaderOptions: publicApi.setHeaderOptions,
getVODs: product.listVOD,
}; };
export default connect(mapStateToProps, mapDispatchToProps)(Main); export default connect(mapStateToProps, mapDispatchToProps)(Main);

Loading…
Cancel
Save