reza completed home page api

master
RezaAshrafi77 3 years ago
parent e810e8b89d
commit be2401b918
  1. 60
      src/components/GradeFilter/index.tsx
  2. 6
      src/components/HomeSearchBox/index.scss
  3. 63
      src/components/HomeSearchBox/index.tsx
  4. 16
      src/custom.scss
  5. 53
      src/redux/actions-type/book.tsx
  6. 28
      src/redux/actions-type/faq.tsx
  7. 4
      src/redux/actions-type/index.tsx
  8. 33
      src/redux/actions-type/product.tsx
  9. 5
      src/redux/actions/book.tsx
  10. 14
      src/redux/actions/content.tsx
  11. 18
      src/redux/actions/faq.tsx
  12. 6
      src/redux/actions/index.tsx
  13. 27
      src/redux/actions/product.tsx
  14. 2
      src/redux/actions/user.tsx
  15. 14
      src/redux/actions/userFactor.tsx
  16. 10
      src/redux/actions/userProduct.tsx
  17. 102
      src/redux/reducers/book.tsx
  18. 35
      src/redux/reducers/faq.tsx
  19. 4
      src/redux/reducers/index.tsx
  20. 29
      src/redux/reducers/product.tsx
  21. 18
      src/views/Auth/SignUp/index.tsx
  22. 17
      src/views/Faq/index.tsx
  23. 8
      src/views/Home/Books/Book/index.scss
  24. 10
      src/views/Home/Books/index.scss
  25. 16
      src/views/Home/Books/index.tsx
  26. 8
      src/views/Home/Courses/Course/index.scss
  27. 12
      src/views/Home/Courses/Course/index.tsx
  28. 11
      src/views/Home/Courses/index.scss
  29. 5
      src/views/Home/Courses/index.tsx
  30. 111
      src/views/Home/index.tsx
  31. 32
      src/views/Subscription/SubscribeRadio/index.tsx
  32. 30
      src/views/Subscription/index.tsx

