reza added something

temp
Reza_ashrafi 3 years ago
parent 89e3085230
commit 5c7046df04
  1. 2
      src/components/Input/index.js
  2. 15
      src/components/VodProduct/index.js
  3. 1
      src/redux/actions/index.js
  4. 4
      src/redux/actions/user.js
  5. 33
      src/redux/actions/userAddress.js
  6. 1
      src/redux/reducers/index.js
  7. 2
      src/redux/reducers/user.js
  8. 35
      src/redux/reducers/userAddress.js
  9. 30
      src/utils/onInput.js
  10. 61
      src/views/Address/index.js
  11. 15
      src/views/Auth/Profile/index.js
  12. 26
      src/views/Auth/SignUp/index.js
  13. 4
      src/views/DeliveryForm/Address/index.js
  14. 12
      src/views/DeliveryForm/index.js
  15. 15
      src/views/Home/Desktop/index.js
  16. 25
      src/views/Products/index.js
  17. 21
      src/views/Products/layouts/Main.js
  18. 205
      src/views/ShoppingCart/index.js
  19. 8
      src/views/Video/index.js
  20. 2
      src/views/VideoDisplay/index.js

@ -49,7 +49,7 @@ export default function Input(props) {
return ( return (
<div <div
className={_.join( className={_.join(
["input flex flex-col relative my-2 dark:bg-opacity-10", langDetector(lang, "fa", "en")], ["input flex flex-col relative my-2 dark:bg-opacity-10 w-full", langDetector(lang, "fa", "en")],
" " " "
)} )}
> >

@ -1,5 +1,6 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import {Link} from 'react-router-dom'; import {Link} from 'react-router-dom';
import separate from '../../utils/separate';
import StarRating from "../StarRating"; import StarRating from "../StarRating";
import ReactTooltip from "react-tooltip"; import ReactTooltip from "react-tooltip";
@ -67,7 +68,7 @@ const VodProduct = ({
<> <>
{/* product UI Design */} {/* product UI Design */}
<Link <Link
to={'/videos/' + video?.id} to={'/videos/' + video?.bookId}
className="flex flex-wrap sm:flex-nowrap justify-around" className="flex flex-wrap sm:flex-nowrap justify-around"
style={{ direction: "rtl" }} style={{ direction: "rtl" }}
> >
@ -144,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
@ -184,12 +185,12 @@ const VodProduct = ({
</p> </p>
)} */} )} */}
</div> </div>
{/* <p <p
className={`text-sm font-semibold inline text-productPrice`} className={`text-base font-semibold text-left`}
> >
{video?.price} {separate(video?.price) + ' '}
<span>تومان</span> <span>تومان</span>
</p> */} </p>
</div> </div>
{/* add to cart */} {/* add to cart */}
{addToCartHolder && ( {addToCartHolder && (

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

@ -1,11 +1,11 @@
import proxy from "../proxy"; import proxy from "../proxy";
const user = { const user = {
otp: (data) => async (dispatch) => otp: (data = {}) => async (dispatch) =>
await proxy.post("public/sendOTP", data, { dispatch }), await proxy.post("public/sendOTP", data, { dispatch }),
otp_login: (data) => async (dispatch) => otp_login: (data) => async (dispatch) =>
await proxy.login("user/otp/login", data, { dispatch }), await proxy.login("user/otp/login", data, { dispatch }), //{cellphone, otp}
login: (data) => async (dispatch) => login: (data) => async (dispatch) =>
await proxy.login("user/login", data, { dispatch }), await proxy.login("user/login", data, { dispatch }),

@ -0,0 +1,33 @@
import proxy from "../proxy";
const userAddress = {
list:
(data = {}) =>
async (dispatch) => {
await proxy.get("userAddress/list", data, { dispatch });
},
info:
(data = {}) =>
async (dispatch) => {
await dispatch({ type: "userAddress/info", data });
},
update:
(data = {}, data2 = {}) =>
async (dispatch) => {
await proxy.put("userAddress/update", data);
await proxy.get("userAddress/list", data2, { dispatch });
},
add:
(data = {}, data2 = {}, data3 = {}) =>
async (dispatch) => {
await proxy.post("userAddress/add", data, { dispatch });
await proxy.get("userAddress/list", data2, { dispatch });
},
del:
(data = {}, data2 = {}) =>
async (dispatch) => {
await proxy.delete("userAddress/delete", data);
await proxy.get("userAddress/list", data2, { dispatch });
},
};
export default userAddress;

@ -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 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";
export { default as userFactor } from "./userFactor"; export { default as userFactor } from "./userFactor";

@ -19,7 +19,7 @@ export default function user(state = initialState, action) {
// case "user/register": // case "user/register":
// case "user/switchRole": // case "user/switchRole":
case "public/sendOTP": case "public/sendOTP":
return { ...state, loading: false, status: data.profile, error: null }; return { ...state, loading: false, error: null };
case "user/login": case "user/login":
case "user/otp/login": case "user/otp/login":
return { return {

@ -0,0 +1,35 @@
import { toast } from "react-toastify";
const initialState = {
loading: false,
error: null,
list: [],
info : null,
};
export default function userAddress(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "userAddress/list":
return {
...state,
loading: false,
list: data,
error: null,
};
case "userAddress/info":
return { ...state, loading: false, info: data, error: null };
case "userAddress/update":
return { ...state, loading: false, error: null };
case "userAddress/add":
return { ...state, loading: false, error: null, sum: data.payPrice };
case "userAddress/delete":
return { ...state, loading: false, error: null };
case "userAddress/loading":
return { ...state, loading: true };
case "userAddress/error":
toast.error(data.message);
return { ...state, loading: false, error: data.message };
default:
return state;
}
}

@ -80,16 +80,16 @@ class onInput {
englishAndNumberWithoutSpace = (txt) => { englishAndNumberWithoutSpace = (txt) => {
let newText = txt; let newText = txt;
newText = newText.replace(/`/g, ""); newText = newText.replace(/`/g, "");
newText = newText.replace(/0/g, "0"); newText = newText.replace(/۰/g, "0");
newText = newText.replace(/1/g, "1"); newText = newText.replace(/۱/g, "1");
newText = newText.replace(/2/g, "2"); newText = newText.replace(/۲/g, "2");
newText = newText.replace(/3/g, "3"); newText = newText.replace(/۳/g, "3");
newText = newText.replace(/4/g, "4"); newText = newText.replace(/۴/g, "4");
newText = newText.replace(/5/g, "5"); newText = newText.replace(/۵/g, "5");
newText = newText.replace(/6/g, "6"); newText = newText.replace(/۶/g, "6");
newText = newText.replace(/7/g, "7"); newText = newText.replace(/۷/g, "7");
newText = newText.replace(/8/g, "8"); newText = newText.replace(/۸/g, "8");
newText = newText.replace(/9/g, "9"); newText = newText.replace(/۹/g, "9");
newText = newText.replace(/ا/g, ""); newText = newText.replace(/ا/g, "");
newText = newText.replace(/ب/g, ""); newText = newText.replace(/ب/g, "");
newText = newText.replace(/پ/g, ""); newText = newText.replace(/پ/g, "");
@ -149,6 +149,16 @@ class onInput {
newText = newText.replace(/7/g, "7"); newText = newText.replace(/7/g, "7");
newText = newText.replace(/8/g, "8"); newText = newText.replace(/8/g, "8");
newText = newText.replace(/9/g, "9"); newText = newText.replace(/9/g, "9");
newText = newText.replace(/۰/g, "0");
newText = newText.replace(/۱/g, "1");
newText = newText.replace(/۲/g, "2");
newText = newText.replace(/۳/g, "3");
newText = newText.replace(/۴/g, "4");
newText = newText.replace(/۵/g, "5");
newText = newText.replace(/۶/g, "6");
newText = newText.replace(/۷/g, "7");
newText = newText.replace(/۸/g, "8");
newText = newText.replace(/۹/g, "9");
newText = newText.replace(/ا/g, ""); newText = newText.replace(/ا/g, "");
newText = newText.replace(/ب/g, ""); newText = newText.replace(/ب/g, "");
newText = newText.replace(/پ/g, ""); newText = newText.replace(/پ/g, "");

@ -0,0 +1,61 @@
import React, {useState} from "react";
import { connect } from "react-redux";
import Input from "../../components/Input";
export const Address = ({}) => {
const [addressFields, setAddressFields] = useState({});
const onChange = (name, value) => {
}
const Header = ({ title, text }) => {
return (
<div className="flex flex-row items-center gap-2 mb-4">
<strong className="text-blue5F text-base">{title}</strong>
<p className="mt-1 inline flex-1 text-sm text-gray70">{text}</p>
</div>
);
};
return (
<div
className="flex flex-row-reverse flex-1 pb-20 gap-5 divide-x divide-solid divide-gray-200"
style={{ minHeight: "calc(100vh - 500px)" }}
>
<div className="flex flex-col w-1/2"></div>
<div className="flex flex-col w-1/2 pl-4">
<Header
title="اطلاعات هویتی"
text="( لطفا نام و نام خانوادگی خود را به طور کامل وارد نمایید )"
/>
<div className="flex flex-row items-center gap-5 w-full">
<Input
width={{width : '50%'}}
label={"نام"}
regex={val => val}
name="firstName"
onChange={(name, value) => onChange(name, value)}
value={addressFields?.firstName}
align="text-right"
direction="rtl"
/>
<Input
label={"نام خانوادگی"}
regex={(val) => val}
name="lastName"
onChange={(name, value) => onChange(name, value)}
value={addressFields?.lastName}
align="text-right"
direction="rtl"
/>
</div>
</div>
</div>
);
};
const mapStateToProps = (state) => ({});
const mapDispatchToProps = {};
export default connect(mapStateToProps, mapDispatchToProps)(Address);

@ -13,8 +13,8 @@ import Birthdate from "./Birthdate";
import MultipleSelector from "./MultipleSelector"; import MultipleSelector from "./MultipleSelector";
import Document from "./Document"; import Document from "./Document";
function Profile({ function Profile({
isMobile,
profile, profile,
uploads, uploads,
getProvince, getProvince,
@ -187,7 +187,7 @@ function Profile({
// if (setDone) return <Navigate path="/" />; // if (setDone) return <Navigate path="/" />;
return ( return isMobile ? (
<div className="profile main d-flex justify-content-center"> <div className="profile main d-flex justify-content-center">
<main> <main>
<header className="d-flex align-items-center justify-content-between"> <header className="d-flex align-items-center justify-content-between">
@ -419,6 +419,16 @@ function Profile({
</div> </div>
</main> </main>
</div> </div>
) : (
<ul className="flex flex-col flex-1">
<li className="flex flex-row gap-5">
<div className="flex flex-col w-4/12">
<strong>اطلاعات هویتی</strong>
<p>لطفا نام و نام خانوادگی خود را به طور کامل وارد نمایید</p>
</div>
<div className="flex flex-row w-8/12"></div>
</li>
</ul>
); );
} }
@ -431,6 +441,7 @@ export default connect(
uploads: state.file.uploads, uploads: state.file.uploads,
provinceList: state.publicApi.province, provinceList: state.publicApi.province,
cityList: state.publicApi.city, cityList: state.publicApi.city,
isMobile: state.publicApi.isMobile,
}), }),
{ {
getProfile: user.getProfile, getProfile: user.getProfile,

@ -21,7 +21,7 @@ function SignUp({
setHeaderOptions, setHeaderOptions,
}) { }) {
const [level, setLevel] = useState("phonenumber"); const [level, setLevel] = useState("phonenumber");
const [signUpFields, setSignUpFiels] = useState({}); const [signUpFields, setSignUpFiels] = useState({});
const [error, setError] = useState(""); const [error, setError] = useState("");
const [resend, setResend] = useState(false); const [resend, setResend] = useState(false);
const navigate = useNavigate(); const navigate = useNavigate();
@ -152,7 +152,7 @@ function SignUp({
<Input <Input
label={"شماره موبایل"} label={"شماره موبایل"}
name="cellphone" name="cellphone"
regex={onInput.phonenumber} regex={onInput.numberOnly}
onChange={(name, value) => onChange(name, value)} onChange={(name, value) => onChange(name, value)}
value={signUpFields?.cellphone} value={signUpFields?.cellphone}
align="text-center" align="text-center"
@ -241,7 +241,7 @@ function SignUp({
onChange={(e) => onChange={(e) =>
onChange( onChange(
e.target.name, e.target.name,
(e.target.value = onInput.numberOnly(e.target.value)) (e.target.value = onInput.englishAndNumberWithoutSpace(e.target.value))
) )
} }
maxlength="1" maxlength="1"
@ -276,13 +276,17 @@ function SignUp({
); );
} }
const mapStateToProps = (state) => ({
loginFlag : state.user.status,
});
const mapDispatchToProps = {
sendOtp: user.otp_login,
sendPhoneNumber: user.otp,
setHeaderOptions: publicApi.setHeaderOptions,
};
export default connect( export default connect(
(state) => ({ mapStateToProps,
loginFlag: state.user.status, mapDispatchToProps
}),
{
sendOtp: user.otp_login,
sendPhoneNumber: user.otp,
setHeaderOptions: publicApi.setHeaderOptions,
}
)(SignUp); )(SignUp);

@ -3,7 +3,7 @@ import { connect } from "react-redux";
import Button from "../../../components/Button"; import Button from "../../../components/Button";
import Radio from "../../../components/Radio"; import Radio from "../../../components/Radio";
function Address({ addresses, isDark, isMobile }) { function Address({ addresses, isDark, isMobile, setPhase }) {
const [activeAddress, setActiveAddress] = useState(addresses[0]); const [activeAddress, setActiveAddress] = useState(addresses[0]);
const Location = ({ address }) => { const Location = ({ address }) => {
return isMobile ? ( return isMobile ? (
@ -97,7 +97,7 @@ function Address({ addresses, isDark, isMobile }) {
bgOpacity="bg-opacity-100" bgOpacity="bg-opacity-100"
width="100%" width="100%"
color={isDark ? "text-white" : "text-gray70"} color={isDark ? "text-white" : "text-gray70"}
onClick={() => {}} onClick={() => setPhase("address")}
/> />
</div> </div>
</section> </section>

@ -1,6 +1,6 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi, userFactor } from "../../redux/actions"; import { publicApi, userFactor, userAddress } from "../../redux/actions";
import Address from "./Address"; import Address from "./Address";
import TransportMethod from "./TransportMethod"; import TransportMethod from "./TransportMethod";
import TransportDate from "./TransportDate"; import TransportDate from "./TransportDate";
@ -10,6 +10,8 @@ import ExpressIcon from "../../assets/icons/express.svg";
import PishtazIcon from "../../assets/icons/pishtaz.svg"; import PishtazIcon from "../../assets/icons/pishtaz.svg";
export const DeliveryForm = ({ export const DeliveryForm = ({
getList,
list,
setHeaderOptions, setHeaderOptions,
headerOptions, headerOptions,
form, form,
@ -18,13 +20,14 @@ export const DeliveryForm = ({
userId, userId,
isDark, isDark,
isMobile, isMobile,
setPhase,
}) => { }) => {
useEffect(() => { useEffect(() => {
if (isMobile) { if (isMobile) {
setHeaderOptions(headerOptions); setHeaderOptions(headerOptions);
} }
getFactorInfo({ userId }); getFactorInfo({ userId });
getList();
}, []); }, []);
const PriceStatus = ({ name, value, type }) => { const PriceStatus = ({ name, value, type }) => {
@ -82,7 +85,7 @@ export const DeliveryForm = ({
<span className="w-6 h-6 rounded-full bg-grayF4 flex justify-center items-center text-sm"> <span className="w-6 h-6 rounded-full bg-grayF4 flex justify-center items-center text-sm">
1 1
</span> </span>
<Address addresses={form.addresses} /> <Address addresses={list} setPhase={setPhase} />
</div> </div>
<div className="w-full flex flex-row gap-5 mt-8"> <div className="w-full flex flex-row gap-5 mt-8">
<span className="w-6 h-6 rounded-full bg-grayF4 flex justify-center items-center text-sm"> <span className="w-6 h-6 rounded-full bg-grayF4 flex justify-center items-center text-sm">
@ -105,11 +108,14 @@ const mapStateToProps = (state) => ({
userId: state.user.status.id, userId: state.user.status.id,
isDark: state.publicApi.isDark, isDark: state.publicApi.isDark,
isMobile: state.publicApi.isMobile, isMobile: state.publicApi.isMobile,
list : state.userAddress.list
}); });
const mapDispatchToProps = { const mapDispatchToProps = {
setHeaderOptions: publicApi.setHeaderOptions, setHeaderOptions: publicApi.setHeaderOptions,
getFactorInfo: userFactor.info, getFactorInfo: userFactor.info,
getList: userAddress.list
}; };
export default connect(mapStateToProps, mapDispatchToProps)(DeliveryForm); export default connect(mapStateToProps, mapDispatchToProps)(DeliveryForm);

@ -5,14 +5,14 @@ import filterIcon from "../../../assets/images/vuesax-linear-filter-tick.svg";
import Banners from "../../../components/Banners"; import Banners from "../../../components/Banners";
import SalesContainer from "./SalesContainer"; import SalesContainer from "./SalesContainer";
import { book, publicApi } from "../../../redux/actions"; import { book, publicApi, product } from "../../../redux/actions";
import Part2 from "./Part2"; 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"; import { get } from "lodash";
const DesktopHome = ({ grades, getList, books }) => { const DesktopHome = ({ grades, getBooks, books, getVODs, listVOD }) => {
const banners = [ const banners = [
{ {
flex: 4, flex: 4,
@ -56,7 +56,8 @@ const DesktopHome = ({ grades, getList, books }) => {
]; ];
useEffect(() => { useEffect(() => {
getList(); getBooks();
getVODs();
},[]); },[]);
return ( return (
@ -75,7 +76,7 @@ const DesktopHome = ({ grades, getList, books }) => {
<div className="mb-16"> <div className="mb-16">
<img src={HomeImg} /> <img src={HomeImg} />
</div> </div>
<Part4 books={books} grades={grades} /> <Part4 books={listVOD} grades={grades} />
</div> </div>
); );
}; };
@ -86,11 +87,13 @@ const mapStateToProps = (state) => ({
books: state.book.list, books: state.book.list,
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 = {
getList: book.list, getBooks: book.list,
getVODs: product.listVOD,
gradeFilter: book.gradeFilter, gradeFilter: book.gradeFilter,
setHeaderOptions: publicApi.setHeaderOptions, setHeaderOptions: publicApi.setHeaderOptions,
}; };

@ -5,12 +5,14 @@ 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 } from "../../redux/actions"; import { book, publicApi, product } 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,
@ -23,21 +25,19 @@ export const Products = ({
headerOptions, headerOptions,
desktopContentTransform, desktopContentTransform,
}) => { }) => {
const [filter, setFilter] = useState({ const [filter, setFilter] = useState({
search: "", search: "",
grade: "", grade: "",
productsType: "کتاب", productsType: "کتاب",
}); });
const onChange = (name, value) => { const onChange = (name, value) => {
setFilter({ ...filter, [name]: value }); setFilter({ ...filter, [name]: value });
}; };
useEffect(() => { useEffect(() => {
getList(); getList();
getVODs();
setHeaderOptions(headerOptions); setHeaderOptions(headerOptions);
}, []); }, []);
@ -45,8 +45,6 @@ export const Products = ({
gradeFilter(filter.grade); gradeFilter(filter.grade);
}, [filter]); }, [filter]);
const Product = ({ productsType, product, index }) => { const Product = ({ productsType, product, index }) => {
return ( return (
<> <>
@ -80,7 +78,7 @@ export const Products = ({
<img <img
src={"https://dnvn.ir/api/v1/file/" + product?.fileIds} src={"https://dnvn.ir/api/v1/file/" + product?.fileIds}
className="w-full rounded-md mb-2" className="w-full rounded-md mb-2"
style={{height : "calc(100vh / 5)"}} style={{ height: "calc(100vh / 5)" }}
/> />
<strong className="text-blue5F dark:text-white text-tiny font-bold mb-2"> <strong className="text-blue5F dark:text-white text-tiny font-bold mb-2">
{product?.name} {product?.name}
@ -149,7 +147,6 @@ export const Products = ({
/> />
)) ))
: books?.map((product, index) => ( : books?.map((product, index) => (
<Product <Product
key={index} key={index}
productsType={filter.productsType} productsType={filter.productsType}
@ -164,8 +161,14 @@ export const Products = ({
className={`w-full flex flex-row gap-10 px-5 overflow-y-hidden mt-3 justify-center`} className={`w-full flex flex-row gap-10 px-5 overflow-y-hidden mt-3 justify-center`}
> >
<div className="w-11/12 flex flex-row gap-5"> <div className="w-11/12 flex flex-row gap-5">
<Sidebar onChange={onChange}/> <Sidebar onChange={onChange} />
<Main filter={filter}/> <Main
filter={filter}
listVOD={listVOD}
getVODs={getVODs}
books={books}
grades={grades}
/>
</div> </div>
</div> </div>
)} )}
@ -178,6 +181,7 @@ const mapStateToProps = (state) => ({
isDark: state.publicApi.isDark, isDark: state.publicApi.isDark,
isMobile: state.publicApi.isMobile, isMobile: state.publicApi.isMobile,
books: state.book.list, books: state.book.list,
listVOD: state.product.listVOD,
grades: state.publicApi.grades, grades: state.publicApi.grades,
gradeFilterBooks: state.book.gradeFilterBooks, gradeFilterBooks: state.book.gradeFilterBooks,
selectedGrade: state.book.selectedGrade, selectedGrade: state.book.selectedGrade,
@ -188,6 +192,7 @@ 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);

@ -6,11 +6,12 @@ import { Carousel } from "@trendyol-js/react-carousel";
import filterIcon from "../../../assets/images/vuesax-linear-filter-tick.svg"; import filterIcon from "../../../assets/images/vuesax-linear-filter-tick.svg";
import Product from "../../../components/Product"; import Product from "../../../components/Product";
import VodProduct from "../../../components/VodProduct"; import VodProduct from "../../../components/VodProduct";
import { book, publicApi } from "../../../redux/actions"; import { book, publicApi, product } from "../../../redux/actions";
import posterImage from "../../../assets/images/poster.svg"; 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,
@ -61,7 +62,7 @@ export const Main = ({
))} ))}
</ul> </ul>
</div> </div>
{books?.length > 0 && ( {listVOD?.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)}
@ -85,7 +86,7 @@ export const Main = ({
/> />
} }
> >
{books?.map((video, index) => ( {listVOD?.map((video, index) => (
<VodProduct <VodProduct
video={video} video={video}
key={index} key={index}
@ -103,20 +104,9 @@ export const Main = ({
? gradeFilterBooks?.map((product, index) => ( ? gradeFilterBooks?.map((product, index) => (
<Product <Product
key={index} key={index}
productsType={filter.productsType}
product={product} product={product}
index={Number(index)} index={Number(index)}
grades={grades} grades={grades}
roductName={`کتاب ${product?.name}`}
productCat={`پایه ${grades[product?.gradeId]}`}
productPrice={100000}
productImg={"https://dnvn.ir/api/v1/file/" + product?.fileIds}
numberOfRegards={160}
productTitleColor="text-blue5F"
productCatTextColor="text-blueC0"
productHolderBorder=""
productHolderHoverBorder="shadow-md"
starRate={Math.floor(Math.random() * 5) + 1}
imageSize={4.5} imageSize={4.5}
/> />
)) ))
@ -145,14 +135,13 @@ Main.defaultProps = {
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
isDark: state.publicApi.isDark, isDark: state.publicApi.isDark,
isMobile: state.publicApi.isMobile, isMobile: state.publicApi.isMobile,
books: state.book.list,
grades: state.publicApi.grades,
}); });
const mapDispatchToProps = { 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);

@ -3,10 +3,12 @@ import { userProduct, userFactor, publicApi } from "../../redux/actions";
import DeliveryForm from "../DeliveryForm"; import DeliveryForm from "../DeliveryForm";
import Product from "./Product"; import Product from "./Product";
import Address from "../Address";
import Code from "./Code"; import Code from "./Code";
import Button from "../../components/Button"; import Button from "../../components/Button";
//assets //assets
import dropdownIcon from "../../assets/icons/dropdown-blue.svg";
import alertIcon from "../../assets/icons/alert.svg"; import alertIcon from "../../assets/icons/alert.svg";
import { connect } from "react-redux"; import { connect } from "react-redux";
@ -17,7 +19,7 @@ function ShoppingCart({
list, list,
payPrice, payPrice,
factorInfo, factorInfo,
userId, user,
hasPhysical, hasPhysical,
getList, getList,
getInfo, getInfo,
@ -31,10 +33,19 @@ function ShoppingCart({
useEffect(() => { useEffect(() => {
getList(); getList();
getFactorInfo({ userId }); getFactorInfo({ userId: user?.id });
setHeaderOptions(headerOptions); setHeaderOptions(headerOptions);
}, []); }, []);
const next = {
products: () => setPhase("deliveryForm"),
deliveryForm: () => console.log("Go to shaparak"),
profile: () => {
console.log("Set profile");
console.log("Go to shaparak");
},
};
const Table = () => { const Table = () => {
return ( return (
<div className="w-full flex flex-col"> <div className="w-full flex flex-col">
@ -50,9 +61,10 @@ function ShoppingCart({
</strong> </strong>
</header> </header>
<ul className="w-full mt-2 list-none p-0"> <ul className="w-full mt-2 list-none p-0">
{list.map((product, index) => product.condition < 2 && ( {list.map(
<Product key={index} product={product} /> (product, index) =>
))} product.condition < 2 && <Product key={index} product={product} />
)}
</ul> </ul>
</div> </div>
); );
@ -96,6 +108,12 @@ function ShoppingCart({
); );
}; };
const layouts = {
products: <Table />,
deliveryForm: <DeliveryForm setPhase={setPhase} />,
address: <Address setPhase={setPhase} />,
};
return isMobile ? ( return isMobile ? (
<div className="w-full flex flex-col px-4"> <div className="w-full flex flex-col px-4">
{list.map((product, index) => ( {list.map((product, index) => (
@ -147,95 +165,104 @@ function ShoppingCart({
</div> </div>
) : ( ) : (
<div <div
className={`w-full flex flex-row relative gap-10 px-5 mt-10 pb-20 ${ className={`w-11/12 mx-auto flex flex-row relative gap-10 px-5 mt-10 pb-20 ${
desktopContentTransform ? "top-24" : "" desktopContentTransform ? "top-24" : ""
}`} }`}
> >
<div className="flex flex-col w-3/4"> <div className="flex flex-col flex-1">{layouts[phase]}</div>
{phase === "products" && <Table />} {phase !== "address" && (
{phase === "delivery-form" && <DeliveryForm />} <div
</div> className="flex flex-col w-1/4 p-10 bg-grayF9 border border-solid border-grayDB rounded-md px-4 py-4"
<div style={{ height: "fit-content" }}
className="flex flex-col w-1/4 p-10 bg-grayF9 border border-solid border-grayDB rounded-md px-4 py-4" >
style={{ height: "fit-content" }} <div className="flex flex-col w-full border-t py-2 border-gray-300 border-b">
> <PriceStatus
<div className="flex flex-col w-full border-t py-2 border-gray-300 border-b"> name="مبلغ سبد خرید"
<PriceStatus value={factorInfo?.sumPrice}
name="مبلغ سبد خرید" type="normal"
value={factorInfo?.sumPrice}
type="normal"
/>
<PriceStatus
name="میزان تخفیف"
value={factorInfo?.offPrice}
type="error"
/>
<PriceStatus
name="مالیات بر ارزش افزوده"
value={Math.floor(factorInfo?.sumPrice * 0.009)}
type="error"
/>
</div>
<div className="flex flex-row justify-between items-center w-full py-4 border-t border-b border-grayDB border-solid">
<strong className="font-medium text-tiny text-blue5F dark:text-white">
جمع کل سبد خرید
</strong>
<p className="font-medium text-greenBA text-xl dark:text-white">
{factorInfo?.payPrice}
<span className="font-medium text-greenBA text-sm mr-2">تومان</span>
</p>
</div>
{phase === "products" && (
<div
className="w-full rounded-md flex flex-row justify-center items-center py-2.5 px-3 mt-10 mb-4"
style={{ backgroundColor: "#196EC01a" }}
>
<img src={alertIcon} className="w-5 ml-2" />
<p className="text-xs text-blueC0 dark:text-white text-justify">
هزینه ارسال کالا پس از تعیین محل آدرس مشخص میشود
</p>
</div>
)}
{phase === "delivery-form" && (
<div className="flex flex-col mt-10">
<strong className="text-tiny text-blue52 mb-5 font-medium">
انتخاب شیوه پرداخت
</strong>
<Button
title="ادامه فرایند خرید"
backgroundColor="bg-transparent"
border={{ color: "#77777755", width: "1px" }}
width="100%"
color="text-blue52"
onClick={() =>
setPhase(phase === "products" ? "delivery-form" : "")
}
/> />
<br /> <PriceStatus
<Button name="میزان تخفیف"
title="پرداخت در محل" value={factorInfo?.offPrice}
backgroundColor="bg-transparent" type="error"
border={{ color: "#77777755", width: "1px" }} />
width="100%" <PriceStatus
color="text-blue52" name="مالیات بر ارزش افزوده"
onClick={() => value={Math.floor(factorInfo?.sumPrice * 0.009)}
setPhase(phase === "products" ? "delivery-form" : "") type="error"
}
/> />
<br/>
<br/>
</div> </div>
)} <div className="flex flex-row justify-between items-center w-full py-4 border-t border-b border-grayDB border-solid">
<strong className="font-medium text-tiny text-blue5F dark:text-white">
<Button جمع کل سبد خرید
title="ادامه فرایند خرید" </strong>
backgroundColor="bg-blueC0" <p className="font-medium text-greenBA text-xl dark:text-white">
border={{ color: "#196EC055", width: "1px" }} {factorInfo?.payPrice}
width="100%" <span className="font-medium text-greenBA text-sm mr-2">
color="text-white" تومان
onClick={() => setPhase(phase === "products" ? "delivery-form" : "")} </span>
/> </p>
</div> </div>
{phase === "products" && (
<div
className="w-full rounded-md flex flex-row justify-center items-center py-2.5 px-3 mt-10 mb-4"
style={{ backgroundColor: "#196EC01a" }}
>
<img src={alertIcon} className="w-5 ml-2" />
<p className="text-xs text-blueC0 dark:text-white text-justify">
هزینه ارسال کالا پس از تعیین محل آدرس مشخص میشود
</p>
</div>
)}
{phase === "deliveryForm" && (
<div className="flex flex-col mt-10">
<strong className="text-tiny text-blue52 mb-5 font-medium">
انتخاب شیوه پرداخت
</strong>
<Button
title="از طریق درگاه پرداخت"
backgroundColor="bg-transparent"
border={{ color: "#77777755", width: "1px" }}
width="100%"
color="text-blue52"
onClick={() => {}}
/>
<br />
<Button
title="پرداخت در محل"
backgroundColor="bg-transparent"
border={{ color: "#77777755", width: "1px" }}
width="100%"
color="text-blue52"
onClick={() => {}}
/>
<br />
<br />
</div>
)}
<Button
title="ادامه فرایند خرید"
backgroundColor="bg-blueC0"
border={{ color: "#196EC055", width: "1px" }}
width="100%"
color="text-white"
onClick={next[phase]}
/>
{phase === "deliveryForm" && (
<button
className="bg-transparent mt-4 text-tiny text-blueC0 py-3 flex flex-row justify-center items-center"
onClick={() => setPhase("products")}
>
بازگشت
<img
src={dropdownIcon}
alt=""
className="w-4 transform rotate-90"
/>
</button>
)}
</div>
)}
</div> </div>
); );
} }
@ -246,7 +273,7 @@ const mapStateToProps = (state) => ({
list: state.userProduct.list, list: state.userProduct.list,
payPrice: state.userProduct.sum, payPrice: state.userProduct.sum,
factorInfo: state.userFactor.info, factorInfo: state.userFactor.info,
userId: state.user.status.id, user: state.user.status,
hasPhysical: state.userProduct.hasPhysical, hasPhysical: state.userProduct.hasPhysical,
desktopContentTransform: state.publicApi.desktopContentTransform, desktopContentTransform: state.publicApi.desktopContentTransform,
}); });

@ -68,15 +68,9 @@ function Video({
const [type, setType] = useState(0); const [type, setType] = useState(0);
useEffect(() => { useEffect(() => {
getBook({ bookId: Number(location.getId()) }); getBook({ bookId: location.getId() });
setHeaderOptions(headerOptions); setHeaderOptions(headerOptions);
}, []); }, []);
useEffect(() => {
if (book) {
// console.log(book);
}
}, [book]);
return isMobile ? ( return isMobile ? (
<div className="w-full flex flex-col px-4"> <div className="w-full flex flex-col px-4">
<div className="w-full flex flex-col"> <div className="w-full flex flex-col">

@ -103,7 +103,7 @@ function VideoDisplay({
</div> </div>
) : ( ) : (
<div className="w-11/12 flex flex-col mb-6 justify-center items-center mx-auto"> <div className="w-11/12 flex flex-col mb-6 justify-center items-center mx-auto">
<div className="w-full flex flex-row justify-center overflow-hidden relative gap-2 mt-4"> <div className="w-full flex flex-row justify-between overflow-hidden relative gap-2 mt-4">
<div className="flex flex-col w-8/12"> <div className="flex flex-col w-8/12">
<JolPlayer <JolPlayer
fileIds={selectedVideo?.fileIds} fileIds={selectedVideo?.fileIds}

Loading…
Cancel
Save