Pedram Keshavarzi 3 years ago
commit 8c30e37408
  1. 44
      src/components/Navbar/index.js
  2. 2
      src/redux/reducers/public.js
  3. 8
      src/views/Auth/Desktop/back.svg
  4. 5260
      src/views/Auth/Desktop/bg.svg
  5. 94
      src/views/Auth/Desktop/index.js
  6. 4
      src/views/Auth/SignUp/index.js
  7. 6
      src/views/Auth/index.js
  8. 2
      src/views/Dashboard/layouts/Main/index.js
  9. 2
      src/views/Home/Desktop/index.js
  10. 7
      src/views/Products/index.js
  11. 22
      src/views/Video/components/Season.js
  12. 11
      src/views/Video/index.js
  13. 6
      src/views/VideoDisplay/components/Season.js
  14. 29
      src/views/VideoDisplay/index.js
  15. 34
      yarn.lock

@ -1,6 +1,7 @@
import React, { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom";
import { connect } from "react-redux";
import {publicApi} from "../../redux/actions";
import _ from "lodash";
import Drawer from "../Drawer";
import Search from "../Search";
@ -29,10 +30,10 @@ import bookmarkDeactiveDarkIcon from "../../assets/icons/bookmark-deactive-dark.
import dotsMenuLightIcon from "../../assets/icons/dots-menu-light.svg";
import bookmarkDeactiveLightIcon from "../../assets/icons/bookmark-deactive-light.svg";
function Navbar({
pages,
isDark,
changeDarkMode,
isMobile,
isLogin,
headerOptions,
@ -86,6 +87,20 @@ function Navbar({
});
}
}, []);
let tapedTwice = false;
const doubleTap = (event) => {
if (!tapedTwice) {
tapedTwice = true;
setTimeout(function () {
tapedTwice = false;
}, 300);
return false;
}
event.preventDefault();
//action on double tap goes below
changeDarkMode(!isDark);
};
return isMobile ? (
<div
className={_.join(
@ -97,6 +112,7 @@ function Navbar({
style={{
backgroundColor: !top ? (isDark ? "#061B30" : "white") : "",
}}
onClick={(e) => doubleTap(e)}
>
{/* landscape start */}
@ -302,13 +318,15 @@ function Navbar({
</a>
))} */}
{
pages.map((item, index) => (
<Link to={item.link} className={`text-sm text-blue52 ${menuItemsColor}`} key={'nav' + index}>
{pages.map((item, index) => (
<Link
to={item.link}
className={`text-sm text-blue52 ${menuItemsColor}`}
key={"nav" + index}
>
{item.name}
</Link>
))
}
))}
</div>
</div>
</div>
@ -323,13 +341,17 @@ const mapStateToProps = (state) => ({
isLogin: state.user.status,
});
export default connect(mapStateToProps, {})(Navbar);
const mapDispatchToProps = {
changeDarkMode : publicApi.setIsDark
}
export default connect(mapStateToProps, mapDispatchToProps)(Navbar);
Navbar.defaultProps = {
pages: [
{
link: '/',
name: 'خانه'
link: "/",
name: "خانه",
},
{
link: "/products",
@ -340,7 +362,7 @@ Navbar.defaultProps = {
name: "دسته بندیها",
},
{
link: "/contact",
link: "/contact-us",
name: "تماس با ما",
},
{
@ -348,7 +370,7 @@ Navbar.defaultProps = {
name: "درباره ما",
},
{
link: "/orders",
link: "/dashboard",
name: "پیگیری",
},
{

@ -1,7 +1,7 @@
import location from "../../utils/location";
const initialState = {
isDark: localStorage.getItem("isDark") || false,
isDark: false,
isMobile: window.innerWidth < 1024,
homeData: [],
newProducts: [],

@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
<g id="vuesax_linear_arrow-left" data-name="vuesax/linear/arrow-left" transform="translate(-364 -252)">
<g id="arrow-left">
<path id="Vector" d="M7.1,15.84.577,9.32a1.986,1.986,0,0,1,0-2.8L7.1,0" transform="translate(371.902 256.08)" fill="none" stroke="#196ec0" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-2" data-name="Vector" d="M0,0H24V24H0Z" transform="translate(388 276) rotate(180)" fill="none" opacity="0"/>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 582 B

File diff suppressed because it is too large Load Diff

After

Width:  |  Height:  |  Size: 736 KiB

@ -0,0 +1,94 @@
import React, { useState } from "react";
import { connect } from "react-redux";
import { useNavigate } from "react-router-dom";
import SignUp from "../SignUp";
import Button from "../../../components/Button";
//assets
import logoIcon from "../SignUp/assets/logo.svg";
import bgImage from "./bg.svg";
import arrowIcon from "./back.svg";
export const Desktop = ({}) => {
const [phase, setPhase] = useState("manage");
const navigate = useNavigate();
const UserMangement = () => {
return (
<div
className={`flex flex-col items-center justify-center w-full relative h-full transform transition-all duration-700 ${
phase !== "manage" ? "translate-x-full" : ""
}`}
>
<img
src={logoIcon}
alt=""
className="w-20 absolute left-1/2 top-10 transform -translate-x-1/2"
/>
<strong className="text-2xl text-blueC0 self-start tracking-tighter">
ورود یا ثبت نام
</strong>
<p className="text-tiny self-start text-gray-500 mt-6 leading-6">
کاربر گرامی لطفا یکی از دوگزینه زیر را انتخاب نمائید.
<br /> درصورتی که عضو نیستید روی دکمه ثبت نام بزنید
</p>
<div className="mt-16 flex flex-col gap-4 w-full">
<Button
title="ثبت نام"
backgroundColor="bg-blueC0"
border={{ color: "#196EC055", width: "1px" }}
width="100%"
color="text-white"
onClick={() => setPhase("signup")}
/>
<Button
title="ورود"
backgroundColor="bg-transparent border border-solid border-blueC0"
border={{ color: "", width: 1 }}
width="100%"
color="text-blueC0"
onClick={() => setPhase("login")}
/>
</div>
</div>
);
};
const phases = {
manage: <UserMangement />,
signup: <SignUp />,
login: <SignUp />,
};
return (
<div className="h-screen w-full flex justify-center items-center">
<div className="w-4/5 h-4/5 rounded-xl flex overflow-hidden border border-solid border-gray-200">
<div className="w-2/5 h-full flex justify-center items-center">
<div
className="w-4/5 flex justify-center items-center relative"
style={{ height: "90%" }}
>
<button
className="absolute left-0 top-0 p-3 bg-grayF4 rounded-xl z-20"
onClick={() =>
setPhase(() => (phase === "manage" ? navigate("/") : "manage"))
}
>
<img src={arrowIcon} />
</button>
{phases[phase]}
</div>
</div>
<div className="w-3/5 h-full bg-grayF9 flex justify-center items-center">
<img src={bgImage} alt="" className="w-4/5" />
</div>
</div>
</div>
);
};
const mapStateToProps = (state) => ({});
const mapDispatchToProps = {};
export default connect(mapStateToProps, mapDispatchToProps)(Desktop);

@ -130,7 +130,7 @@ function SignUp({
useEffect(() => {
if (loginFlag) {
navigate("/");
// navigate("/");
}
}, [loginFlag]);
const light = theme === "light";
@ -162,7 +162,7 @@ function SignUp({
<span className="text-red-500 text-xs">{error}</span>
<br />
<Button
title="ادامه فرایند خرید"
title="ادامه"
backgroundColor="bg-blueC0"
border={{ color: "#196EC055", width: "1px" }}
width="100%"

@ -2,6 +2,7 @@ import React, { useState, useEffect } from "react";
import SignUp from "./SignUp/index";
import Profile from "./Profile/index";
import Login from "./Login/index";
import Desktop from "./Desktop";
import { connect } from "react-redux";
function Auth(props) {
@ -9,7 +10,7 @@ function Auth(props) {
useEffect(() => {
setPage(() => props.page);
}, [props.page]);
return (
return props.isMobile ? (
<>
{page === "signup" && (
<SignUp theme={props.theme} headerOptions={props.headerOptions} />
@ -23,9 +24,10 @@ function Auth(props) {
)}
{page === "profile" && <Profile theme={props.theme} />}
</>
);
) : <Desktop />
}
export default connect((state) => ({
theme: state.publicApi.theme,
isMobile: state.publicApi.isMobile
}))(Auth);

@ -9,7 +9,7 @@ export const Main = ({}) => {
orders: <Orders />,
userItems: <UserItems />
};
const [page, setPage] = useState("userItems");
const [page, setPage] = useState("orders");
return <div className="flex-1 py-2.5 overflow-y-scroll">{views[page]}</div>;
};

@ -22,7 +22,7 @@ const DesktopHome = (
return (
<div className="flex flex-col items-center w-4/5 justify-center my-10">
<div className="flex flex-col items-center w-11/12 justify-center my-10">
<Banners/>
<SalesContainer books={books} grades={grades}/>
<Part2 grades={grades}/>

@ -80,14 +80,15 @@ export const Products = ({
<img
src={"https://dnvn.ir/api/v1/file/" + product?.fileIds}
className="w-full rounded-md mb-2"
style={{height : "calc(100vh / 5)"}}
/>
<strong className="text-blue5F dark:text-white text-sm font-bold mb-1">
<strong className="text-blue5F dark:text-white text-tiny font-bold mb-2">
{product?.name}
</strong>
<span className="text-xs text-blueC0 dark:text-white font-light mb-4">
<span className="text-sm text-blueC0 dark:text-white font-light mb-4">
{"پایه" + " " + grades[product?.gradeId]}
</span>
<div className="w-full flex flex-row justify-center font-medium text-sm text-blue5F dark:text-white">
<div className="w-full flex flex-row justify-center font-medium text-tiny text-blue5F dark:text-white">
{1399 + " " + "تومان"}
</div>
</Link>

@ -26,16 +26,19 @@ const Season = ({
// const [activeSeason, setActiveSeason] = useState(null);
const Unit = ({ unit }) => {
return isMobile ? (
<div className="w-full flex flex-col rounded-md overflow-hidden mb-3 border border-solid border-blueFE dark:border-opacity-60 bg-blueFF">
<Link
to="/videos/0/display"
className="w-full flex flex-col rounded-md overflow-hidden mb-3 border border-solid border-blueFE dark:border-opacity-60 bg-blueFF dark:bg-opacity-10"
>
<div className="w-full flex flex-row justify-between items-center py-3 px-2 border-b border-solid border-blueFE dark:border-opacity-60">
<strong className="text-blueC0 text-sm dark:text-white font-normal">
{unit.name}
</strong>
<span className="text-sm text-blueC0 dark:text-white">
{/* <span className="text-sm text-blueC0 dark:text-white">
{unit.duration}
</span>
</span> */}
</div>
<div className="w-full flex flex-row">
{/* <div className="w-full flex flex-row">
{unit.play && (
<Link
to={`/videos/${id}/display`}
@ -52,8 +55,8 @@ const Season = ({
دانلود
</Link>
)}
</div>
</div>
</div> */}
</Link>
) : (
<Link to="/videos/0/display" className="d-flex flex-column">
<li
@ -73,7 +76,10 @@ const Season = ({
);
};
return isMobile ? (
<div className="w-full flex flex-col">
<div
className="w-full flex flex-col"
onClick={() => toggle(season[0].categoryId)}
>
<button
className="flex flex-row justify-between items-center rounded-md py-3 px-3 mb-3 bg-blueC0"
// onClick={() =>
@ -89,7 +95,7 @@ const Season = ({
<span className="text-xs text-white">{season.duration}</span>
</button>
{season.name === activeSeason &&
{season[0].categoryId === activeSeason &&
season.map((unit, index) => <Unit unit={unit} key={index} />)}
</div>
) : (

@ -68,10 +68,9 @@ function Video({
}, []);
useEffect(() => {
if(book){
if (book) {
// console.log(book);
}
}, [book]);
return isMobile ? (
<div className="w-full flex flex-col px-4">
@ -95,17 +94,17 @@ function Video({
<div className="flex flex-col flex-1 justify-between pr-2">
<div className="flex flex-col">
<strong className="mt-2 text-blue5F text-lg dark:text-white">
{product.name}
{book?.name}
</strong>
<span className="text-blueC0 text-sm mb-1 dark:text-greenBA mt-2">
{product.grade}
{"پایه" + " " + (grades[book?.gradeId] || "پایه دوازدهم")}
</span>
</div>
<Divider type={"vertical"} />
</div>
</div>
<div className="flex flex-col">
{product.seasons.map((season, index) => (
{seasons?.map((season, index) => (
<Season season={season} key={index} id={product.id} />
))}
</div>
@ -145,7 +144,7 @@ function Video({
<div className="w-3/12 flex flex-col">
<div className="w-full flex flex-col pr-2 py-2 border-0">
<h1 className="text-blue5F mb-3 font-semibold text-xl dark:text-white">
{book?.name }
{book?.name}
</h1>
<div className="text-blueC0 text-sm dark:text-greenBA">
{"پایه" + " " + (grades[book?.gradeId] || "پایه دوازدهم")}

@ -5,7 +5,7 @@ const Season = ({ season }) => {
const [activeSeason, setActiveSeason] = useState(null);
const Unit = ({ unit }) => {
return (
<div className="w-full flex flex-col rounded-md overflow-hidden mb-3 border border-solid border-blueFE dark:border-opacity-60 bg-blueFF">
<div className="w-full flex flex-col rounded-md overflow-hidden mb-3 border border-solid border-blueFE dark:border-opacity-60 bg-blueFF dark:bg-opacity-10">
<div className="w-full flex flex-row justify-between items-center py-3 px-2 border-b border-solid border-blueFE dark:border-opacity-60">
<strong className="text-blueC0 text-sm dark:text-white font-normal">
{unit.name}
@ -17,7 +17,7 @@ const Season = ({ season }) => {
<div className="w-full flex flex-row">
{unit.play && (
<Link
to={"/videos/:id/display"}
to={"/videos/0/display"}
className="flex flex-1 flex-row items-center py-2.5 px-2 border-l border-solid border-blueFE dark:border-opacity-60 justify-center text-sm text-blueC0 dark:text-white"
>
نمایش
@ -25,7 +25,7 @@ const Season = ({ season }) => {
)}
{unit.download && (
<Link
to="/videos/:id/download"
to="/videos/0/download"
className="flex flex-1 flex-row items-center py-2.5 px-2 justify-center text-sm text-blueC0 dark:text-white"
>
دانلود

@ -44,16 +44,31 @@ function VideoDisplay({
},
headerOptions,
setHeaderOptions,
book,
seasons,
grades,
getBook,
}) {
useEffect(() => {
const id = window.location.pathname.slice(
8,
window.location.pathname.lastIndexOf("/")
);
setHeaderOptions(headerOptions);
// getBook({ bookId: id });
}, []);
return (
isMobile ?
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>';
return isMobile ? (
<div className="w-full flex flex-col px-4">
<div className="w-full flex flex-col mb-6">
<div className="w-full flex flex-row flex-1 justify-between items-center overflow-hidden relative">
<video style={{ width: "100%", height: "calc(100vw * 9 / 16 - 16)" }} controls>
<video
style={{ width: "100%", height: "calc(100vw * 9 / 16 - 16)" }}
controls
>
<source
src={`https://dnvn.ir/api/v1/file/20540`}
type="video/mp4"
@ -75,17 +90,23 @@ function VideoDisplay({
<Season season={season} key={index} />
))}
</div>
</div> :
</div>
) : (
<DesktopVideoDisplay />
);
}
const mapStateToProps = (state) => ({
isMobile: state.publicApi.isMobile,
book: state.publicApi.bookInfo,
grades: state.publicApi.categories,
grades: state.publicApi.grades,
selectedVideo: state.publicApi.selectedVideo,
});
const mapDispatchToProps = {
setHeaderOptions: publicApi.setHeaderOptions,
getBook: publicApi.getBook,
};
export default connect(mapStateToProps, mapDispatchToProps)(VideoDisplay);

@ -3450,7 +3450,7 @@ class-utils@^0.3.5:
isobject "^3.0.0"
static-extend "^0.1.1"
classnames@^2.2.5:
classnames@^2.2.5, classnames@^2.2.6:
version "2.3.1"
resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.1.tgz#dfcfa3891e306ec1dad105d0e88f4417b8535e8e"
integrity sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==
@ -4152,6 +4152,11 @@ data-urls@^2.0.0:
whatwg-mimetype "^2.3.0"
whatwg-url "^8.0.0"
debounce@^1.2.0:
version "1.2.1"
resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.1.tgz#38881d8f4166a5c5848020c11827b834bcb3e0a5"
integrity sha512-XRRe6Glud4rd/ZGQfiV1ruXSfbvfJedlV9Y6zOlP+2K04vBYiJEte6stfFkCP03aMnY5tsipamumUjL14fofug==
debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
@ -4520,6 +4525,11 @@ earcut@^2.2.2:
resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.3.tgz#d44ced2ff5a18859568e327dd9c7d46b16f55cf4"
integrity sha512-iRDI1QeCQIhMCZk48DRDMVgQSSBDmbzzNhnxIo+pwx3swkfjMh6vh0nWLq1NdvGHLKH6wIrAM3vQWeTj6qeoug==
easy-bem@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/easy-bem/-/easy-bem-1.1.1.tgz#1bfcc10425498090bcfddc0f9c000aba91399e03"
integrity sha512-GJRqdiy2h+EXy6a8E6R+ubmqUM08BK0FWNq41k24fup6045biQ8NXxoXimiwegMQvFFV3t1emADdGNL1TlS61A==
ee-first@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d"
@ -9674,6 +9684,15 @@ react-error-overlay@^6.0.9:
resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.10.tgz#0fe26db4fa85d9dbb8624729580e90e7159a59a6"
integrity sha512-mKR90fX7Pm5seCOfz8q9F+66VCc1PGsWSBxKbITjfKVQHMNF2zudxHnMdJiB1fRCb+XsbQV9sO9DCkgsMQgBIA==
react-indiana-drag-scroll@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/react-indiana-drag-scroll/-/react-indiana-drag-scroll-2.1.0.tgz#37654eae8caced01cdecc8bce55f0382871a021d"
integrity sha512-Tj94Dv9PkmoKqc9nxK/dzwhtE8pP7NTxmeHqkD8KN0zad1NNE+/JsvRcK4EdqE6CdA2nMESzqPMvv1AzRXdBew==
dependencies:
classnames "^2.2.6"
debounce "^1.2.0"
easy-bem "^1.1.1"
react-is@^16.13.1, react-is@^16.7.0:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
@ -9827,6 +9846,14 @@ react-toastify@^8.1.0:
dependencies:
clsx "^1.1.1"
react-tooltip@^4.2.21:
version "4.2.21"
resolved "https://registry.yarnpkg.com/react-tooltip/-/react-tooltip-4.2.21.tgz#840123ed86cf33d50ddde8ec8813b2960bfded7f"
integrity sha512-zSLprMymBDowknr0KVDiJ05IjZn9mQhhg4PRsqln0OZtURAJ1snt1xi5daZfagsh6vfsziZrc9pErPTDY1ACig==
dependencies:
prop-types "^15.7.2"
uuid "^7.0.3"
react-wavesurfer@^0.8.6:
version "0.8.6"
resolved "https://registry.yarnpkg.com/react-wavesurfer/-/react-wavesurfer-0.8.6.tgz#da05f3f501e566a63853f9babec45a5251111538"
@ -11743,6 +11770,11 @@ uuid@^3.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"
integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==
uuid@^7.0.3:
version "7.0.3"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b"
integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg==
uuid@^8.3.0, uuid@^8.3.2:
version "8.3.2"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"

Loading…
Cancel
Save