@ -1,28 +1,31 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { connect } from "react-redux";
import { book } from "../../redux/actions";
import "./index.scss"; import "./index.scss";
import dropdown from "../../assets/icons/dropdown.png"; import dropdown from "../../assets/icons/dropdown.png";
export default function GradeFilter(props: any) { function GradeFilter({selectedGrade, gradeFilter, grades}: any) {
const [arrowTop, setArrowTop] = useState(false); const [arrowTop, setArrowTop] = useState(false);
const { grades, grade, setGrade } = props;
useEffect(() => { useEffect(() => {
setArrowTop(false); setArrowTop(false);
},[grade]) }, [selectedGrade]);
return ( return (
<section className="grade-filter d-flex align-items-center"> <section className="grade-filter d-flex align-items-center">
<h1 className="d-flex align-items-center"> <h1 className="d-flex align-items-center">
پایه تحصیلی پایه تحصیلی
{window.innerWidth > 1007 ? <span></span> : null} <span className="desktop"></span>
</h1> </h1>
<div <div
className="grade-filter__box d-flex" className="grade-filter__box d-flex"
onClick={() => setArrowTop(!arrowTop)} onClick={() => setArrowTop(!arrowTop)}
> >
{ {selectedGrade ? (
grade ? <h2>{grade}</h2> : <span>پایه تحصیلی خود را انتخاب نمائید</span> <h2>{grades[selectedGrade - 1].name}</h2>
} ) : (
<span>پایه تحصیلی خود را انتخاب نمائید</span>
)}
<img <img
src={dropdown} src={dropdown}
style={{ transform: !arrowTop ? "rotate(180deg)" : "rotate(0deg)" }} style={{ transform: !arrowTop ? "rotate(180deg)" : "rotate(0deg)" }}
@ -30,35 +33,38 @@ export default function GradeFilter(props: any) {
</div> </div>
{arrowTop ? ( {arrowTop ? (
<ul className="grade-filter__list d-flex flex-wrap"> <ul className="grade-filter__list d-flex flex-wrap">
{grades.map((item: String, i: any) => ( {grades.map((item: any, i: any) => (
<li <li
key={i} key={i}
onClick={(e) => onClick={() =>
grade !== item ? setGrade(item) : setGrade(null) gradeFilter(item.value)
} }
className={grade === item ? "grade-filter__list--active" : ""} className={selectedGrade === item.value ? "grade-filter__list--active" : ""}
> >
{item} {item.name}
</li> </li>
))} ))}
</ul> </ul>
) : null} ) : null}
{window.innerWidth > 1007 ? ( <ul className="desktop align-items-center">
<ul className="d-flex align-items-center"> {grades.map((item: any, i: any) => (
{grades.map((item: String, i: any) => ( <li
<li key={i}
key={i} onClick={(e) => gradeFilter(item.value)}
onClick={(e) => className={selectedGrade === item.value ? "grade-filter__active" : ""}
grade !== item ? setGrade(item) : setGrade(null) >
} {item.name}
className={grade === item ? "grade-filter__active" : ""} </li>
> ))}
{item} </ul>
</li>
))}
</ul>
) : null}
</section> </section>
); );
} }
export default connect(
(state: any) => ({
selectedGrade: state.book.selectedGrade,
}),
{ gradeFilter: book.gradeFilter }
)(GradeFilter);

@ -103,6 +103,9 @@
&__voice { &__voice {
display: none; display: none;
} }
&__searchIcon{
display: none;
}
form { form {
width: 85%; width: 85%;
input { input {
@ -147,7 +150,8 @@
&__searchIcon { &__searchIcon {
position: absolute; position: absolute;
left: 62px; left: 62px;
top: 9px; top: 50%;
transform: translateY(-50%);
width: 27px; width: 27px;
} }
form { form {

@ -1,25 +1,48 @@
import React, { useState } from "react"; import React, { useState } from "react";
import "./index.scss"; import "./index.scss";
import { connect } from "react-redux";
import { book } from "../../redux/actions";
import search from "../../assets/icons/search.png"; import search from "../../assets/icons/search.png";
import voice from "../../assets/icons/voice.png"; import voice from "../../assets/icons/voice.png";
export default function HomeSearchBox(props: any) { function HomeSearchBox({
const { lastItems, setVocal, inputValue, setInputValue } = props; lastItems,
setVocal,
inputValue,
setInputValue,
sortFilter,
selectedSort,
}: any) {
const submitInput = (value: any) => {
setInputValue(value);
sortFilter({ search: value, sort: selectedSort });
};
const submitSort = (value: any) => {
sortFilter({ search: inputValue, sort: value });
};
return ( return (
<section className="home-search-box d-flex flex-column align-items-center"> <section className="home-search-box d-flex flex-column align-items-center">
<form className="d-flex" onSubmit={(e) => e.preventDefault()}> <form className="d-flex" onSubmit={(e) => e.preventDefault()}>
<input <input
type="search" type="search"
placeholder="نام درس یا دوره را جستجو کنید" placeholder="نام درس یا دوره را جستجو کنید"
onChange={(e) => setInputValue(e.target.value)} onChange={(e) => submitInput(e.target.value)}
value={inputValue} value={inputValue}
/> />
<button type="submit"> <button
type="submit"
onClick={() => sortFilter({ search: inputValue, sort: selectedSort })}
>
<img src={search} /> <img src={search} />
</button> </button>
{window.innerWidth < 640 ? (
<img className="home-search-box__searchIcon" src={search} /> <img
) : null} className="mobile home-search-box__searchIcon"
src={search}
onClick={() => sortFilter({ search: inputValue, sort: selectedSort })}
/>
<button <button
className="home-search-box__voice" className="home-search-box__voice"
onClick={() => setVocal(true)} onClick={() => setVocal(true)}
@ -30,8 +53,12 @@ export default function HomeSearchBox(props: any) {
<ul className="d-flex"> <ul className="d-flex">
{lastItems.map((item: any, i: any) => ( {lastItems.map((item: any, i: any) => (
<li key={i} style={{ color: i === 0 ? "#9CDF52" : "" }}> <li
{item} key={i}
style={{ color: selectedSort === item.name ? "#9CDF52" : "" }}
onClick={() => sortFilter({ search: inputValue, sort: item.name })}
>
{item.name}
</li> </li>
))} ))}
</ul> </ul>
@ -39,6 +66,22 @@ export default function HomeSearchBox(props: any) {
); );
} }
export default connect(
(state: any) => ({
selectedSort: state.book.selectedSort,
}),
{ sortFilter: book.sortFilter }
)(HomeSearchBox);
HomeSearchBox.defaultProps = { HomeSearchBox.defaultProps = {
lastItems: ["دوره علوم تجربی", "دوره علوم انسانی", "تمامی دورهها"], lastItems: [
{
name: "تمامی دورهها",
icon: "",
},
{
name: "جدیدترینها",
icon: "",
},
],
}; };

@ -84,7 +84,21 @@
} }
.main { .main {
background: black; background: linear-gradient(
135deg,
hsla(0, 0%, 31%, 1) 0%,
hsla(0, 0%, 0%, 1) 100%
);
background: -moz-linear-gradient(
135deg,
hsla(0, 0%, 31%, 1) 0%,
hsla(0, 0%, 0%, 1) 100%
);
background: -webkit-linear-gradient(
135deg,
hsla(0, 0%, 31%, 1) 0%,
hsla(0, 0%, 0%, 1) 100%
);
width: 100%; width: 100%;
overflow-x: hidden; overflow-x: hidden;
padding-top: 60px; padding-top: 60px;

@ -1,34 +1,51 @@
interface list { interface list {
type : "book/list" type: "book/list";
data : any data: any;
} }
interface info{ interface info {
type : "book/info" type: "book/info";
data : any data: any;
} }
interface setLessonActive{ interface setLessonActive {
type : "book/lesson/active" type: "book/lesson/active";
data : any data: any;
} }
interface setVideoActive{ interface setVideoActive {
type : "book/video/active" type: "book/video/active";
data : any data: any;
} }
interface error{ interface gradeFilter {
type : "book/error" type: "book/gradeFilter";
data : undefined data: any;
} }
interface loading{ interface sortFilter {
type : "book/loading" type: "book/sortFilter";
data : undefined data: any;
} }
interface error {
type: "book/error";
data: undefined;
}
interface loading {
type: "book/loading";
data: undefined;
}
type BookAction = list | info | setVideoActive | setLessonActive | loading | error; type BookAction =
| list
| info
| setVideoActive
| setLessonActive
| gradeFilter
| sortFilter
| loading
| error;
export default BookAction; export default BookAction;

@ -0,0 +1,28 @@
interface list {
type : "faq/list"
data : any
}
interface add {
type : "faq/add"
data : any
}
interface selectFaq{
type : "faq/selectFaq"
data : any
}
interface error{
type : "faq/error"
data : undefined
}
interface loading{
type : "faq/loading"
data : undefined
}
type FaqAction = list | add | selectFaq | loading | error;
export default FaqAction;

@ -3,5 +3,9 @@ export type { default as PublicAction } from "./public";
export type { default as UserAction } from "./user"; export type { default as UserAction } from "./user";
export type { default as BookAction } from "./book"; export type { default as BookAction } from "./book";
export type { default as BlogAction } from "./blog"; export type { default as BlogAction } from "./blog";
export type { default as productAction } from "./product";
export type { default as FaqAction } from "./faq";

@ -0,0 +1,33 @@
interface ListVOD {
type : "product/listVOD"
data : any
}
interface AddVOD {
type : "product/addVOD"
data : any
}
interface DeleteVOD{
type : "product/deleteVOD"
data : any
}
interface SelectVOD{
type : "product/selectVOD"
data : any
}
interface error{
type : "product/error"
data : undefined
}
interface loading{
type : "product/loading"
data : undefined
}
type productAction = ListVOD | AddVOD | DeleteVOD | SelectVOD | loading | error;
export default productAction;

@ -9,11 +9,14 @@ const book = {
(data = {}) => (data = {}) =>
async (dispatch: Dispatch) => async (dispatch: Dispatch) =>
await proxy.get("book/info", data, { dispatch }), await proxy.get("book/info", data, { dispatch }),
setLessonActive: (data: undefined) => async (dispatch: Dispatch) => setLessonActive: (data: undefined) => async (dispatch: Dispatch) =>
await dispatch({ type: "book/lesson/active", data: data }), await dispatch({ type: "book/lesson/active", data: data }),
setVideoActive: (data: undefined) => async (dispatch: Dispatch) => setVideoActive: (data: undefined) => async (dispatch: Dispatch) =>
await dispatch({ type: "book/video/active", data: data }), await dispatch({ type: "book/video/active", data: data }),
gradeFilter: (data: undefined) => async (dispatch: Dispatch) =>
await dispatch({ type: "book/gradeFilter", data: data }),
sortFilter: (data: undefined) => async (dispatch: Dispatch) =>
await dispatch({ type: "book/sortFilter", data: data }),
// update: // update:
// (data = {}, data2 = {}) => // (data = {}, data2 = {}) =>
// async (dispatch : Dispatch) => { // async (dispatch : Dispatch) => {

@ -0,0 +1,14 @@
import proxy from "../proxy";
import { Dispatch } from "redux";
const content = {
listVOD:
(data = {}) =>
async (dispatch: Dispatch) =>
await proxy.get("content/listVOD", data, { dispatch }),
infoVOD:
(data = {}) =>
async (dispatch: Dispatch) =>
await proxy.get("content/infoVOD", data, { dispatch }),
};
export default content;

@ -0,0 +1,18 @@
import proxy from "../proxy";
import { Dispatch } from "redux";
const faq = {
list:
(data = {}) =>
async (dispatch: Dispatch) =>
await proxy.get("faq/list", data, { dispatch }),
add:
(data = {}) =>
async (dispatch: Dispatch) =>
await proxy.post("faq/add", data, { dispatch }),
selectFaq:
(data = {}) =>
async (dispatch: Dispatch) =>
await dispatch({ type: "faq/selectFaq", data: data }),
};
export default faq;

@ -3,6 +3,12 @@ export { default as publicApi } from "./public";
export { default as user } from "./user"; 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 userFactor } from "./userFactor";
export { default as userProduct } from "./userProduct";
export { default as content } from "./content";
export { default as faq } from "./faq";

@ -0,0 +1,27 @@
import proxy from "../proxy";
import { Dispatch } from "redux";
const product = {
listVOD:
(data = {}) =>
async (dispatch: Dispatch) =>
await proxy.get("product/listVOD", data, { dispatch }),
addVOD:
(data = {}, data2 = {}) =>
async (dispatch: Dispatch) => {
await proxy.post("product/addVOD", data);
await proxy.get("product/listVOD", data2, { dispatch });
},
deleteVOD:
(data = {}, data2 = {}) =>
async (dispatch: Dispatch) => {
await proxy.delete("product/deleteVOD", data);
await proxy.get("product/listVOD", data2, { dispatch });
},
selectVOD:
(data = {}) =>
async (dispatch: Dispatch) => {
await dispatch({ type: "product/selectVOD", data });
},
};
export default product;

@ -3,7 +3,7 @@ import {Dispatch} from 'redux';
const user = { const user = {
otp: (data : String) => async (dispatch : Dispatch) => otp: (data : String) => async (dispatch : Dispatch) =>
await proxy.login("public/sendOTP", data, { dispatch }), await proxy.post("public/sendOTP", data, { dispatch }),
otp_login: (data : Object) => async (dispatch : Dispatch) => otp_login: (data : Object) => async (dispatch : Dispatch) =>
await proxy.login("user/otp/login", data, { dispatch }), await proxy.login("user/otp/login", data, { dispatch }),

@ -0,0 +1,14 @@
import proxy from "../proxy";
import { Dispatch } from "redux";
const userFactor = {
payment:
(data = {}) =>
async (dispatch: Dispatch) =>
await proxy.get("userFactor/payment", data, { dispatch }),
verify:
(data = {}) =>
async (dispatch: Dispatch) =>
await proxy.get("userFactor/verify", data, { dispatch }),
};
export default userFactor;

@ -0,0 +1,10 @@
import proxy from "../proxy";
import { Dispatch } from "redux";
const userProduct = {
addVOD:
(data = {}) =>
async (dispatch : Dispatch) =>
await proxy.post("userProduct/addVOD", data, { dispatch }),
};
export default userProduct;

@ -201,19 +201,19 @@ const initialState = {
name: "درس اول", name: "درس اول",
files: [ files: [
{ {
id : 0, id: 0,
name: "ماهی های پرورشی و فواید آن ی", name: "ماهی های پرورشی و فواید آن ی",
src: sea, src: sea,
text: "لورم اپیوسرم یک متن آزمایشی است که برای", text: "لورم اپیوسرم یک متن آزمایشی است که برای",
}, },
{ {
id : 1, id: 1,
name: "ماهی های پرورشی و فواید آن ذ", name: "ماهی های پرورشی و فواید آن ذ",
src: sea, src: sea,
text: "لورم اپیوسرم یک متن آزمایشی است که برای", text: "لورم اپیوسرم یک متن آزمایشی است که برای",
}, },
{ {
id : 2, id: 2,
name: "ماهی های پرورشی و فواید آن ن", name: "ماهی های پرورشی و فواید آن ن",
src: sea, src: sea,
text: "لورم اپیوسرم یک متن آزمایشی است که برای", text: "لورم اپیوسرم یک متن آزمایشی است که برای",
@ -242,56 +242,60 @@ const initialState = {
], ],
}, },
], ],
attachments : [ attachments: [
{ {
name : "تمرین بخش اول از درس دوم", name: "تمرین بخش اول از درس دوم",
file : '' file: "",
}, },
{ {
name : "تمرین بخش اول از درس دوم", name: "تمرین بخش اول از درس دوم",
file : '' file: "",
}, },
{ {
name : "تمرین بخش اول از درس دوم", name: "تمرین بخش اول از درس دوم",
file : '' file: "",
}, },
{ {
name : "تمرین بخش اول از درس دوم", name: "تمرین بخش اول از درس دوم",
file : '' file: "",
}, },
{ {
name : "تمرین بخش اول از درس دوم", name: "تمرین بخش اول از درس دوم",
file : '' file: "",
}, },
{ {
name : "تمرین بخش اول از درس دوم", name: "تمرین بخش اول از درس دوم",
file : '' file: "",
}, },
] ],
}, },
selectedVideo : { selectedVideo: {
name: "ماهی های پرورشی و فواید آن ی", name: "ماهی های پرورشی و فواید آن ی",
src: sea, src: sea,
text: "لورم اپیوسرم یک متن آزمایشی است که برای", text: "لورم اپیوسرم یک متن آزمایشی است که برای",
}, },
comments : [ comments: [
{ {
id : 0, id: 0,
imageUrl : user1, imageUrl: user1,
name : 'حمد عظیمی', name: "حمد عظیمی",
text : 'متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد', text: "متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد",
repliedTo : null, repliedTo: null,
date : '1400/07/29', date: "1400/07/29",
}, },
{ {
id : 1, id: 1,
imageUrl : user2, imageUrl: user2,
name : 'حمد عظیمی', name: "حمد عظیمی",
text : 'متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد', text: "متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد",
repliedTo : null, repliedTo: null,
date : '1400/07/29', date: "1400/07/29",
}, },
] ],
gradeFilterBooks: null,
sortFilterCourse: null,
selectedGrade: null,
selectedSort: 'تمامی دورهها',
}; };
const grades = [ const grades = [
@ -349,13 +353,39 @@ export default function book(state = initialState, action: BookAction) {
: { ...item, active: false } : { ...item, active: false }
), ),
}; };
case "book/video/active": case "book/video/active":
return {
...state,
loading: false,
error: null,
selectedVideo: data,
};
case "book/gradeFilter":
if (data === state.selectedGrade) {
return { ...state, gradeFilterBooks: null, selectedGrade: null };
} else {
return { return {
...state, ...state,
loading: false, gradeFilterBooks: state.list.filter(
error: null, (item: any, i: any) => item.gradeId === data
selectedVideo : data, ),
selectedGrade: data,
}; };
}
case "book/sortFilter":
const search = state.list.filter(
(item: any) => item.name.indexOf(data.search) !== -1
);
if (data.sort === "تمامی دورهها") {
return { ...state, sortFilterCourse: search, selectedSort: data.sort };
}
else if(data.sort === 'جدیدترینها'){
return { ...state, sortFilterCourse: search.sort((item1 : any, item2 : any) => {
return item1.publishYear - item2.publishYear;
}), selectedSort: data.sort };
}
return { ...state, sortFilterCourse: search, selectedSort: data.sort };
// case "book/update": // case "book/update":
// return { ...state, loading: false, error: null }; // return { ...state, loading: false, error: null };
// case "book/add": // case "book/add":

@ -0,0 +1,35 @@
import { toast } from "react-toastify";
import { FaqAction } from "../actions-type";
const initialState = {
loading: false,
error: null,
list: [],
};
export default function faq(state = initialState, action: FaqAction) {
let { type, data } = action;
switch (type) {
case "faq/list":
return { ...state, loading: false, list: data, error: null };
case "faq/add":
return { ...state, loading: false, error: null };
case "faq/selectFaq":
return {
...state,
loading: false,
error: null,
list: state.list.map((item: any) =>
item.id === data
? { ...item, active: !item.active }
: { ...item, active: false }
),
};
case "faq/loading":
return { ...state, loading: true };
case "faq/error":
toast.error(data.message);
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -3,5 +3,5 @@ export { default as publicApi } from "./public";
export { default as user } from "./user"; 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 faq } from "./faq";

@ -0,0 +1,29 @@
import { toast } from "react-toastify";
import { productAction } from "../actions-type";
const initialState = {
loading: false,
error: null,
listVOD: [],
selectedVOD: null,
};
export default function product(state = initialState, action: productAction) {
let { type, data } = action;
switch (type) {
case "product/listVOD":
return { ...state, loading: false, listVOD: data, error: null };
case "product/addVOD":
return { ...state, loading: false, error: null };
case "product/deleteVOD":
return { ...state, loading: false, error: null };
case "product/selectVOD":
return {...state, selectedVOD : data};
case "product/loading":
return { ...state, loading: true };
case "product/error":
toast.error(data.message);
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -17,8 +17,7 @@ interface SignUpFields {
otp?: String; otp?: String;
} }
function SignUp({ sendOtp, sendPhoneNumber }: any) {
function SignUp({sendOtp, sendPhoneNumber} : any) {
const [level, setLevel] = useState("phonenumber"); const [level, setLevel] = useState("phonenumber");
const [signUpFields, setSignUpFiels] = useState<SignUpFields | undefined>( const [signUpFields, setSignUpFiels] = useState<SignUpFields | undefined>(
undefined undefined
@ -45,7 +44,12 @@ function SignUp({sendOtp, sendPhoneNumber} : any) {
const checkOtp = () => { const checkOtp = () => {
if (signUpFields?.otp?.length === 4) { if (signUpFields?.otp?.length === 4) {
sendOtp({ cellphone: signUpFields?.cellphone, otp : signUpFields?.otp }); sendOtp({
cellphone: signUpFields?.cellphone,
otp: signUpFields?.otp,
userToken: "2",
applicationToken: "22",
});
setError(undefined); setError(undefined);
} else { } else {
setError("کد وارد شده را چک کنید."); setError("کد وارد شده را چک کنید.");
@ -57,15 +61,15 @@ function SignUp({sendOtp, sendPhoneNumber} : any) {
useEffect(() => { useEffect(() => {
numberInput.current.focus(); numberInput.current.focus();
},[]); }, []);
useEffect(() => { useEffect(() => {
if(level === 'phonenumber'){ if (level === "phonenumber") {
numberInput.current.focus(); numberInput.current.focus();
}else{ } else {
otpInput.current.focus(); otpInput.current.focus();
} }
},[level]) }, [level]);
return ( return (
<div className="signup d-flex flex-column align-items-center justify-content-center"> <div className="signup d-flex flex-column align-items-center justify-content-center">

@ -5,12 +5,13 @@ import search from "../../assets/icons/search.png";
import dropdown from "../../assets/icons/dropdown.png"; import dropdown from "../../assets/icons/dropdown.png";
import whiteDropdown from "../../assets/icons/white-dropdown.png"; import whiteDropdown from "../../assets/icons/white-dropdown.png";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi } from "../../redux/actions"; import { faq } from "../../redux/actions";
import scroll from "../../util/scroll.js"; import scroll from "../../util/scroll.js";
import "./index.scss"; import "./index.scss";
function Faq({ list, setFaqActive }: any) { function Faq({ list, selectFaq, getList }: any) {
useEffect(() => { useEffect(() => {
getList();
scroll.goToTop(); scroll.goToTop();
}, []); }, []);
return ( return (
@ -32,13 +33,13 @@ function Faq({ list, setFaqActive }: any) {
</div> </div>
</header> </header>
<ul className="faq__list d-flex flex-column"> <ul className="faq__list d-flex flex-column">
{list.map((item: any, i: any) => ( {list?.map((item: any, i: any) => (
<li className="d-flex flex-column" key={i}> <li className="d-flex flex-column" key={i}>
<div <div
className="faq__list--itemHeader d-flex align-items-center justify-content-between p-4" className="faq__list--itemHeader d-flex align-items-center justify-content-between p-4"
onClick={() => setFaqActive(item.id)} onClick={() => selectFaq(item.id)}
> >
<strong>{item.name}</strong> <strong>{item.title}</strong>
{item.active ? ( {item.active ? (
<img src={dropdown} alt="" /> <img src={dropdown} alt="" />
) : ( ) : (
@ -47,7 +48,7 @@ function Faq({ list, setFaqActive }: any) {
</div> </div>
{item.active && ( {item.active && (
<div className="faq__list--itemBody d-flex px-4"> <div className="faq__list--itemBody d-flex px-4">
<p>{item.value}</p> <p>{item.description}</p>
</div> </div>
)} )}
</li> </li>
@ -61,7 +62,7 @@ function Faq({ list, setFaqActive }: any) {
export default connect( export default connect(
(state: any) => ({ (state: any) => ({
list: state.publicApi.faqList, list: state.faq.list,
}), }),
{ setFaqActive: publicApi.setFaqActive } { getList: faq.list, selectFaq: faq.selectFaq }
)(Faq); )(Faq);

@ -34,8 +34,7 @@
@media screen and (min-width : 1441px){ @media screen and (min-width : 1441px){
.home-books-book{ .home-books-book{
img{ img{
height: 200px; height: 300px;
width: 170px;
} }
h2{ h2{
font-size: 20px; font-size: 20px;
@ -52,8 +51,8 @@
@media screen and (min-width : 1008px) and (max-width : 1440px){ @media screen and (min-width : 1008px) and (max-width : 1440px){
.home-books-book{ .home-books-book{
img{ img{
height: 200px; height: 250px;
width: 100%; // width: 100%;
} }
h2{ h2{
font-size: calc(100vw / 80); font-size: calc(100vw / 80);
@ -71,7 +70,6 @@
.home-books-book{ .home-books-book{
img{ img{
height: 200px; height: 200px;
width : calc(100vw / 4);
border-bottom-left-radius: 25px !important; border-bottom-left-radius: 25px !important;
} }
h2{ h2{

@ -25,6 +25,13 @@
padding-right: 5px; padding-right: 5px;
color: green; color: green;
} }
&__list{
scrollbar-width: 0px;
&::-webkit-scrollbar{
display: none;
width: 0px;
}
}
} }
@media screen and (min-width: 1441px) { @media screen and (min-width: 1441px) {
@ -75,6 +82,9 @@
&__more{ &__more{
font-size: calc(100vw / 90); font-size: calc(100vw / 90);
} }
&__list{
overflow-x: scroll;
}
} }
} }

@ -5,7 +5,7 @@ import Book from "./Book/index";
import { book } from "../../../redux/actions"; import { book } from "../../../redux/actions";
import "./index.scss"; import "./index.scss";
function Books({list, number, getList}: any) { function Books({list, number}: any) {
const slideNumberHandler = () => { const slideNumberHandler = () => {
if (window.innerWidth >= 1440) { if (window.innerWidth >= 1440) {
return 5; return 5;
@ -18,17 +18,12 @@ function Books({list, number, getList}: any) {
} }
}; };
console.log(list);
useEffect(() => {
getList();
}, []);
return ( return (
<section <section
className="home-books d-flex flex-column" className="home-books d-flex flex-column"
onClick={() => getList()}
> >
{window.innerWidth > 1007 && list?.length > 0 ? ( {window.innerWidth > 1007 ? (
<Carousel <Carousel
itemsToShow={slideNumberHandler()} itemsToShow={slideNumberHandler()}
isRTL={true} isRTL={true}
@ -36,13 +31,13 @@ function Books({list, number, getList}: any) {
showArrows={true} showArrows={true}
pagination={false} pagination={false}
> >
{list?.map((item: Object, i: Number) => ( {list.map((item: Object, i: Number) => (
<Book data={item} key={i} /> <Book data={item} key={i} />
))} ))}
</Carousel> </Carousel>
) : ( ) : (
<div className="home-books__list d-flex"> <div className="home-books__list d-flex">
{list?.map((item: Object, i: Number) => ( {list.map((item: Object, i: Number) => (
<Book data={item} key={i} /> <Book data={item} key={i} />
))} ))}
</div> </div>
@ -53,7 +48,6 @@ function Books({list, number, getList}: any) {
export default connect( export default connect(
( state : any) => ({ ( state : any) => ({
list : state.book.list,
}), }),
{ getList: book.list } { }
)(Books); )(Books);

@ -33,7 +33,7 @@
@media screen and (min-width : 1441px){ @media screen and (min-width : 1441px){
.home-courses-course{ .home-courses-course{
img{ img{
height: 200px; height: 300px;
} }
h2{ h2{
font-size: 20px; font-size: 20px;
@ -50,7 +50,7 @@
@media screen and (min-width : 1008px) and (max-width : 1440px){ @media screen and (min-width : 1008px) and (max-width : 1440px){
.home-courses-course{ .home-courses-course{
img{ img{
width: 180px; height: 280px;
} }
h2{ h2{
font-size: calc(100vw / 80); font-size: calc(100vw / 80);
@ -67,7 +67,7 @@
@media screen and (min-width : 641px) and (max-width : 1007px){ @media screen and (min-width : 641px) and (max-width : 1007px){
.home-courses-course{ .home-courses-course{
img{ img{
height: 200px; height: 220px;
} }
h2{ h2{
font-size: calc(100vw / 60); font-size: calc(100vw / 60);
@ -84,7 +84,7 @@
@media screen and (max-width : 640px){ @media screen and (max-width : 640px){
.home-courses-course{ .home-courses-course{
img{ img{
width: calc(100vw / 1.9); height: 250px;
// height: calc(100vw / 2.2); // height: calc(100vw / 2.2);
} }
h2{ h2{

@ -8,18 +8,18 @@ export default function Course(props: any) {
const { data } = props; const { data } = props;
return ( return (
<Link to={`/courses/${data.id}`} className="home-courses-course d-flex flex-column" draggable={'false'}> <Link to={`/courses/${data.id}`} className="home-courses-course d-flex flex-column" draggable={'false'}>
<img src={data.imageUrl} alt={data.name} draggable={'false'} /> <img src={`https://dnvn.ir/api/v1/file/${data.fileIds}`} alt={data.name} draggable={'false'} />
<footer className="d-flex"> <footer className="d-flex">
<Avatar src={data.user} style={{ width: 40, height: 40 }} /> <Avatar src={`https://dnvn.ir/api/v1/file/${data.fileIds}`} style={{ width: 40, height: 40 }} />
<div className="home-courses-course__info d-flex flex-column"> <div className="home-courses-course__info d-flex flex-column">
<h2>{data.name}</h2> <h2>{data.name}</h2>
{window.innerWidth > 1007 ? ( {/* {window.innerWidth > 1007 ? (
<p>{data.text.slice(0, 100)}</p> <p>{data.text.slice(0, 100)}</p>
) : ( ) : (
<p>{data.text.slice(0, 50)}</p> <p>{data.text.slice(0, 50)}</p>
)} )} */}
<ul className="d-flex flex-wrap"> {/* <ul className="d-flex flex-wrap">
{data.tags.length <= 2 {data.tags.length <= 2
? data.tags.map((item: String, i: any) => <li key={i}>{item}</li>) ? data.tags.map((item: String, i: any) => <li key={i}>{item}</li>)
: null} : null}
@ -30,7 +30,7 @@ export default function Course(props: any) {
<li key={3}>+</li> <li key={3}>+</li>
</> </>
) : null} ) : null}
</ul> </ul> */}
</div> </div>
</footer> </footer>
</Link> </Link>

@ -33,6 +33,13 @@
color: #9CDF52; color: #9CDF52;
} }
} }
&__list{
scrollbar-width: 0px;
&::-webkit-scrollbar{
display: none;
width: 0px;
}
}
} }
@media screen and (min-width: 1441px) { @media screen and (min-width: 1441px) {
@ -83,7 +90,11 @@
&__more{ &__more{
font-size: calc(100vw / 90); font-size: calc(100vw / 90);
} }
&__list{
overflow-x: scroll;
}
} }
} }
@media screen and (max-width: 640px) { @media screen and (max-width: 640px) {

@ -1,11 +1,11 @@
import React from "react"; import React, {useEffect} from "react";
import Carousel from "react-elastic-carousel"; import Carousel from "react-elastic-carousel";
import Course from "./Course/index"; import Course from "./Course/index";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import ExpandMoreRoundedIcon from "@mui/icons-material/ExpandMoreRounded"; import ExpandMoreRoundedIcon from "@mui/icons-material/ExpandMoreRounded";
import "./index.scss"; import "./index.scss";
export default function Courses(props: any) { export default function Courses({number, courses} : any) {
const slideNumberHandler = () => { const slideNumberHandler = () => {
if (window.innerWidth >= 1440) { if (window.innerWidth >= 1440) {
return 4; return 4;
@ -17,7 +17,6 @@ export default function Courses(props: any) {
return 2; return 2;
} }
}; };
const { number, courses } = props;
return ( return (
<section className="home-courses d-flex flex-column"> <section className="home-courses d-flex flex-column">
<header className="d-flex justify-content-between"> <header className="d-flex justify-content-between">

@ -11,6 +11,8 @@ import Header from "./Header/index";
import AppDownload from "./AppDownload/index"; import AppDownload from "./AppDownload/index";
import Vocal from "../../components/Vocal/Vocal"; import Vocal from "../../components/Vocal/Vocal";
import scroll from "../../util/scroll"; import scroll from "../../util/scroll";
import { connect } from "react-redux";
import { book } from "../../redux/actions";
import olum7 from "../../assets/images/olum7.jpg"; import olum7 from "../../assets/images/olum7.jpg";
import olum8 from "../../assets/images/olum8.jpg"; import olum8 from "../../assets/images/olum8.jpg";
@ -20,17 +22,29 @@ import blog1 from "../../assets/images/blog1.png";
import blog2 from "../../assets/images/blog2.png"; import blog2 from "../../assets/images/blog2.png";
import blog3 from "../../assets/images/blog3.png"; import blog3 from "../../assets/images/blog3.png";
export default function Home({ courses, grades, headerData, blogs }: any) { function Home({
courseList,
getCourseList,
grades,
headerData,
blogs,
gradeFilterBooks,
sortFilterCourse,
selectedSort,
sortFilter
}: any) {
const [grade, setGrade] = useState(null); const [grade, setGrade] = useState(null);
const [vocal, setVocal] = useState(false); const [vocal, setVocal] = useState(false);
const [inputValue, setInputValue] = useState(""); const [inputValue, setInputValue] = useState("");
useEffect(() => { useEffect(() => {
if (inputValue) { if (inputValue) {
sortFilter({search : inputValue, sort : selectedSort});
setVocal(false); setVocal(false);
} }
}, [inputValue]); }, [inputValue]);
useEffect(() => { useEffect(() => {
getCourseList();
scroll.goToTop(); scroll.goToTop();
}, []); }, []);
return ( return (
@ -48,9 +62,9 @@ export default function Home({ courses, grades, headerData, blogs }: any) {
inputValue={inputValue} inputValue={inputValue}
setInputValue={setInputValue} setInputValue={setInputValue}
/> />
<Courses courses={courses} /> <Courses courses={sortFilterCourse ? sortFilterCourse : courseList} />
<GradeFilter grades={grades} grade={grade} setGrade={setGrade} /> <GradeFilter grades={grades} grade={grade} setGrade={setGrade} />
<Books courses={courses} /> <Books list={gradeFilterBooks ? gradeFilterBooks : courseList} />
<Blogs blogs={blogs} /> <Blogs blogs={blogs} />
<AppDownload /> <AppDownload />
<Footer /> <Footer />
@ -62,64 +76,65 @@ export default function Home({ courses, grades, headerData, blogs }: any) {
); );
} }
export default connect(
(state: any) => ({
courseList: state.book.list,
gradeFilterBooks: state.book.gradeFilterBooks,
sortFilterCourse: state.book.sortFilterCourse,
selectedSort: state.book.selectedSort,
}),
{ getCourseList: book.list, sortFilter: book.sortFilter }
)(Home);
Home.defaultProps = { Home.defaultProps = {
courses: [ grades: [
{ {
id: 0, name: "اول",
name: "فیزیک کوانتوم و موارد مشابه", value: 1,
text: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.",
imageUrl: olum7,
tags: ["دوره جدید", "تخفیفهای هفتگی", "پایه هفتم"],
}, },
{ {
id: 1, name: "دوم",
name: "فیزیک کوانتوم و موارد مشابه", value: 2,
text: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.",
imageUrl: olum8,
tags: ["دوره جدید", "تخفیفهای هفتگی", "پایه هفتم"],
}, },
{ {
id: 2, name: "سوم",
name: "فیزیک کوانتوم و موارد مشابه", value: 3,
text: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.",
imageUrl: olum9,
tags: ["دوره جدید", "تخفیفهای هفتگی", "پایه هفتم"],
}, },
{ {
id: 3, name: "چهارم",
name: "فیزیک کوانتوم و موارد مشابه", value: 4,
text: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.",
imageUrl: olum7,
tags: ["دوره جدید", "تخفیفهای هفتگی", "پایه هفتم"],
}, },
{ {
id: 4, name: "پنجم",
name: "فیزیک کوانتوم و موارد مشابه", value: 5,
text: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.",
imageUrl: olum8,
tags: ["دوره جدید", "تخفیفهای هفتگی", "پایه هفتم"],
}, },
{ {
id: 5, name: "ششم",
name: "فیزیک کوانتوم و موارد مشابه", value: 6,
text: "لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.", },
imageUrl: olum9, {
tags: ["دوره جدید", "تخفیفهای هفتگی", "پایه هفتم"], name: "هفتم",
value: 7,
},
{
name: "هشتم",
value: 8,
},
{
name: "نهم",
value: 9,
},
{
name: "دهم",
value: 10,
},
{
name: "یازدهم",
value: 11,
},
{
name: "دوازدهم",
value: 12,
}, },
],
grades: [
"اول",
"دوم",
"سوم",
"چهارم",
"پنجم",
"ششم",
"هفتم",
"هشتم",
"نهم",
"دهم",
"یازدهم",
"دوازدهم",
], ],
headerData: [ headerData: [
{ {

@ -4,20 +4,20 @@ import CustomCheckbox from "../../../components/CustomCheckbox";
import CircleRoundedIcon from "@mui/icons-material/CircleRounded"; import CircleRoundedIcon from "@mui/icons-material/CircleRounded";
import RadioButtonUncheckedRoundedIcon from "@mui/icons-material/RadioButtonUncheckedRounded"; import RadioButtonUncheckedRoundedIcon from "@mui/icons-material/RadioButtonUncheckedRounded";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi } from "../../../redux/actions"; import {product } from "../../../redux/actions";
function SubscribeRadio({ data, selectedSubscribe, setSubscribe }: any) { function SubscribeRadio({ data, selectedVOD, selectVOD }: any) {
return ( return (
<div <div
className={ className={
"subscribe-radio d-flex" + "subscribe-radio d-flex" +
" " + " " +
(selectedSubscribe.id === data.id ? "subscribe-radio-active" : "") (selectedVOD?.id === data.id ? "subscribe-radio-active" : "")
} }
onClick={() => onClick={() =>
selectedSubscribe.id === data.id selectedVOD?.id === data.id
? setSubscribe({}) ? selectVOD(null)
: setSubscribe(data) : selectVOD(data)
} }
> >
<div className="subscribe-radio__name d-flex align-items-center"> <div className="subscribe-radio__name d-flex align-items-center">
@ -32,27 +32,27 @@ function SubscribeRadio({ data, selectedSubscribe, setSubscribe }: any) {
style={{ color: "white", fontSize: 40, padding: 0 }} style={{ color: "white", fontSize: 40, padding: 0 }}
/> />
} }
checked={selectedSubscribe.id === data.id} checked={selectedVOD?.id === data.id}
/> />
<h2>{data.name}</h2> <h2>{data.name}</h2>
</div> </div>
<div className="subscribe-radio__factor d-flex flex-column justify-content-center"> <div className="subscribe-radio__factor d-flex flex-column justify-content-center">
{data.offPercent !== 0 && ( {/* {data.offPercent !== 0 && ( */}
<div className="subscribe-radio__factor--off d-flex align-items-center"> <div className="subscribe-radio__factor--off d-flex align-items-center">
<b> <b>
{data.off} {data.offerPrice}
<span></span> <span></span>
</b> </b>
<i>تومان</i> <i>تومان</i>
</div> </div>
)} {/* )} */}
<div className="subscribe-radio__factor--finalPrice d-flex align-items-center"> <div className="subscribe-radio__factor--finalPrice d-flex align-items-center">
<strong>{data.finalPrice}</strong> <strong>{data.price}</strong>
<i>تومان</i> <i>تومان</i>
</div> </div>
{data.offPercent !== 0 && ( {/* {data.offPercent !== 0 && ( */}
<span className="subscribe-radio__factor--tag">{`${data.offPercent}% تخفیف ویژه`}</span> {/* <span className="subscribe-radio__factor--tag">{`${30}% تخفیف ویژه`}</span> */}
)} {/* )} */}
</div> </div>
</div> </div>
); );
@ -60,7 +60,7 @@ function SubscribeRadio({ data, selectedSubscribe, setSubscribe }: any) {
export default connect( export default connect(
(state: any) => ({ (state: any) => ({
selectedSubscripe: state.publicApi.selectedSubscripe, selectedVOD: state.product.selectedVOD,
}), }),
{ setSubscribe: publicApi.setSubscribe } { selectVOD: product.selectVOD }
)(SubscribeRadio); )(SubscribeRadio);

@ -1,16 +1,18 @@
import React, {useEffect} from "react"; import React, { useEffect } from "react";
import Navbar from "../../components/Navbar/index"; import Navbar from "../../components/Navbar/index";
import Footer from "../../views/Home/Footer/index"; import Footer from "../../views/Home/Footer/index";
import SubscribeRadio from "./SubscribeRadio/index"; import SubscribeRadio from "./SubscribeRadio/index";
import DiscountCode from "./DiscountCode/index"; import DiscountCode from "./DiscountCode/index";
import {connect} from 'react-redux'; import { connect } from "react-redux";
import scroll from '../../util/scroll'; import { product } from "../../redux/actions";
import scroll from "../../util/scroll";
import "./index.scss"; import "./index.scss";
function Subscription({subscribes, selectedSubscribe} : any) { function Subscription({ listVOD, getList }: any) {
useEffect(() => { useEffect(() => {
getList();
scroll.goToTop(); scroll.goToTop();
},[]) }, []);
return ( return (
<div className="subscription main d-flex flex-column"> <div className="subscription main d-flex flex-column">
<Navbar /> <Navbar />
@ -21,11 +23,9 @@ function Subscription({subscribes, selectedSubscribe} : any) {
از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و از طراحان گرافیک است. چاپگرها و متون بلکه روزنامه و مجله در ستون و
سطرآنچنان که لازم است و برای شرایط{" "} سطرآنچنان که لازم است و برای شرایط{" "}
</p> </p>
{ {listVOD?.map((subscribe: any, i: any) => (
subscribes?.map((subscribe : any , i : any) => ( <SubscribeRadio data={subscribe} />
<SubscribeRadio data={subscribe} selectedSubscribe={selectedSubscribe} /> ))}
))
}
<DiscountCode /> <DiscountCode />
<div className="d-flex justify-content-end py-4"> <div className="d-flex justify-content-end py-4">
<button className="submit submit-large">تایید و پرداخت</button> <button className="submit submit-large">تایید و پرداخت</button>
@ -36,7 +36,9 @@ function Subscription({subscribes, selectedSubscribe} : any) {
); );
} }
export default connect((state : any) => ({ export default connect(
subscribes : state.publicApi.mockSubscribes, (state: any) => ({
selectedSubscribe : state.publicApi.selectedSubscribe listVOD: state.product.listVOD,
}), {})(Subscription); }),
{ getList: product.listVOD }
)(Subscription);

Loading…
Cancel
Save