Merge branch 'master' of https://git.sitenevis.com/Danovin/application

Conflicts:
	yarn.lock
master
Your Name 2 years ago
commit f443fe281c
  1. 6
      postcss.config.js
  2. 1
      src/App.scss
  3. 8
      src/assets/icons/bookmark-active-dark.svg
  4. 8
      src/assets/icons/bookmark-active-light.svg
  5. 2
      src/components/BottomNavigation/index.js
  6. 17
      src/components/ButtonBetween/index.js
  7. 14
      src/components/Comments/index.js
  8. 8
      src/components/CourseChapter/index.js
  9. 4
      src/components/Dialog/index.js
  10. 110
      src/components/Drawer/index.js
  11. 24
      src/components/Footer/index.js
  12. 2
      src/components/Header/index.js
  13. 24
      src/components/Modal/index.js
  14. 242
      src/components/Navbar/index.js
  15. 2
      src/components/OR/index.js
  16. 2
      src/components/ProductImage/index.js
  17. 24
      src/components/ProductStatusCard/index.js
  18. 6
      src/components/ProductSuggestion/index.js
  19. 2
      src/components/ProductTab/index.js
  20. 22
      src/components/QandA/index.js
  21. 3
      src/components/StarRating/index.js
  22. 4
      src/components/VerticalExpandableProductFilter/index.js
  23. 1
      src/index.css
  24. 4
      src/redux/actions/blog.js
  25. 1
      src/redux/actions/comment.js
  26. 12
      src/redux/actions/config.js
  27. 1
      src/redux/actions/index.js
  28. 16
      src/redux/reducers/blog.js
  29. 24
      src/redux/reducers/config.js
  30. 2
      src/redux/reducers/form.js
  31. 1
      src/redux/reducers/index.js
  32. 91
      src/router.js
  33. 7
      src/views/About/index.js
  34. 4
      src/views/About/index.scss
  35. 2
      src/views/Activation/components/Alert.js
  36. 12
      src/views/Address/index.js
  37. 71
      src/views/Auth/Desktop/index.js
  38. 4
      src/views/Auth/Profile/index.js
  39. 100
      src/views/Auth/SignUp/index.js
  40. 15
      src/views/Auth/index.js
  41. 67
      src/views/Blog/index.js
  42. 58
      src/views/Blogs/index.js
  43. 45
      src/views/Blogs/layouts/Blog.js
  44. 23
      src/views/Blogs/layouts/Hashtags.js
  45. 2
      src/views/Blogs/layouts/Join.js
  46. 4
      src/views/Blogs/layouts/New.js
  47. 2
      src/views/Blogs/layouts/Suggest.js
  48. 6
      src/views/Blogs/layouts/Target.js
  49. 36
      src/views/Contact/index.js
  50. 2
      src/views/Contact/layouts/Info.js
  51. 26
      src/views/Contact/layouts/Ticket.js
  52. 8
      src/views/Contact/layouts/Upload.js
  53. 2
      src/views/Dashboard/index.js
  54. 35
      src/views/Dashboard/layouts/Main/Addresses/index.js
  55. 2
      src/views/Dashboard/layouts/Main/MyBooks/index.js
  56. 14
      src/views/Dashboard/layouts/Mobile/List.js
  57. 30
      src/views/Dashboard/layouts/Mobile/ProfileAddress/index.js
  58. 8
      src/views/Dashboard/layouts/Mobile/ProfileBookmark/index.js
  59. 8
      src/views/Dashboard/layouts/Mobile/Trophy.js
  60. 6
      src/views/Dashboard/layouts/Mobile/User.js
  61. 32
      src/views/Dashboard/layouts/SidebarMenu/index.js
  62. 44
      src/views/DeliveryForm/Address/index.js
  63. 6
      src/views/DeliveryForm/PaymentMethod/index.js
  64. 6
      src/views/DeliveryForm/TransportDate/index.js
  65. 2
      src/views/DeliveryForm/TransportMethod/index.js
  66. 14
      src/views/DeliveryForm/index.js
  67. 2
      src/views/Faq/components/NotFound.js
  68. 2
      src/views/Faq/components/Question.js
  69. 2
      src/views/Faq/index.js
  70. 2
      src/views/Favorites/index.js
  71. 2
      src/views/Home/Desktop/Part2/index.js
  72. 2
      src/views/Home/Desktop/Part4/index.js
  73. 2
      src/views/Home/Desktop/SalesContainer/index.js
  74. 2
      src/views/Home/Landscape/Page1/Lights/index.js
  75. 6
      src/views/Home/Landscape/Page1/index.js
  76. 2
      src/views/Home/Landscape/Page2/Mobile/QrResult/Link/index.js
  77. 2
      src/views/Home/Landscape/Page2/Mobile/QrResult/PDF/index.js
  78. 4
      src/views/Home/Landscape/Page2/Mobile/QrResult/index.js
  79. 2
      src/views/Home/Landscape/Page3/index.js
  80. 2
      src/views/Home/Landscape/Page4/index.js
  81. 2
      src/views/Home/Landscape/Test/Question.js
  82. 6
      src/views/Home/Landscape/Test/index.js
  83. 4
      src/views/Home/Landscape/VideoTube/LessonPlayList/index.js
  84. 4
      src/views/Home/Landscape/VideoTube/index.js
  85. 12
      src/views/Home/Portrait/Private/Blogs/index.js
  86. 60
      src/views/Home/Portrait/Private/MyBooks/index.js
  87. 4
      src/views/Home/Portrait/Private/Videos/index.js
  88. 2
      src/views/Home/Portrait/Public/Features/index.js
  89. 4
      src/views/Home/Portrait/Public/Header/index.js
  90. 2
      src/views/Home/Portrait/Public/Platforms/index.js
  91. 4
      src/views/Home/Portrait/Public/Responsive/index.js
  92. 6
      src/views/Order/components/Book.js
  93. 34
      src/views/Order/index.js
  94. 12
      src/views/Orders/components/Order.js
  95. 4
      src/views/Product/Comment/index.js
  96. 6
      src/views/Product/Desktop/ProductOverAll/index.js
  97. 131
      src/views/Product/Rate/index.js
  98. 229
      src/views/Product/index.js
  99. 5
      src/views/Products/index.js
  100. 142
      src/views/Products/layouts/Desktop/Main.js
  101. Some files were not shown because too many files have changed in this diff Show More

@ -0,0 +1,6 @@
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

@ -1,3 +1,4 @@
@import "./constants/size.scss"; @import "./constants/size.scss";
@import "./constants/colors.scss"; @import "./constants/colors.scss";
@import "./views/Home/Landscape/Page1/index.scss"; @import "./views/Home/Landscape/Page1/index.scss";

@ -0,0 +1,8 @@
<svg id="vuesax_linear_archive-add" data-name="vuesax/linear/archive-add" xmlns="http://www.w3.org/2000/svg" width="29.778" height="29.778" viewBox="0 0 29.778 29.778">
<g id="archive-add" transform="translate(0)">
<path id="Vector" d="M6.2,0H0" transform="translate(11.787 13.214)" fill="#fff" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-2" data-name="Vector" d="M0,0V6.2" transform="translate(14.889 10.187)" fill="none" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-3" data-name="Vector" d="M16.75,0H4.789A4.8,4.8,0,0,0,0,4.789V22.272c0,2.233,1.6,3.176,3.561,2.1l6.055-3.362a2.628,2.628,0,0,1,2.32,0l6.055,3.362c1.96,1.092,3.561.149,3.561-2.1V4.789A4.819,4.819,0,0,0,16.75,0Z" transform="translate(4.119 2.482)" fill="#fff" stroke="#fff" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-4" data-name="Vector" d="M0,0H29.778V29.778H0Z" fill="none" opacity="0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

@ -0,0 +1,8 @@
<svg id="vuesax_linear_archive-add" data-name="vuesax/linear/archive-add" xmlns="http://www.w3.org/2000/svg" width="29.778" height="29.778" viewBox="0 0 29.778 29.778">
<g id="archive-add" transform="translate(0)">
<path id="Vector" d="M6.2,0H0" transform="translate(11.787 13.214)" fill="rgb(19, 123, 79)" stroke="rgb(19, 123, 79)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-2" data-name="Vector" d="M0,0V6.2" transform="translate(14.889 10.187)" fill="rgb(19, 123, 79)" stroke="rgb(19, 123, 79)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-3" data-name="Vector" d="M16.75,0H4.789A4.8,4.8,0,0,0,0,4.789V22.272c0,2.233,1.6,3.176,3.561,2.1l6.055-3.362a2.628,2.628,0,0,1,2.32,0l6.055,3.362c1.96,1.092,3.561.149,3.561-2.1V4.789A4.819,4.819,0,0,0,16.75,0Z" transform="translate(4.119 2.482)" fill="rgb(19, 123, 79)" stroke="rgb(19, 123, 79)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/>
<path id="Vector-4" data-name="Vector" d="M0,0H29.778V29.778H0Z" fill="rgb(19, 123, 79)" opacity="0"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -38,7 +38,7 @@ export const BottomNavigation = ({ pages, isDark }) => {
return ( return (
<> <>
<footer <footer
className="w-full flex flex-row justify-around items-center fixed bottom-0 left-0 py-2 z-20 lg:hidden" className="w-full flex justify-around items-center fixed bottom-0 left-0 py-2 z-20 lg:hidden"
style={{ background: isDark ? "hsla(209, 39%, 28%)" : "#E8FCFF" }} style={{ background: isDark ? "hsla(209, 39%, 28%)" : "#E8FCFF" }}
> >
{pages.map((page, index) => ( {pages.map((page, index) => (

@ -1,6 +1,9 @@
import React from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
//components
import Loading from "../Loading";
export const ButtonBetween = ({ export const ButtonBetween = ({
item, item,
status, status,
@ -8,6 +11,7 @@ export const ButtonBetween = ({
width, width,
active, active,
toggle, toggle,
loading,
}) => { }) => {
return toggle ? ( return toggle ? (
<button <button
@ -17,6 +21,9 @@ export const ButtonBetween = ({
onClick={() => onClick()} onClick={() => onClick()}
style={{ width, padding: "18px 8px" }} style={{ width, padding: "18px 8px" }}
> >
{loading ? (
<Loading size={2} color="bg-green-500" />
) : (
<strong <strong
className={`text-tiny ${ className={`text-tiny ${
active ? "text-green-700" : "text-gray-700" active ? "text-green-700" : "text-gray-700"
@ -24,6 +31,8 @@ export const ButtonBetween = ({
> >
{item} {item}
</strong> </strong>
)}
{status && ( {status && (
<span <span
className={`pr-3 border-r border-solid ${ className={`pr-3 border-r border-solid ${
@ -42,7 +51,13 @@ export const ButtonBetween = ({
onClick={() => onClick()} onClick={() => onClick()}
style={{ width, padding: "18px 8px" }} style={{ width, padding: "18px 8px" }}
> >
<strong className="text-tiny text-green-700 font-semibold">{item}</strong> {loading ? (
<Loading size={2} color="bg-green-500" />
) : (
<strong className="text-tiny text-green-700 font-semibold">
{item}
</strong>
)}
{status && ( {status && (
<span className="pr-3 border-r border-solid border-green-600 text-tiny text-green-700 font-semibold"> <span className="pr-3 border-r border-solid border-green-600 text-tiny text-green-700 font-semibold">
{status} {status}

@ -39,8 +39,8 @@ export const Comments = ({ comments, indent }) => {
const Comment = ({ comment }) => { const Comment = ({ comment }) => {
return ( return (
<div className="flex flex-col w-full"> <div className="flex flex-col w-full">
<header className="w-full flex flex-row justify-between py-1"> <header className="w-full flex justify-between py-1">
<div className="flex flex-row items-end"> <div className="flex items-end">
<Avatar source={comment?.userImage} size={60} rounded={true} /> <Avatar source={comment?.userImage} size={60} rounded={true} />
<div className="flex flex-col"> <div className="flex flex-col">
<div className="flex items-center"> <div className="flex items-center">
@ -48,18 +48,18 @@ export const Comments = ({ comments, indent }) => {
<span className="text-tiny text-greenBA mr-3"> <span className="text-tiny text-greenBA mr-3">
{comment?.userRoll || window.t("خریدار محصول")} {comment?.userRoll || window.t("خریدار محصول")}
</span> </span>
<div className="flex flex-row items-center mr-10 font-semibold"> <div className="flex items-center mr-10 font-semibold">
<StarRating /> <StarRating />
</div> </div>
</div> </div>
<div <div
className="flex flex-row divide-x divide-gray-300 mt-4 divided items-center" className="flex divide-x divide-gray-300 mt-4 divided items-center"
style={{ direction: "ltr" }} style={{ direction: "ltr" }}
></div> ></div>
</div> </div>
</div> </div>
<div <div
className="flex flex-row divide-x divide-gray-300 divided items-center" className="flex divide-x divide-gray-300 divided items-center"
style={{ direction: "ltr" }} style={{ direction: "ltr" }}
> >
<span className="px-2 text-sm text-blue-400"> <span className="px-2 text-sm text-blue-400">
@ -73,9 +73,9 @@ export const Comments = ({ comments, indent }) => {
<div className="flex flex-row"> <div className="flex flex-row">
<div style={{ width: 60 }} className="min-h-full"></div> <div style={{ width: 60 }} className="min-h-full"></div>
<div className="flex flex-1 flex-col px-3"> <div className="flex flex-1 flex-col px-3">
<header className="w-full flex flex-row justify-between items-center"> <header className="w-full flex justify-between items-center">
<div>&nbsp;</div> <div>&nbsp;</div>
<div className="flex flex-row items-center"> <div className="flex items-center">
{comment?.status === true && ( {comment?.status === true && (
<> <>
<img src={positiveIcon} alt="" className="w-6 ml-2" /> <img src={positiveIcon} alt="" className="w-6 ml-2" />

@ -33,7 +33,7 @@ const CourseChapter = ({
height: isMobile ? "auto" : "calc(100vh - 300px)", height: isMobile ? "auto" : "calc(100vh - 300px)",
}} }}
> >
<div className="hidden lg:flex flex-row w-full items-center justify-between"> <div className="hidden lg:flex w-full items-center justify-between">
<div> <div>
<h2 className="text-green7B bg-opacity-5 text-base font-semibold"> <h2 className="text-green7B bg-opacity-5 text-base font-semibold">
{window.t("سرفصل دوره")} {window.t("سرفصل دوره")}
@ -48,7 +48,7 @@ const CourseChapter = ({
</div> </div>
<span className="hidden lg:flex w-full h-px bg-blue-200 my-4"></span> <span className="hidden lg:flex w-full h-px bg-blue-200 my-4"></span>
<div className="lg:overflow-y-scroll w-full hasScrollbar flex-1 flex flex-col"> <div className="lg:overflow-y-scroll w-full hasScrollbar flex-1 flex flex-col">
<div className="bg-green-600 rounded-sm p-4 flex flex-row items-center justify-between mb-2"> <div className="bg-green-600 rounded-sm p-4 flex items-center justify-between mb-2">
<p className="text-tiny font-bold text-white"> <p className="text-tiny font-bold text-white">
{seasons?.length > 0 && {seasons?.length > 0 &&
playList?.length > 0 && playList?.length > 0 &&
@ -65,7 +65,7 @@ const CourseChapter = ({
key={index} key={index}
> >
<div <div
className="flex flex-row items-center justify-around" className="flex items-center justify-around"
key={index} key={index}
> >
{/* right div dot dot */} {/* right div dot dot */}
@ -108,7 +108,7 @@ const CourseChapter = ({
disabled={true} disabled={true}
> >
{/* top */} {/* top */}
<div className="flex flex-row items-center justify-between p-3 border-0 border-b border-solid border-green-200"> <div className="flex items-center justify-between p-3 border-0 border-b border-solid border-green-200">
<p <p
className={`text-base lg:text-tiny font-bold className={`text-base lg:text-tiny font-bold
${selectedVideo?.id === video?.id ? "text-white" : ""}`} ${selectedVideo?.id === video?.id ? "text-white" : ""}`}

@ -47,7 +47,7 @@ export const Dialog = ({ dialog, setDialog }) => {
{text} {text}
</p> </p>
{type === "confirm" && ( {type === "confirm" && (
<div className="flex flex-row gap-4 w-full"> <div className="flex gap-4 w-full">
<button <button
className="py-2.5 w-1/2 shadow-md rounded-sm bg-blueC0 text-white" className="py-2.5 w-1/2 shadow-md rounded-sm bg-blueC0 text-white"
onClick={() => acceptFunc()} onClick={() => acceptFunc()}
@ -63,7 +63,7 @@ export const Dialog = ({ dialog, setDialog }) => {
</div> </div>
)} )}
{type === "alert" && ( {type === "alert" && (
<div className="flex flex-row gap-4 w-full"> <div className="flex gap-4 w-full">
<button <button
className="py-2.5 w-full shadow-md rounded-sm bg-blue-400 text-white" className="py-2.5 w-full shadow-md rounded-sm bg-blue-400 text-white"
onClick={() => setDialog({ ...dialog, open: !dialog.open })} onClick={() => setDialog({ ...dialog, open: !dialog.open })}

@ -10,7 +10,7 @@ import homeDarkIcon from "./home-dark.svg";
import logoutIcon from "./logout.svg"; import logoutIcon from "./logout.svg";
import logoutDarkIcon from "./logout-dark.svg"; import logoutDarkIcon from "./logout-dark.svg";
import dangerIcon from "./mobile-danger.svg"; import dangerIcon from "./mobile-danger.svg";
import dangerDarkIcon from "./mobile-danger-dark.svg"; // import dangerDarkIcon from "./mobile-danger-dark.svg";
import activationIcon from "./activation.svg"; import activationIcon from "./activation.svg";
import activationDarkIcon from "./activation-dark.svg"; import activationDarkIcon from "./activation-dark.svg";
import contactIcon from "./contact.svg"; import contactIcon from "./contact.svg";
@ -24,7 +24,7 @@ import cartDarkIcon from "./mobile-basket-dark.svg";
import faqIcon from "./faq.svg"; import faqIcon from "./faq.svg";
import faqDarkIcon from "./faq-dark.svg"; import faqDarkIcon from "./faq-dark.svg";
import arrowLeftVideo from "../../assets/icons/dropdown-white.svg"; // import arrowLeftVideo from "../../assets/icons/dropdown-white.svg";
import sunIcon from "./sun.svg"; import sunIcon from "./sun.svg";
import moonIcon from "./moon.svg"; import moonIcon from "./moon.svg";
@ -40,49 +40,10 @@ const MyDrawer = ({
setDialog, setDialog,
logout, logout,
}) => { }) => {
const [addUserDropdown, setAddUserDropdown] = useState(false); // const [addUserDropdown, setAddUserDropdown] = useState(false);
const publicLink = [
{ const privateLink = React.useMemo(() => {
name: window.t("صفحه اصلی"), return [
link: "/",
icon: (
<img
src={homeIcon}
className="opacity-50 dark:bg-white"
alt={window.t("صفحه اصلی")}
/>
),
toast: "",
message: "",
},
{
name: window.t("ورود یا ثبت نام"),
link: "/signup",
icon: (
<img
src={logoutIcon}
className="opacity-50 dark:bg-white"
alt={window.t("کتابهای من")}
/>
),
toast: "",
message: "",
},
{
name: window.t("پشتیبانی"),
link: "/contact-us",
icon: (
<img
src={dangerIcon}
className="opacity-50 dark:bg-white"
alt={window.t("پشتیبانی")}
/>
),
toast: "",
message: "",
},
];
const privateLink = [
{ {
name: window.t("صفحه اصلی"), name: window.t("صفحه اصلی"),
link: "/", link: "/",
@ -220,6 +181,51 @@ const MyDrawer = ({
}, },
}, },
]; ];
},[isDark, user]);
const publicLink = React.useMemo(() => {
return [
{
name: window.t("صفحه اصلی"),
link: "/",
icon: (
<img
src={homeIcon}
className="opacity-50 dark:bg-white"
alt={window.t("صفحه اصلی")}
/>
),
toast: "",
message: "",
},
{
name: window.t("ورود یا ثبت نام"),
link: "/signup",
icon: (
<img
src={logoutIcon}
className="opacity-50 dark:bg-white"
alt={window.t("کتابهای من")}
/>
),
toast: "",
message: "",
},
{
name: window.t("پشتیبانی"),
link: "/contact-us",
icon: (
<img
src={dangerIcon}
className="opacity-50 dark:bg-white"
alt={window.t("پشتیبانی")}
/>
),
toast: "",
message: "",
},
];
},[isDark, user]);
return ( return (
<Drawer <Drawer
@ -238,7 +244,7 @@ const MyDrawer = ({
className="flex flex-col justify-between h-1/6 pt-3 px-3 bg-green-500 dark:bg-blue90" className="flex flex-col justify-between h-1/6 pt-3 px-3 bg-green-500 dark:bg-blue90"
style={{ minHeight: "calc(100vh / 6)" }} style={{ minHeight: "calc(100vh / 6)" }}
> >
<div className="flex flex-row justify-between"> <div className="flex justify-between">
<Avatar size={70} rounded={true} /> <Avatar size={70} rounded={true} />
<img <img
src={isDark ? sunIcon : moonIcon} src={isDark ? sunIcon : moonIcon}
@ -247,7 +253,7 @@ const MyDrawer = ({
onClick={() => changeDarkMode(!isDark)} onClick={() => changeDarkMode(!isDark)}
/> />
</div> </div>
<div className="flex flex-row justify-between px-2 pb-3 mt-1"> <div className="flex justify-between px-2 pb-3 mt-1">
<div className="flex flex-col"> <div className="flex flex-col">
<strong className="text-lg text-white"> <strong className="text-lg text-white">
{user && user?.firstName + " " + user?.lastName} {user && user?.firstName + " " + user?.lastName}
@ -256,25 +262,25 @@ const MyDrawer = ({
{user?.cellphone} {user?.cellphone}
</span> </span>
</div> </div>
<img {/* <img
src={arrowLeftVideo} src={arrowLeftVideo}
alt="" alt=""
className={`transform ${ className={`transform ${
addUserDropdown ? "rotate-90" : "-rotate-90" addUserDropdown ? "rotate-90" : "-rotate-90"
} cursor-pointer`} } cursor-pointer`}
onClick={() => setAddUserDropdown(() => !addUserDropdown)} onClick={() => setAddUserDropdown(() => !addUserDropdown)}
/> /> */}
</div> </div>
</header> </header>
<ul {/* <ul
className={`flex flex-col ${ className={`flex flex-col ${
addUserDropdown ? "h-20" : "h-0" addUserDropdown ? "h-20" : "h-0"
} transition-all duration-500`} } transition-all duration-500`}
></ul> ></ul> */}
<ul className="h-full flex flex-col py-6 px-4 gap-6"> <ul className="h-full flex flex-col py-6 px-4 gap-6">
{(!user ? publicLink : privateLink).map((item, key) => ( {(!user ? publicLink : privateLink).map((item, key) => (
<Link to={item.link} key={key} onClick={() => item.onClick()}> <Link to={item.link} key={key} onClick={() => item.onClick()}>
<div className="flex flex-row items-center"> <div className="flex items-center">
{item.icon} {item.icon}
<div className="text-gray70 text-tiny mr-5 dark:text-white"> <div className="text-gray70 text-tiny mr-5 dark:text-white">
{item.name} {item.name}

@ -20,22 +20,22 @@ const FooterDesign1 = ({ color, bg, items, hasHeader }) => {
<div className="flex items-center ml-8 "> <div className="flex items-center ml-8 ">
<img src={callIcon} className="p-2" /> <img src={callIcon} className="p-2" />
<div> <div>
<h1 className="text-2xl mb-4 font-bold"> <h1 className="text-lg mb-4 font-bold">
<span className=" text-blueC0 font-black">7</span> <span className=" text-blueC0 font-black">7 </span>
{window.t("روز هفته")} {window.t("روز هفته")}
<span className="text-blueC0 font-black">24</span> <span className="text-blueC0 font-black"> 24 </span>
{window.t("ساعته")} {window.t("ساعته")}
</h1> </h1>
<p className="text-lg font-light text-blue5F"> <p className="text-tiny font-light text-blue5F">
{window.t("منتظر شنیدن صدای گرمتان هستیم")} {window.t("منتظر شنیدن صدای گرمتان هستیم")}
</p> </p>
</div> </div>
</div> </div>
<div className="mr-8 text-lg flex flex-col font-black transform translate-y-0.5"> <div className="mr-8 text-base flex flex-col font-black transform translate-y-0.5">
<a href="tel:654412 021" className="text-left mb-5"> <a href="tel:654412 021" className="text-left mb-5">
654412 021 654412 021
</a> </a>
<a href="mailto:Info@danovin.ir">Info@danovin.ir</a> <a href="mailto:Info@danovin.ir" className="text-tiny">Info@danovin.ir</a>
{/* <a href="https://info@danovin.ir">Info@danovin.ir</a> */} {/* <a href="https://info@danovin.ir">Info@danovin.ir</a> */}
</div> </div>
</div> </div>
@ -44,7 +44,7 @@ const FooterDesign1 = ({ color, bg, items, hasHeader }) => {
<a <a
href="http://danovin.ir/app.apk" href="http://danovin.ir/app.apk"
download download
className="py-4 px-5 text-base font-bold rounded-md bg-blueC0 transition-all transform hover:scale-110 text-white" className="py-4 px-5 text-tiny font-bold rounded-md bg-blueC0 transition-all transform hover:scale-110 text-white"
> >
{window.t("دانلود اپلیکیشن اندروید")} {window.t("دانلود اپلیکیشن اندروید")}
</a> </a>
@ -53,18 +53,18 @@ const FooterDesign1 = ({ color, bg, items, hasHeader }) => {
</div> </div>
) : null} ) : null}
<footer <footer
className={`flex flex-col bg-gray-200 py-16 md:flex-row justify-around items-start md:items-start relative shadow-md z-20 ${bg}`} className={`flex flex-col bg-gray-200 py-16 md:justify-around items-start md:items-start relative shadow-md z-20 ${bg}`}
> >
<div className="w-11/12 flex justify-between"> <div className="w-11/12 flex justify-between mx-auto">
<div className="flex flex-row gap-10"> <div className="flex gap-10">
{items.map((item, index) => ( {items.map((item, index) => (
<div className="flex flex-col" key={index}> <div className="flex flex-col" key={index}>
<strong className="text-xl text-gray70">{item.name}</strong> <strong className="text-base text-gray70">{item.name}</strong>
<ul className="flex flex-col mt-0"> <ul className="flex flex-col mt-0">
{item.links.map((link, index) => ( {item.links.map((link, index) => (
<li className="mt-6" key={index}> <li className="mt-6" key={index}>
<Link <Link
className="text-gray70 text-base " className="text-gray70 text-tiny"
to={link.link} to={link.link}
key={index} key={index}
> >

@ -6,7 +6,7 @@ import arrowWhiteIcon from "../../assets/icons/arrow-left-white.svg";
function Header({ title, link, isDark }) { function Header({ title, link, isDark }) {
return ( return (
<header className="w-full flex flex-row justify-between items-center pl-0"> <header className="w-full flex justify-between items-center pl-0">
<strong className="text-green7B dark:text-white font-semibold text-base lg:text-sm"> <strong className="text-green7B dark:text-white font-semibold text-base lg:text-sm">
{title} {title}
</strong> </strong>

@ -0,0 +1,24 @@
import React from "react";
export default function Modal({ children, open, onClose }) {
const [animationFlag, setAnimationFlag] = React.useState(false);
React.useEffect(() => {
setAnimationFlag(true);
return () => {
setAnimationFlag(false);
};
}, []);
return open ? (
<div
className={`w-full h-full fixed top-0 left-0 z-50 flex items-center justify-center backdrop-filter backdrop-blur-sm bg-black bg-opacity-25 transform transition-all duration-500 origin-center ${
animationFlag ? "scale-100" : "scale-0"
}`}
onClick={() => onClose()}
>
{children}
</div>
) : null;
}

@ -1,5 +1,5 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate, NavLink } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { userProduct, userFavorite } from "../../redux/actions"; import { userProduct, userFavorite } from "../../redux/actions";
import location from "../../utils/location"; import location from "../../utils/location";
@ -9,6 +9,7 @@ import _ from "lodash";
import Drawer from "../Drawer"; import Drawer from "../Drawer";
import Search from "../Search"; import Search from "../Search";
import SearchResult from "./SearchResult"; import SearchResult from "./SearchResult";
import Loading from "../Loading";
//assets //assets
import cartIcon from "./cart-blue.svg"; import cartIcon from "./cart-blue.svg";
@ -24,18 +25,24 @@ import arrowBlueIcon from "../../assets/icons/arrow-right-blue.svg";
import arrowWhiteIcon from "../../assets/icons/arrow-left-white.svg"; import arrowWhiteIcon from "../../assets/icons/arrow-left-white.svg";
import dotsMenuDarkIcon from "../../assets/icons/dots-menu-dark.svg"; import dotsMenuDarkIcon from "../../assets/icons/dots-menu-dark.svg";
import bookmarkDeactiveDarkIcon from "../../assets/icons/bookmark-deactive-dark.svg"; import bookmarkDeactiveDarkIcon from "../../assets/icons/bookmark-deactive-dark.svg";
import bookmarkActiveDarkIcon from "../../assets/icons/bookmark-active-dark.svg";
import dotsMenuLightIcon from "../../assets/icons/dots-menu-light.svg"; import dotsMenuLightIcon from "../../assets/icons/dots-menu-light.svg";
import bookmarkDeactiveLightIcon from "../../assets/icons/bookmark-deactive-light.svg"; import bookmarkDeactiveLightIcon from "../../assets/icons/bookmark-deactive-light.svg";
import bookmarkActiveLightIcon from "../../assets/icons/bookmark-active-light.svg";
function Navbar({ function Navbar({
getCartProducts, getCartProducts,
getUserFavorite,
cartProductsLength, cartProductsLength,
pages, pages,
isDark, isDark,
isMobile, isMobile,
isLogin, user,
headerOptions, headerOptions,
addToFavorite, addToFavorite,
deleteBookmark,
bookmarkLoading,
userFavoriteList,
language, language,
}) { }) {
const navigation = useNavigate(); const navigation = useNavigate();
@ -46,11 +53,22 @@ function Navbar({
const [search, setSearch] = useState(null); const [search, setSearch] = useState(null);
const [drawerOpen, setDrawerOpen] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false);
const isActiveBookmark = React.useMemo(() => {
return userFavoriteList?.find((object) =>
headerOptions?.productId
? object?.productId === headerOptions?.productId
: object?.contentId === headerOptions?.contentId
);
}, [headerOptions, userFavoriteList]);
console.log(Boolean(isActiveBookmark));
useEffect(() => { useEffect(() => {
if (window.scrollY === 0) { if (window.scrollY === 0) {
setTop(() => true); setTop(() => true);
} }
if (isMobile) { if (isMobile) {
// getUserFavorite();
window.addEventListener("scroll", () => { window.addEventListener("scroll", () => {
if (window.scrollY === 0) { if (window.scrollY === 0) {
setTop(() => true); setTop(() => true);
@ -62,30 +80,60 @@ function Navbar({
}, []); }, []);
useEffect(() => { useEffect(() => {
if (!isMobile && isLogin) { if (!isMobile && user) {
console.log(111);
getCartProducts(); getCartProducts();
} }
}, [isLogin]); }, [user]);
return isMobile ? ( return (
<div <div
className={_.join( className="z-50 flex fixed left-0 top-0 w-full"
[
"z-50 flex flex-1 flex-row fixed left-0 top-0 justify-between w-full lg:bg-opacity-20 lg:bg-transparent lg:shadow-sm lg:backdrop-filter lg:backdrop-blur-md lg:px-5 xl:px-10 transition-all duration-300",
],
" "
)}
style={{ style={{
backgroundColor: !top ? (isDark ? "#061B30" : "white") : "", backgroundColor: !top ? (isDark ? "#061B30" : "white") : "",
}} }}
> >
{/* landscape start */} <div className="w-full lg:w-11/12 lg:mx-auto relative flex items-center justify-between py-3 px-4" style={{
{/* landscape end */} backgroundColor: isDark ? "#061B30" : "white"
{/* portrait start */} }}>
{/* desktop */}
<div className=" items-center hidden lg:flex">
<Link
to="/"
className="flex items-center text-2xl font-black text-green7B"
>
<img src={logoIcon} className="w-8 relative bottom-1 ml-1" alt="" />
{window.t("دانوین")}
</Link>
<div className="w-full h-full relative flex flex-row items-center justify-between lg:hidden py-3 px-4"> <ul className="flex list-none items-center relative top-0.5 mr-4">
<div className="relative"> {pages.map((page, index) => (
<li key={index}>
<NavLink
to={page.link}
className="text-tiny py-2 px-4 mx-4"
style={({ isActive }) => ({
color: isActive ? "rgb(19, 123, 79)" : "#202020",
fontWeight: isActive ? "700" : "200",
})}
>
{page.name}
</NavLink>
</li>
))}
</ul>
</div>
{logo && (
<Link
to="/"
className="lg:hidden absolute left-1/2 transform -translate-y-1/2 top-1/2 -translate-x-1/2"
>
<img src={logoIcon} className="w-6 h-8" />
</Link>
)}
{/* desktop */}
{/* <div className="flex items-center"></div> */}
<div className="flex lg:hidden relative">
{hamburgerMenu && ( {hamburgerMenu && (
<> <>
<span className="w-2.5 h-2.5 rounded-full bg-redFF1 absolute -left-1 -top-1 animate-bounce"></span> <span className="w-2.5 h-2.5 rounded-full bg-redFF1 absolute -left-1 -top-1 animate-bounce"></span>
@ -97,7 +145,6 @@ function Navbar({
/> />
</> </>
)} )}
{!title && back ? ( {!title && back ? (
<img <img
src={isDark ? arrowWhiteIcon : arrowBlueIcon} src={isDark ? arrowWhiteIcon : arrowBlueIcon}
@ -112,29 +159,31 @@ function Navbar({
</strong> </strong>
)} )}
</div> </div>
{logo && ( <div className="flex items-center">
<Link {overLayer && (
to="/" <div
className="absolute left-1/2 transform -translate-y-1/2 top-1/2 -translate-x-1/2" className="z-30 w-screen h-full fixed top-0 right-0 backdrop-filter blur-sm bg-opacity-60 bg-gray-600"
onClick={() => setOverLayer(false)}
> >
<img src={logoIcon} className="w-6 h-8" /> <div className="relative w-full h-full">
</Link> <div
className="flex flex-col w-full absolute left-1/2 top-16 transform -translate-x-1/2 z-50 rounded-md"
style={{ maxWidth: "calc(100vw / 3)" }}
onClick={(e) => e.stopPropagation()}
>
<Search onChange={(val) => setSearch(val)} />
{search && <SearchResult text={search} setText={setSearch} />}
</div>
</div>
</div>
)} )}
<div className="flex flex-row items-center">
{qr && ( {qr && (
<> <>
<Link <Link
to="/scan" to="/scan"
className={_.join( className={`flex lg:hidden rounded-sm p-1.5 ${
[ isDark ? "bg-blueC0 bg-opacity-10 ml-2" : " ml-3 shadow-sm"
"rounded-sm p-1.5", }`}
isDark
? "bg-blueC0 bg-opacity-10 ml-2"
: " ml-3 shadow-sm",
],
" "
)}
style={{ style={{
border: `1px solid ${isDark ? "#D7E3FC20" : "#D7E3FC"}`, border: `1px solid ${isDark ? "#D7E3FC20" : "#D7E3FC"}`,
}} }}
@ -147,13 +196,9 @@ function Navbar({
</Link> </Link>
<Link <Link
to="/ar" to="/ar"
className={_.join( className={`flex lg:hidden rounded-sm p-1.5 ${
[ isDark ? "bg-blueC0 bg-opacity-10" : "shadow-sm"
"rounded-sm p-1.5", }`}
isDark ? "bg-blueC0 bg-opacity-10" : " shadow-sm",
],
" "
)}
style={{ style={{
border: `1px solid ${isDark ? "#D7E3FC20" : "#D7E3FC"}`, border: `1px solid ${isDark ? "#D7E3FC20" : "#D7E3FC"}`,
}} }}
@ -166,93 +211,56 @@ function Navbar({
</Link> </Link>
</> </>
)} )}
{bookmark && ( {bookmark ? (
bookmarkLoading ? (
<Loading size={2} color="bg-green-500" />
) : isActiveBookmark ? (
<img
src={
isDark ? bookmarkActiveDarkIcon : bookmarkActiveLightIcon
}
alt="bookmark"
className="w-7 flex lg:hidden"
onClick={() =>
deleteBookmark({
id: userFavoriteList?.find(
(object) => object?.productId === headerOptions?.productId
)?.id,
})
}
/>
) : (
<img <img
src={ src={
isDark ? bookmarkDeactiveDarkIcon : bookmarkDeactiveLightIcon isDark ? bookmarkDeactiveDarkIcon : bookmarkDeactiveLightIcon
} }
alt="bookmark" alt="bookmark"
className="w-7" className="w-7 flex lg:hidden"
onClick={() => addToFavorite({ [bookmark]: location.getId() })} onClick={() => addToFavorite({ [bookmark]: location.getId() })}
/> />
)} )
) : null}
{menu && ( {menu && (
<img <img
src={isDark ? dotsMenuDarkIcon : dotsMenuLightIcon} src={isDark ? dotsMenuDarkIcon : dotsMenuLightIcon}
alt="menu" alt="menu"
className="w-7 mr-2" className="w-7 mr-2 flex lg:hidden"
/> />
)} )}
{title && back ? ( {title && back ? (
<img <img
src={isDark ? arrowWhiteIcon : arrowBlueIcon} src={isDark ? arrowWhiteIcon : arrowBlueIcon}
alt="back" alt="back"
className={`w-6 transform ${isDark ? "" : "-rotate-180"}`} className={`w-6 flex lg:hidden transform ${
isDark ? "" : "-rotate-180"
}`}
onClick={() => navigation(-1)} onClick={() => navigation(-1)}
/> />
) : null} ) : null}
</div> {/* desktop */}
</div>
<Drawer drawerOpen={drawerOpen} setDrawerOpen={setDrawerOpen} />
{/* portrait end */}
</div>
) : (
<header
className={`w-full border-b border-gray-200 border-solid fixed top-0 right-0 bg-white z-20`}
style={{ boxShadow: "0px 0px 10px rgba(0,0,0,0.1)" }}
>
<div className={`w-11/12 mx-auto flex flex-col`}>
<div className="w-full flex flex-row items-center py-3 relative justify-between h-ful">
<div className="flex flex-row items-center">
<Link
to="/"
className="flex flex-row items-center text-2xl font-black text-green7B"
>
<img
src={logoIcon}
className="w-8 relative bottom-1 ml-1"
alt=""
/>
{window.t("دانوین")}
</Link>
<ul className="flex flex-row list-none items-center relative top-0.5 mr-6">
{pages.map((page, index) => (
<li key={index}>
<Link
to={page.link}
className="text-tiny font-semibold text-green7B py-2 px-4 mx-4"
>
{page.name}
</Link>
</li>
))}
</ul>
</div>
{overLayer && (
<div
className="z-30 w-screen h-full fixed top-0 right-0 backdrop-filter blur-sm bg-opacity-60 bg-gray-600"
onClick={() => setOverLayer(false)}
>
<div className="relative w-full h-full">
<div
className="flex flex-col w-full absolute left-1/2 top-16 transform -translate-x-1/2 z-50 rounded-md"
style={{ maxWidth: "calc(100vw / 3)" }}
onClick={(e) => e.stopPropagation()}
>
<Search onChange={(val) => setSearch(val)} />
{search && <SearchResult text={search} setText={setSearch} />}
</div>
</div>
</div>
)}
<div className="flex flex-row items-center">
<select <select
style={{ width: "100px" }} style={{ width: "100px" }}
className="flex items-center text-blueC0 border border-blueC0 px-1 rounded base py-1.5 ml-4 cursor-pointer" className="hidden lg:flex items-center text-blueC0 border border-blueC0 px-1 rounded base py-1.5 ml-4 cursor-pointer"
> >
{language.map((item, index) => ( {language.map((item, index) => (
<option <option
@ -267,12 +275,12 @@ function Navbar({
<img <img
src={searchIcon} src={searchIcon}
alt="" alt=""
className="w-7 ml-3 cursor-pointer" className="w-7 ml-3 cursor-pointer lg:flex hidden"
onClick={() => setOverLayer(true)} onClick={() => setOverLayer(true)}
/> />
{isLogin && ( {user && (
<div className="flex justify-end items-center gap-4"> <div className="hidden lg:flex justify-end items-center gap-4">
<Link to="/cart" className="relative"> <Link to="/cart" className="relative">
<img src={cartIcon} alt="" className="w-8" /> <img src={cartIcon} alt="" className="w-8" />
<span className="absolute -right-2 -top-0.5 w-4 p-2.5 h-4 flex justify-center items-center bg-green-700 bg-opacity-100 rounded-full text-white text-xs"> <span className="absolute -right-2 -top-0.5 w-4 p-2.5 h-4 flex justify-center items-center bg-green-700 bg-opacity-100 rounded-full text-white text-xs">
@ -285,7 +293,7 @@ function Navbar({
</div> </div>
)} )}
{!isLogin ? ( {!user ? (
<Link <Link
to="/signup" to="/signup"
className="bg-blueC0 font-semibold text-white rounded-md px-4 py-3 text-sm mr-7 hover:bg-opacity-90 shadow-sm" className="bg-blueC0 font-semibold text-white rounded-md px-4 py-3 text-sm mr-7 hover:bg-opacity-90 shadow-sm"
@ -295,15 +303,17 @@ function Navbar({
) : ( ) : (
<Link <Link
to="/dashboard" to="/dashboard"
className="bg-blueC0 font-semibold text-white rounded-md px-4 py-3 text-sm mr-7 hover:bg-opacity-90 shadow-sm" className="hidden lg:flex bg-blueC0 font-semibold text-white rounded-md px-4 py-3 text-sm mr-7 hover:bg-opacity-90 shadow-sm"
> >
{window.t("حساب کاربری")} {window.t("حساب کاربری")}
</Link> </Link>
)} )}
{/* desktop */}
</div> </div>
</div> </div>
<Drawer drawerOpen={drawerOpen} setDrawerOpen={setDrawerOpen} />
</div> </div>
</header>
); );
} }
@ -311,15 +321,19 @@ const mapStateToProps = (state) => ({
isDark: state.publicApi.isDark, isDark: state.publicApi.isDark,
isMobile: state.publicApi.isMobile, isMobile: state.publicApi.isMobile,
headerOptions: state.publicApi.headerOptions, headerOptions: state.publicApi.headerOptions,
isLogin: state.user.status, user: state.user.status,
cartProductsLength: state.userProduct.list?.filter( cartProductsLength: state.userProduct.list?.filter(
(product) => product.condition < 2 (product) => product.condition < 2
)?.length, )?.length,
bookmarkLoading: state.userFavorite.loading,
userFavoriteList: state.userFavorite.list,
}); });
const mapDispatchToProps = { const mapDispatchToProps = {
getCartProducts: userProduct.list, getCartProducts: userProduct.list,
addToFavorite: userFavorite.add, addToFavorite: userFavorite.add,
deleteBookmark: userFavorite.del,
getUserFavorite: userFavorite.list
}; };
export default connect(mapStateToProps, mapDispatchToProps)(Navbar); export default connect(mapStateToProps, mapDispatchToProps)(Navbar);

@ -2,7 +2,7 @@ import React from "react";
function OR({}) { function OR({}) {
return ( return (
<div className="w-full flex flex-row justify-between items-center my-3 lg:my-5"> <div className="w-full flex justify-between items-center my-3 lg:my-5">
<div <div
style={{ width: "43%", height: 1, backgroundColor: "#EFEFEF" }} style={{ width: "43%", height: 1, backgroundColor: "#EFEFEF" }}
></div> ></div>

@ -13,7 +13,7 @@ const ProductImage = ({ images }) => {
} }
}, [images]); }, [images]);
return ( return (
<div className="flex flex-row w-1/3 gap-2"> <div className="flex w-1/3 gap-2">
<div <div
className="flex flex-col items-center justify-between w-1/5" className="flex flex-col items-center justify-between w-1/5"
style={{ height: "calc(100vw / 5)" }} style={{ height: "calc(100vw / 5)" }}

@ -37,8 +37,8 @@ const ProductStatusCard = ({
return ( return (
<section className="w-full" style={{ minWidth: 350 }}> <section className="w-full" style={{ minWidth: 350 }}>
<div className="bg-grayF9 rounded-md px-4 py-2 divide-y divide-solid divide-gray-200"> <div className="bg-grayF9 rounded-md px-4 py-2 divide-y divide-solid divide-gray-200">
<div className="flex flex-row items-center justify-between py-3"> <div className="flex items-center justify-between py-3">
<div className="flex flex-row items-center"> <div className="flex items-center">
<img src={tick} alt="" className="w-8" /> <img src={tick} alt="" className="w-8" />
<div className="flex flex-col mr-3"> <div className="flex flex-col mr-3">
<div className="text-sm">{`${window.t( <div className="text-sm">{`${window.t(
@ -49,8 +49,8 @@ const ProductStatusCard = ({
</div> </div>
{seller && ( {seller && (
<div className="flex flex-row items-center justify-between py-3"> <div className="flex items-center justify-between py-3">
<div className="flex flex-row items-center"> <div className="flex items-center">
<img src={shop} alt="" className="w-8" /> <img src={shop} alt="" className="w-8" />
<div className="flex flex-1 flex-col mr-3 text-sm gap-2"> <div className="flex flex-1 flex-col mr-3 text-sm gap-2">
<div className="text-tiny">{"فروشنده" + " " + seller.name}</div> <div className="text-tiny">{"فروشنده" + " " + seller.name}</div>
@ -63,11 +63,11 @@ const ProductStatusCard = ({
</div> </div>
)} )}
<div className="flex flex-row items-center justify-between py-3"> <div className="flex items-center justify-between py-3">
<div className="flex flex-row items-center"> <div className="flex items-center">
<img src={delivery} alt="" className="w-8" /> <img src={delivery} alt="" className="w-8" />
<div className="flex flex-col mr-3"> <div className="flex flex-col mr-3">
<div className="flex flex-row gap-1 text-sm"> <div className="flex gap-1 text-sm">
&nbsp;{shippingTime} &nbsp;{shippingTime}
</div> </div>
</div> </div>
@ -75,18 +75,18 @@ const ProductStatusCard = ({
</div> </div>
{garanty && ( {garanty && (
<div className="flex flex-row items-center justify-between py-3"> <div className="flex items-center justify-between py-3">
<div className="flex flex-row items-center"> <div className="flex items-center">
<img src={shield} alt="" className="w-8" /> <img src={shield} alt="" className="w-8" />
<div className="flex flex-col mr-3"> <div className="flex flex-col mr-3">
<div className="flex flex-row gap-1 text-sm">{garanty}</div> <div className="flex gap-1 text-sm">{garanty}</div>
</div> </div>
</div> </div>
</div> </div>
)} )}
{bookmark && ( {bookmark && (
<div className="flex flex-row items-center py-3"> <div className="flex items-center py-3">
<img <img
src={ src={
isDark ? bookmarkDeactiveDarkIcon : bookmarkDeactiveLightIcon isDark ? bookmarkDeactiveDarkIcon : bookmarkDeactiveLightIcon
@ -141,7 +141,7 @@ const ProductStatusCard = ({
} }
/> />
</div> </div>
<div className="bg-grayF9 rounded px-4 py-2 mt-4 flex flex-row items-center"> <div className="bg-grayF9 rounded px-4 py-2 mt-4 flex items-center">
<div> <div>
<img src={arrow} alt="" className="w-20 h-20" /> <img src={arrow} alt="" className="w-20 h-20" />
</div> </div>

@ -46,10 +46,10 @@ const ProductSuggestion = ({
{window.t("این کالاها برای خرید به شما پیشنهام می دهیم")} {window.t("این کالاها برای خرید به شما پیشنهام می دهیم")}
</h2> </h2>
{/* product design */} {/* product design */}
<div className="flex flex-row flex-wrap items-center justify-center mt-5 w-full gap-10"> <div className="flex flex-wrap items-center justify-center mt-5 w-full gap-10">
{similarList.map((book, index) => ( {similarList.map((book, index) => (
<div <div
className="flex flex-row mb-7 justify-center relative" className="flex mb-7 justify-center relative"
style={{ maxWidth: "calc(100% / 5)" }} style={{ maxWidth: "calc(100% / 5)" }}
key={index} key={index}
> >
@ -98,7 +98,7 @@ const ProductSuggestion = ({
</div> </div>
{/* bottom */} {/* bottom */}
<div className="flex flex-col justify-center items-center mt-4"> <div className="flex flex-col justify-center items-center mt-4">
<div className="flex flex-row mb-5"> <div className="flex mb-5">
<p className="text-base text-productPrice font-bold"> <p className="text-base text-productPrice font-bold">
&nbsp; &nbsp;
{window.t("جمع لوازم اختیاری خریداری شده")} {window.t("جمع لوازم اختیاری خریداری شده")}

@ -7,7 +7,7 @@ const ProductTab = ({ tabs }) => {
return ( return (
<section className="mt-10 flex flex-col w-full"> <section className="mt-10 flex flex-col w-full">
<div className="rounded-md bg-grayF9"> <div className="rounded-md bg-grayF9">
<ul className="flex flex-row justify-center gap-16"> <ul className="flex justify-center gap-16">
{tabs.map((tab, index) => {tabs.map((tab, index) =>
tab.shown ? ( tab.shown ? (
<li <li

@ -14,8 +14,8 @@ const QandA = ({ comments }) => {
return ( return (
<> <>
<div className="flex flex-col leading-7 w-full py-6 border-t-2 border-solid border-gray-200"> <div className="flex flex-col leading-7 w-full py-6 border-t-2 border-solid border-gray-200">
<header className="w-full flex flex-row justify-between py-1"> <header className="w-full flex justify-between py-1">
<div className="flex flex-row items-end"> <div className="flex items-end">
<div className="flex items-center"> <div className="flex items-center">
<strong className="text-lg mx-2">{comment.username}</strong> <strong className="text-lg mx-2">{comment.username}</strong>
{comment.isCostumer ? ( {comment.isCostumer ? (
@ -26,7 +26,7 @@ const QandA = ({ comments }) => {
</div> </div>
</div> </div>
<div <div
className="flex flex-row divide-x divide-gray-300 divided items-center" className="flex divide-x divide-gray-300 divided items-center"
style={{ direction: "ltr" }} style={{ direction: "ltr" }}
> >
<span className="px-2 text-sm text-blue-400"> <span className="px-2 text-sm text-blue-400">
@ -38,11 +38,11 @@ const QandA = ({ comments }) => {
</span> </span>
</div> </div>
</header> </header>
<div className="flex flex-row py-4"> <div className="flex py-4">
<div style={{ width: 60 }} className="min-h-full"></div> <div style={{ width: 60 }} className="min-h-full"></div>
<div className="flex flex-1 flex-col px-3"> <div className="flex flex-1 flex-col px-3">
<header className="w-full flex flex-row justify-between items-center"> <header className="w-full flex justify-between items-center">
<div className="flex flex-row items-center"> <div className="flex items-center">
<div className="py-4 px-6 bg-blue-100 text-gray-400 rounded"> <div className="py-4 px-6 bg-blue-100 text-gray-400 rounded">
<h1>{window.t("پرسش")}</h1> <h1>{window.t("پرسش")}</h1>
</div> </div>
@ -58,11 +58,11 @@ const QandA = ({ comments }) => {
{comment.answers.length > 0 ? ( {comment.answers.length > 0 ? (
comment.answers.slice(0, numberOfAnswers).map((item, index) => ( comment.answers.slice(0, numberOfAnswers).map((item, index) => (
<div className="flex flex-row py-1" key={index}> <div className="flex py-1" key={index}>
<div style={{ width: 60 }} className="min-h-full"></div> <div style={{ width: 60 }} className="min-h-full"></div>
<div className="flex flex-1 flex-col px-3"> <div className="flex flex-1 flex-col px-3">
<header className="w-full flex flex-row justify-between items-center"> <header className="w-full flex justify-between items-center">
<div className="flex flex-row items-center"> <div className="flex items-center">
<div className="py-4 px-6 bg-green-100 text-gray-400 rounded"> <div className="py-4 px-6 bg-green-100 text-gray-400 rounded">
<h1>{window.t("پاسخال پاسخ")}</h1> <h1>{window.t("پاسخال پاسخ")}</h1>
</div> </div>
@ -79,8 +79,8 @@ const QandA = ({ comments }) => {
</div> </div>
)) ))
) : ( ) : (
<header className="w-full flex flex-row justify-between items-center"> <header className="w-full flex justify-between items-center">
<div className="flex w-4/5 flex-row items-center"> <div className="flex w-4/5 items-center">
<div className="py-4 px-6 bg-green-100 text-gray-400 mx-16 rounded"> <div className="py-4 px-6 bg-green-100 text-gray-400 mx-16 rounded">
<h1>{window.t("ارسال پاسخ")}</h1> <h1>{window.t("ارسال پاسخ")}</h1>
</div> </div>

@ -19,7 +19,8 @@ function StarRating({
const [rate, setRating] = React.useState(null); const [rate, setRating] = React.useState(null);
useMemo(() => { useMemo(() => {
if (isLogin) getUserProducts(); //console.log("gl2");
// if (isLogin && !userProducts.length) getUserProducts();
}, []); }, []);
React.useEffect(() => { React.useEffect(() => {

@ -55,9 +55,9 @@ export default function VerticalExpandableProductFilter(props) {
(item1, i) => ( (item1, i) => (
<li <li
key={i} key={i}
className="hover:bg-gray-100 px-3 flex flex-row items-center justify-between py-2" className="hover:bg-gray-100 px-3 flex items-center justify-between py-2"
> >
<div className="flex flex-row items-center"> <div className="flex items-center">
<Checkbox <Checkbox
name={`ch${name}_${i}`} name={`ch${name}_${i}`}
checked={true} checked={true}

@ -2,6 +2,7 @@
@tailwind components; @tailwind components;
@tailwind utilities; @tailwind utilities;
.bg-dark { .bg-dark {
background: hsla(209, 39%, 28%, 1); background: hsla(209, 39%, 28%, 1);

@ -7,7 +7,9 @@ const blog = {
info: (data) => async (dispatch) => info: (data) => async (dispatch) =>
await proxy.get("public/blogInfo", data, { dispatch }), await proxy.get("public/blogInfo", data, { dispatch }),
active: (data) => async (dispatch) => active: (data) => async (dispatch) =>
await dispatch({ type: "public/active", data }), await dispatch({ type: "blog/active", data }),
setActiveHashtag: (data) => async (dispatch) =>
await dispatch({ type: "blog/activeHashtag", data }),
letterAdd: (data) => async (dispatch) => letterAdd: (data) => async (dispatch) =>
await proxy.post("news/LetterAdd", data, { dispatch }), await proxy.post("news/LetterAdd", data, { dispatch }),
}; };

@ -13,6 +13,7 @@ const comment = {
(data = {}, data2) => (data = {}, data2) =>
async (dispatch) => { async (dispatch) => {
await proxy.post("comment/add", data, { dispatch }); await proxy.post("comment/add", data, { dispatch });
dispatch({ type : "form/ticket/reset" });
if (data2) await proxy.get("book/info", data2, { dispatch }); if (data2) await proxy.get("book/info", data2, { dispatch });
}, },
del: del:

@ -0,0 +1,12 @@
import proxy from "../proxy";
const config = {
setDevice: (data) => async (dispatch) =>
await dispatch({ type: "config/setDevice", data }),
getAvailableForSell:
(data = {}) =>
async (dispatch) =>
await proxy.get("config/availableForSell", data, { dispatch }),
};
export default config;

@ -19,3 +19,4 @@ export {default as comment} from "./comment";
export {default as form} from "./form"; export {default as form} from "./form";
export {default as dialog} from "./dialog"; export {default as dialog} from "./dialog";
export {default as menu} from "./menu"; export {default as menu} from "./menu";
export {default as config} from "./config";

@ -5,31 +5,37 @@ const initialState = {
error: null, error: null,
list: [], list: [],
info: null, info: null,
hashtags : [], hashtags: [],
active: null, active: null,
activeHashtag: "همه",
}; };
export default function blog(state = initialState, action) { export default function blog(state = initialState, action) {
let { type, data } = action; let { type, data } = action;
switch (type) { switch (type) {
case "blog/activeHashtag":
return {
...state,
activeHashtag: data,
};
case "public/blogList": case "public/blogList":
return { return {
...state, ...state,
loading: false, loading: false,
list: data, list: data,
hashtags: [...new Set(data.map((object) => object.tag))], hashtags: ["همه", ...new Set(data.map((object) => object.tag))],
error: null, error: null,
}; };
case "public/active": case "blog/active":
return { return {
...state, ...state,
active : data, active: data,
loading: false, loading: false,
error: null, error: null,
}; };
case "public/blogInfo": case "public/blogInfo":
return { ...state, loading: false, error: null, blog: data }; return { ...state, loading: false, error: null, blog: data };
case "news/LetterAdd": case "news/LetterAdd":
toast.success('.به خبرنامه دانوین خوش آمدید'); toast.success(".به خبرنامه دانوین خوش آمدید");
return { ...state, loading: false, error: null }; return { ...state, loading: false, error: null };
case "blog/loading": case "blog/loading":
return { ...state, loading: true }; return { ...state, loading: true };

@ -0,0 +1,24 @@
const initialState = {
device: "mobile",
availableForSell: [],
};
export default function config(state = initialState, action) {
let { type, data } = action;
switch (type) {
case "config/setDevice":
return {
...state,
device: data,
};
case "config/availableForSell":
return {
...state,
loading: false,
availableForSell: data.productTypes,
error: null,
};
default:
return state;
}
}

@ -15,6 +15,8 @@ export default function form(state = initialState, action) {
ticket: { ...state.ticket, [data.name]: data.value }, ticket: { ...state.ticket, [data.name]: data.value },
error: null, error: null,
}; };
case "form/ticket/reset":
return { ...state, ticket: {} };
case "form/loading": case "form/loading":
return { ...state, loading: true }; return { ...state, loading: true };
case "form/error": case "form/error":

@ -19,3 +19,4 @@ export {default as comment} from "./comment";
export {default as form} from "./form"; export {default as form} from "./form";
export {default as dialog} from "./dialog"; export {default as dialog} from "./dialog";
export {default as menu} from "./menu"; export {default as menu} from "./menu";
export {default as config} from "./config";

@ -2,7 +2,7 @@ import React, { useEffect } from "react";
import { BrowserRouter, Routes, Route } from "react-router-dom"; import { BrowserRouter, Routes, Route } from "react-router-dom";
import { Navigate } from "react-router-dom"; import { Navigate } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi, menu } from "./redux/actions"; import { publicApi, menu, config, userProduct } from "./redux/actions";
import Navbar from "./components/Navbar"; import Navbar from "./components/Navbar";
import BG from "./components/BG"; import BG from "./components/BG";
import BottomNavigation from "./components/BottomNavigation"; import BottomNavigation from "./components/BottomNavigation";
@ -35,11 +35,60 @@ import Address from "./views/Address";
import Favorites from "./views/Favorites"; import Favorites from "./views/Favorites";
import Addresses from "./views/Dashboard/layouts/Mobile/ProfileAddress"; import Addresses from "./views/Dashboard/layouts/Mobile/ProfileAddress";
function Router({ isDark, isMobile, headerOptions, dialog, menu, setMenu }) { function Router({
isDark,
isMobile,
headerOptions,
dialog,
menu,
setMenu,
setDevice,
device,
getAvailableForSell,
getUserProducts
}) {
useEffect(() => { useEffect(() => {
window.addEventListener("scroll", () => {}); getAvailableForSell();
getUserProducts();
const width = window.innerWidth;
if (width <= 640) {
setDevice("mobile");
}
if (width > 640 && width < 1024) {
setDevice("tablet");
}
if (width > 1024) {
setDevice("desktop");
}
}, []); }, []);
React.useEffect(() => {
window.addEventListener("resize", () => {
const width = window.innerWidth;
if (width <= 640) {
if (device === "mobile") {
return;
} else {
setDevice("mobile");
}
}
if (width > 640 && width < 1024) {
if (device === "tablet") {
return;
} else {
setDevice("tablet");
}
}
if (width > 1024) {
if (device === "desktop") {
return;
} else {
setDevice("desktop");
}
}
});
}, [device]);
const prevDefault = (e) => { const prevDefault = (e) => {
setMenu(); setMenu();
e.stopPropagation(); e.stopPropagation();
@ -116,7 +165,17 @@ function Router({ isDark, isMobile, headerOptions, dialog, menu, setMenu }) {
path="/products" path="/products"
exact exact
element={ element={
<Products headerOptions={{ shown: isMobile ? false : true }} /> <Products
headerOptions={{
logo: true,
hamburgerMenu: true,
qr: true,
title: false,
back: false,
shown: true,
menu: false,
}}
/>
} }
/> />
<Route <Route
@ -478,15 +537,15 @@ function Router({ isDark, isMobile, headerOptions, dialog, menu, setMenu }) {
exact exact
element={ element={
<Blogs <Blogs
// headerOptions={{ headerOptions={{
// logo: true, logo: true,
// hamburgerMenu: true, hamburgerMenu: true,
// qr: true, qr: true,
// title: false, title: false,
// back: false, back: false,
// shown: true, shown: true,
// menu: false, menu: false,
// }} }}
/> />
} }
/> />
@ -535,16 +594,20 @@ function Router({ isDark, isMobile, headerOptions, dialog, menu, setMenu }) {
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
isDark: state.publicApi.isDark, isDark: state.publicApi.isDark,
isMobile: state.publicApi.isMobile, isMobile: state.config.device === "mobile",
isLogin: state.user.status, isLogin: state.user.status,
headerOptions: state.publicApi.headerOptions, headerOptions: state.publicApi.headerOptions,
dialog: state.dialog.dialog, dialog: state.dialog.dialog,
menu: state.menu.open, menu: state.menu.open,
device: state.config.device,
}); });
const mapDispatchToProps = { const mapDispatchToProps = {
setDesktopContentTransform: publicApi.setDesktopContentTransform, setDesktopContentTransform: publicApi.setDesktopContentTransform,
setMenu: menu.set, setMenu: menu.set,
setDevice: config.setDevice,
getAvailableForSell: config.getAvailableForSell,
getUserProducts: userProduct.list
}; };
export default connect(mapStateToProps, mapDispatchToProps)(Router); export default connect(mapStateToProps, mapDispatchToProps)(Router);

@ -17,8 +17,9 @@ function About({
first, first,
setHeaderOptions, setHeaderOptions,
}) { }) {
useEffect(() => { useEffect(() => {
setHeaderOptions({ shown: true }); setHeaderOptions({ shown: true, hamburgerMenu : true, logo: true, qr : true });
}, []); }, []);
useEffect(() => { useEffect(() => {
@ -26,8 +27,8 @@ function About({
}, []); }, []);
return ( return (
<div className={_.join(["about w-11/12 mx-auto flex flex-col"], " ")}> <div className="about w-11/12 mx-auto flex flex-col py-8 lg:py-16">
<main className="flex flex-col items-center pt-16 "> <main className="flex flex-col items-center">
<header> <header>
<h1>{first.title}</h1> <h1>{first.title}</h1>
<p <p

@ -1,4 +1,4 @@
$gray : #aaa; $gray : #222;
$green3 : #00cc69; $green3 : #00cc69;
@ -6,7 +6,7 @@ $green3 : #00cc69;
main { main {
li::before { li::before {
color: $gray; color: $gray;
content: "\2022"; // content: "\2022";
font-weight: bold; font-weight: bold;
display: inline-block; display: inline-block;
width: 1em; width: 1em;

@ -4,7 +4,7 @@ import React from 'react'
import alertIcon from '../../../assets/icons/alert.svg'; import alertIcon from '../../../assets/icons/alert.svg';
function Alert({text}) { function Alert({text}) {
return ( return (
<div className="flex flex-row items-center bg-blueFD rounded-md border border-solid border-blueC0 py-3 px-2 w-full my-3 dark:bg-opacity-5"> <div className="flex items-center bg-blueFD rounded-md border border-solid border-blueC0 py-3 px-2 w-full my-3 dark:bg-opacity-5">
<img src={alertIcon} alt="" /> <img src={alertIcon} alt="" />
<p className="text-blueC0 text-xs mr-3 dark:text-white leading-5 lg:text-sm"> <p className="text-blueC0 text-xs mr-3 dark:text-white leading-5 lg:text-sm">
{text} {text}

@ -335,7 +335,7 @@ export const Address = ({
onClick={() => submit()} onClick={() => submit()}
/> />
<button <button
className="bg-transparent mt-4 text-base lg:text-tiny border border-blueC0 text-blueC0 font-bold rounded-md py-3.5 lg:py-4 flex flex-row justify-center items-center" className="bg-transparent mt-4 text-base lg:text-tiny border border-blueC0 text-blueC0 font-bold rounded-md py-3.5 lg:py-4 flex justify-center items-center"
onClick={() => { onClick={() => {
setPhase("deliveryForm"); setPhase("deliveryForm");
navigation(-1); navigation(-1);
@ -363,7 +363,7 @@ export const Address = ({
<div className="flex item-center gap-x-4"> <div className="flex item-center gap-x-4">
{/* my self */} {/* my self */}
<div <div
className={`flex flex-row items-center mb-7 cursor-pointer className={`flex items-center mb-7 cursor-pointer
`} `}
onClick={() => { onClick={() => {
setActiveCheckbox(true); setActiveCheckbox(true);
@ -380,7 +380,7 @@ export const Address = ({
</div> </div>
{/* someone else */} {/* someone else */}
<div <div
className={`flex flex-row items-center mb-7 cursor-pointer className={`flex items-center mb-7 cursor-pointer
`} `}
onClick={() => { onClick={() => {
setActiveCheckbox(false); setActiveCheckbox(false);
@ -410,7 +410,7 @@ export const Address = ({
)} )}
/> />
<div className="flex flex-col lg:flex-row items-center lg:gap-5 w-full mb-4"> <div className="flex flex-col lg:items-center lg:gap-5 w-full mb-4">
<Input <Input
width={isMobile ? "100%" : "50%"} width={isMobile ? "100%" : "50%"}
label={window.t("نام")} label={window.t("نام")}
@ -457,7 +457,7 @@ export const Address = ({
)} )}
/> />
<div className="flex flex-col lg:flex-row items-center lg:gap-5 w-full mb-4"> <div className="flex flex-col lg:items-center lg:gap-5 w-full mb-4">
<Input <Input
width={isMobile ? "100%" : "50%"} width={isMobile ? "100%" : "50%"}
label={window.t("شماره موبایل")} label={window.t("شماره موبایل")}
@ -526,7 +526,7 @@ export const Address = ({
)} )}
/> />
<div className="flex flex-col lg:flex-row items-center gap-3 lg:gap-5 w-full"> <div className="flex flex-col lg:items-center gap-3 lg:gap-5 w-full">
<Select <Select
selectProvince={"استان"} selectProvince={"استان"}
options={provinces.map((e) => ({ value: e.id, name: e.name }))} options={provinces.map((e) => ({ value: e.id, name: e.name }))}

@ -1,90 +1,29 @@
import React, { useState, useEffect } from "react"; import { useState, useEffect, useMemo, useCallback } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { publicApi } from "../../../redux/actions"; import { publicApi } from "../../../redux/actions";
import { useNavigate } from "react-router-dom"; import { useNavigate } from "react-router-dom";
import SignUp from "../SignUp"; import SignUp from "../SignUp";
import Button from "../../../components/Button";
//assets //assets
import logoIcon from "../SignUp/assets/logo.svg";
import bgImage from "./bg.svg"; import bgImage from "./bg.svg";
import arrowIcon from "../../../assets/icons/dropdown-blue.svg";
export const Desktop = ({ setHeaderOptions }) => { export const Desktop = ({ setHeaderOptions, level, setLevel}) => {
const [phase, setPhase] = useState("signup");
const navigate = useNavigate(); const navigate = useNavigate();
useEffect(() => { useEffect(() => {
setHeaderOptions({ show: false }); setHeaderOptions({ show: false });
}, []); }, []);
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">
{window.t("ورود یا ثبت نام")}
</strong>
<p className="text-tiny self-start text-gray-500 mt-6 leading-6">
{window.t(" کاربر گرامی لطفا یکی از دوگزینه زیر را انتخاب نمائید.")}
<br />
{window.t("درصورتی که عضو نیستید روی دکمه ثبت نام بزنید")}
</p>
<div className="mt-16 flex flex-col gap-4 w-full">
<Button
title={window.t("ورود یا ثبت نام")}
backgroundColor="bg-blueC0"
border={{ color: "#196EC055", width: "0px" }}
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 ( return (
<div className="h-screen w-full flex justify-center items-center"> <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-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-2/5 h-full flex justify-center items-center">
<div <div
className="w-4/5 flex justify-center items-center relative" className="w-4/5 flex justify-center items-center"
style={{ height: "90%" }} style={{ height: "90%" }}
> >
<button
className="absolute left-0 top-0 p-3 bg-grayF4 rounded-xl z-20" <SignUp setLevel={setLevel} level={level} />
onClick={() =>
setPhase(() =>
phase === "manage" ? navigate("/blogs") : "manage"
)
}
>
<img src={arrowIcon} className="transform rotate-90" alt="" />
</button>
{phases[phase]}
</div> </div>
</div> </div>
<div className="w-3/5 h-full bg-grayF9 flex justify-center items-center"> <div className="w-3/5 h-full bg-grayF9 flex justify-center items-center">

@ -422,7 +422,7 @@ function Profile({
</div> </div>
) : ( ) : (
<ul className="flex flex-col flex-1"> <ul className="flex flex-col flex-1">
<li className="flex flex-row gap-5"> <li className="flex gap-5">
<div className="flex flex-col w-4/12"> <div className="flex flex-col w-4/12">
<strong>{window.t(" اطلاعات هویتی")}</strong> <strong>{window.t(" اطلاعات هویتی")}</strong>
<p> <p>
@ -431,7 +431,7 @@ function Profile({
)} )}
</p> </p>
</div> </div>
<div className="flex flex-row w-8/12"></div> <div className="flex w-8/12"></div>
</li> </li>
</ul> </ul>
); );

@ -11,6 +11,7 @@ import { user, publicApi } from "../../../redux/actions";
import _ from "lodash"; import _ from "lodash";
//assets //assets
import logoIcon from "./assets/logo.svg"; import logoIcon from "./assets/logo.svg";
import arrowIcon from "../../../assets/icons/dropdown-blue.svg";
function SignUp({ function SignUp({
sendOtp, sendOtp,
@ -20,8 +21,10 @@ function SignUp({
headerOptions, headerOptions,
setHeaderOptions, setHeaderOptions,
loading, loading,
level,
setLevel,
isMobile,
}) { }) {
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);
@ -103,18 +106,21 @@ function SignUp({
} }
}; };
const numberInput = useRef();
useEffect(() => { useEffect(() => {
// numberInput.current.focus(); // numberInput.current.focus();
setHeaderOptions(headerOptions); setHeaderOptions(headerOptions);
}, []); }, []);
useEffect(() => { useEffect(() => {
if (signUpFields?.otp?.length === 4) { if (
signUpFields?.otp1 &&
signUpFields?.otp2 &&
signUpFields?.otp3 &&
signUpFields?.otp4
) {
sendOtp({ sendOtp({
cellphone: signUpFields?.cellphone, cellphone: signUpFields?.cellphone,
otp: signUpFields?.otp, otp: signUpFields?.otp1 + signUpFields?.otp2 + signUpFields?.otp3 + signUpFields?.otp4,
userToken: "2", userToken: "2",
applicationToken: "22", applicationToken: "22",
}); });
@ -135,33 +141,40 @@ function SignUp({
} }
}, [loginFlag]); }, [loginFlag]);
const light = theme === "light";
return ( return (
<div <div
className="w-screen overflow-x-hidden flex flex-row transform -translate-y-10 relative" className="w-screen overflow-x-hidden flex transform relative"
style={{ height: "calc(100vh - 160px)" }} style={{ height: "calc(100vh - 160px)" }}
> >
<button
className="absolute left-4 top-4 lg:top-8 p-3 bg-grayF4 rounded-xl z-20"
onClick={() =>
setLevel(level === "phonenumber" ? navigate("/") : "phonenumber")
}
>
<img src={arrowIcon} className="transform rotate-90" alt="" />
</button>
<div <div
className={`flex flex-col items-center justify-center h-full w-full p-4 transition transform duration-300 absolute top-0 left-0 ${ className={`flex flex-col items-center lg:pb-8 justify-between h-full w-full px-4 pt-16 lg:pt-16 transition transform duration-300 absolute top-0 left-0 ${
level === "phonenumber" ? "translate-x-0" : "-translate-x-full" level === "phonenumber" ? "translate-x-0" : "-translate-x-full"
}`} }`}
> >
<img src={logoIcon} alt="" className="" /> <div className="w-full flex flex-col items-center gap-6">
<div className="mt-7"> <img src={logoIcon} alt="" className="w-1/5 lg:w-1/6" />
<p className="text-sm align-start "> <p className="text-lg lg:text-base align-start">
{window.t("سلام به ")} {window.t("سلام به ")}
<span className="font-bold text-blueC0"> <span className="font-bold text-blueC0">
{window.t(" دانوین خوش ")} {window.t(" دانوین خوش ")}
</span> </span>
{window.t("آمدید")} {window.t("آمدید")}
</p> </p>
<p className="text-sm mt-4"> </div>
<div className="w-full flex flex-col">
<p className="text-base lg:text-sm mt-4">
{window.t( {window.t(
" لطفا جهت ورود یا ثبت نام شماره همراه خود را وارد نمایید." " لطفا جهت ورود یا ثبت نام شماره همراه خود را وارد نمایید."
)} )}
</p> </p>
</div>
<div className="w-full flex flex-col mt-4"> <div className="w-full flex flex-col mt-4">
<Input <Input
label={window.t("شماره موبایل")} label={window.t("شماره موبایل")}
@ -185,74 +198,92 @@ function SignUp({
/> />
</div> </div>
</div> </div>
</div>
<div <div
className={`flex flex-col items-center justify-center w-full h-full p-4 transition transform duration-300 absolute top-0 left-0 ${ className={`flex flex-col items-center justify-between w-full lg:pb-8 h-full px-4 pt-16 transition transform duration-300 absolute top-0 left-0 ${
level === "otp" ? "translate-x-0" : "translate-x-full" level === "otp" ? "translate-x-0" : "translate-x-full"
}`} }`}
> >
<img src={logoIcon} alt="" className="" /> <div className="flex flex-col w-full items-center">
<img src={logoIcon} alt="" className="w-1/5" />
{!resend && ( {!resend && (
<div className="w-full leading-6 dark:text-white mt-10 text-xs lg:text-sm text-gray1"> <div className="w-full leading-6 dark:text-white mt-10 text-sm lg:text-sm text-gray1">
{window.t("یک کد چهار رقمی تا")} &nbsp; {window.t("یک کد چهار رقمی تا")} &nbsp;
<Timer seconds={120} refresh={setResend} /> &nbsp; <Timer seconds={120} refresh={setResend} /> &nbsp;
{window.t("دیگر برای شماره")} {window.t("دیگر برای شماره")}
&nbsp;
<span className="text-greenBA text-sm lg:text-tiny"> <span className="text-greenBA text-sm lg:text-tiny">
{signUpFields?.cellphone} {signUpFields?.cellphone}
</span> </span>
&nbsp; {window.t("ارسال خواهد شد.")} &nbsp; {window.t("ارسال خواهد شد.")}
</div> </div>
)} )}
</div>
<div className="w-full flex flex-col mt-5"> <div className="w-full flex flex-col">
<div className="w-full flex flex-row-reverse justify-center"> <div className="w-full flex flex-row-reverse justify-between">
<input <input
inputMode="numeric" inputMode="numeric"
style={{ direction: "ltr" }} style={{
direction: "ltr",
width: isMobile ? "calc(100% / 4)" : "70px",
height: isMobile ? "calc((100vw - 32px) / 4.1)" : "70px",
}}
name="otp1" name="otp1"
className="bg-grayF9 dark:bg-opacity-10 outline-none rounded-md p-4 w-16 text-2xl font-bold lg:text-lg text-center text-blueC0 mx-1" className="bg-grayF9 dark:bg-opacity-10 outline-none rounded-md text-2xl font-bold lg:text-lg text-center text-blueC0 mx-1"
onChange={(e) => onChange={(e) =>
onChange( onChange(
e.target.name, e.target.name,
(e.target.value = onInput.numberOnly(e.target.value)) (e.target.value = onInput.numberOnly(e.target.value))
) )
} }
maxlength="1" maxLength="1"
ref={otp1} ref={otp1}
/> />
<input <input
inputMode="numeric" inputMode="numeric"
style={{ direction: "ltr" }} style={{
direction: "ltr",
width: isMobile ? "calc(100% / 4)" : "70px",
height: isMobile ? "calc((100vw - 32px) / 4.1)" : "70px",
}}
name="otp2" name="otp2"
className="bg-grayF9 dark:bg-opacity-10 outline-none rounded-md p-4 w-16 text-2xl font-bold lg:text-lg text-center text-blueC0 mx-1" className="bg-grayF9 dark:bg-opacity-10 outline-none rounded-md text-2xl font-bold lg:text-lg text-center text-blueC0 mx-1"
onChange={(e) => onChange={(e) =>
onChange( onChange(
e.target.name, e.target.name,
(e.target.value = onInput.numberOnly(e.target.value)) (e.target.value = onInput.numberOnly(e.target.value))
) )
} }
maxlength="1" maxLength="1"
ref={otp2} ref={otp2}
/> />
<input <input
inputMode="numeric" inputMode="numeric"
style={{ direction: "ltr" }} style={{
direction: "ltr",
width: isMobile ? "calc(100% / 4)" : "70px",
height: isMobile ? "calc((100vw - 32px) / 4.1)" : "70px",
}}
name="otp3" name="otp3"
className="bg-grayF9 dark:bg-opacity-10 outline-none rounded-md p-4 w-16 text-2xl font-bold lg:text-lg text-center text-blueC0 mx-1" className="bg-grayF9 dark:bg-opacity-10 outline-none rounded-md text-2xl font-bold lg:text-lg text-center text-blueC0 mx-1"
onChange={(e) => onChange={(e) =>
onChange( onChange(
e.target.name, e.target.name,
(e.target.value = onInput.numberOnly(e.target.value)) (e.target.value = onInput.numberOnly(e.target.value))
) )
} }
maxlength="1" maxLength="1"
ref={otp3} ref={otp3}
/> />
<input <input
inputMode="numeric" inputMode="numeric"
style={{ direction: "ltr" }} style={{
direction: "ltr",
width: isMobile ? "calc(100% / 4)" : "70px",
height: isMobile ? "calc((100vw - 32px) / 4.1)" : "70px",
}}
name="otp4" name="otp4"
className="bg-grayF9 dark:bg-opacity-10 outline-none rounded-md p-4 w-16 text-2xl font-bold lg:text-lg text-center text-blueC0 mx-1" className="bg-grayF9 dark:bg-opacity-10 outline-none rounded-md text-2xl font-bold lg:text-lg text-center text-blueC0 mx-1"
onChange={(e) => onChange={(e) =>
onChange( onChange(
e.target.name, e.target.name,
@ -261,7 +292,7 @@ function SignUp({
)) ))
) )
} }
maxlength="1" maxLength="1"
ref={otp4} ref={otp4}
/> />
</div> </div>
@ -277,8 +308,8 @@ function SignUp({
level === "phonenumber" ? checkPhoneNumber(e) : checkOtp(e) level === "phonenumber" ? checkPhoneNumber(e) : checkOtp(e)
} }
/> />
<div className="mt-10 flex flex-row text-center w-full justify-center"> <div className="mt-10 flex text-center w-full justify-center">
<div className="text-xs text-gray1 dark:text-gray-200 lg:text-sm"> <div className="text-sm text-gray1 dark:text-gray-200 lg:text-sm">
{window.t(" شماره خود را اشتباه وارد کردید؟")} {window.t(" شماره خود را اشتباه وارد کردید؟")}
<button <button
className="bg-transparent border-none text-greenBA font-medium" className="bg-transparent border-none text-greenBA font-medium"
@ -297,6 +328,7 @@ function SignUp({
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
loginFlag: state.user.status, loginFlag: state.user.status,
loading: state.user.loading, loading: state.user.loading,
isMobile: state.publicApi.isMobile,
}); });
const mapDispatchToProps = { const mapDispatchToProps = {

@ -6,20 +6,29 @@ import { connect } from "react-redux";
function Auth(props) { function Auth(props) {
const [page, setPage] = useState(props.page); const [page, setPage] = useState(props.page);
const [level, setLevel] = useState("phonenumber");
useEffect(() => { useEffect(() => {
setPage(() => props.page); setPage(() => props.page);
}, [props.page]); }, [props.page]);
return props.isMobile ? ( return props.isMobile ? (
<> <>
{page === "signup" && ( {page === "signup" && (
<SignUp theme={props.theme} headerOptions={props.headerOptions} /> <SignUp
theme={props.theme}
headerOptions={props.headerOptions}
level={level}
setLevel={setLevel}
/>
)} )}
{page === "profile" && <Profile theme={props.theme} />} {page === "profile" && <Profile theme={props.theme} />}
</> </>
) : <Desktop /> ) : (
<Desktop level={level} setLevel={setLevel} />
);
} }
export default connect((state) => ({ export default connect((state) => ({
theme: state.publicApi.theme, theme: state.publicApi.theme,
isMobile: state.publicApi.isMobile isMobile: state.publicApi.isMobile,
}))(Auth); }))(Auth);

@ -2,55 +2,41 @@ import React, { useEffect } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { blog, publicApi } from "../../redux/actions"; import { blog, publicApi } from "../../redux/actions";
import { Carousel } from "@trendyol-js/react-carousel"; import { Carousel } from "@trendyol-js/react-carousel";
import location from "../../utils/location"; import { useParams } from "react-router-dom";
import Hashtags from "../Blogs/layouts/Hashtags"; //components
import Header from "../Blogs/layouts/Header"; import Header from "../Blogs/layouts/Header";
import Suggest from "../Blogs/layouts/Suggest"; import Suggest from "../Blogs/layouts/Suggest";
import New from "../Blogs/layouts/New"; import New from "../Blogs/layouts/New";
import Avatar from "../../components/Avatar"; import Avatar from "../../components/Avatar";
import { useParams } from "react-router-dom";
//assets //assets
import arrow from "../../assets/icons/dropdown-blue.svg"; import arrow from "../../assets/icons/dropdown-blue.svg";
export const Blog = ({ export const Blog = ({
isMobile,
getInfo, getInfo,
blog, blog,
setHeaderOptions, setHeaderOptions,
headerOptions, headerOptions,
getList, getList,
blogs, blogs,
activeBlog,
}) => { }) => {
let { id } = useParams(); let { id } = useParams();
console.log(id);
// let id = location.getId();
useEffect(() => { useEffect(() => {
setHeaderOptions(headerOptions);
getInfo({ id: location.getId() });
if (blogs.length === 0) {
getList(); getList();
} setHeaderOptions(headerOptions);
}, [id]); }, []);
useEffect(() => {
getInfo({ id: location.getId() });
}, [activeBlog]);
useEffect(() => { useEffect(() => {
// alert(); window.scroll({ top: 0, behavior: "smooth" });
window.scrollTo(0, 0); getInfo({ id });
}, [id]); }, [id]);
return ( return blogs?.length ? (
<div className="flex flex-col lg:w-11/12 mx-auto lg:py-24 lg:px-0 px-4 lg:pb-0 pb-24 "> <div className="flex flex-col lg:w-11/12 mx-auto lg:py-24 lg:px-0 px-4 lg:pb-10 pb-24">
<Hashtags />
{isMobile && (
<div <div
className="w-full rounded-md overflow-hidden relative" className="flex lg:hidden w-full rounded-md overflow-hidden relative"
style={{ style={{
minHeight: 200, minHeight: 200,
}} }}
@ -84,8 +70,7 @@ export const Blog = ({
</div> </div>
</div> </div>
</div> </div>
)}
{!isMobile && (
<div <div
className="w-full hidden lg:flex" className="w-full hidden lg:flex"
style={{ style={{
@ -97,13 +82,13 @@ export const Blog = ({
backgroundPosition: "center bottom", backgroundPosition: "center bottom",
}} }}
></div> ></div>
)}
<div className="flex lg:flex-row my-5 gap-5"> <div className="flex lg:my-5 gap-5">
<strong className="flex-1 lg:text-5xl lg:font-black dark:text-gray-200"> <strong className="flex-1 lg:text-5xl lg:font-black dark:text-gray-200">
{blog?.title} {blog?.title}
</strong> </strong>
{!isMobile && ( {/* desktop */}
<div className="flex flex-col"> <div className="hidden lg:flex flex-col">
<div className="flex"> <div className="flex">
<Avatar size={60} /> <Avatar size={60} />
<div className="flex flex-col py-2 mr-2 justify-center"> <div className="flex flex-col py-2 mr-2 justify-center">
@ -124,28 +109,28 @@ export const Blog = ({
</span> </span>
</div> </div>
</div> </div>
)} {/* desktop */}
</div> </div>
<div <div
className="leading-8 lg:text-base text-sm dark:text-white" className="leading-8 lg:text-base text-sm dark:text-white"
dangerouslySetInnerHTML={{ __html: blog?.text }} dangerouslySetInnerHTML={{ __html: blog?.text }}
/> />
<Header title={window.t("پیشنهادی")} /> <Header title={window.t("پیشنهادی")} />
{/* mobile */}
{isMobile ? ( <div className="lg:hidden w-full flex overflow-x-scroll no-scrollbar gap-4">
<div className="w-full flex overflow-x-scroll no-scrollbar gap-4">
{blogs.map((blog, index) => ( {blogs.map((blog, index) => (
<New blog={blog} key={index} /> <New blog={blog} key={index} />
))} ))}
</div> </div>
) : ( {/* mobile */}
<div className="w-full relative" style={{ direction: "ltr" }}> {/* desktop */}
{blogs.length > 0 && ( <div className="hidden lg:flex w-full relative ltr">
<Carousel <Carousel
show={4} show={4}
slide={2} slide={2}
swiping={true} swiping={true}
useArrowKeys={true} useArrowKeys={true}
key={id}
transition={0.5} transition={0.5}
rightArrow={ rightArrow={
<img <img
@ -165,16 +150,18 @@ export const Blog = ({
} }
> >
{blogs {blogs
.filter((e) => e.id != blog.id) ?.slice(0, 10)
?.filter((blog) => Number(blog?.id) !== Number(id))
.map((blog, index) => ( .map((blog, index) => (
<Suggest blog={blog} key={index} /> <Suggest blog={blog} key={index} />
))} ))}
</Carousel> </Carousel>
)}
</div> </div>
)} {/* desktop */}
</div> </div>
); ) : <div className="w-full h-screen">
</div>;
}; };
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({

@ -4,6 +4,7 @@ import { blog, publicApi } from "../../redux/actions";
import { Carousel } from "@trendyol-js/react-carousel"; import { Carousel } from "@trendyol-js/react-carousel";
import Hashtags from "./layouts/Hashtags"; import Hashtags from "./layouts/Hashtags";
import Blog from "./layouts/Blog";
import Single from "./layouts/Single"; import Single from "./layouts/Single";
import Join from "./layouts/Join"; import Join from "./layouts/Join";
import New from "./layouts/New"; import New from "./layouts/New";
@ -14,37 +15,39 @@ import Target from "./layouts/Target";
//assets //assets
import arrow from "../../assets/icons/dropdown-blue.svg"; import arrow from "../../assets/icons/dropdown-blue.svg";
export const Blogs = ({ isMobile, getList, blogs, setHeaderOptions }) => { export const Blogs = ({
isMobile,
getList,
blogs,
setHeaderOptions,
headerOptions,
activeHashtag,
}) => {
useEffect(() => { useEffect(() => {
if (isMobile) { setHeaderOptions(headerOptions);
setHeaderOptions({
shown: true,
hamburgerMenu: true,
qr: true,
});
} else {
setHeaderOptions({ shown: true });
}
getList(); getList();
}, []); }, []);
useEffect(() => { useEffect(() => {
window.scrollTo(0, 0); window.scroll({ top: 0, behavior: "smooth" });
}, []); }, []);
return ( return (
<div className="flex w-full px-4 lg:px-0 flex-col lg:w-11/12 mx-auto lg:py-24 pb-24 lg:pb-0 "> <div className="flex w-full px-4 lg:px-0 flex-col lg:w-11/12 mx-auto lg:py-24 pb-24 lg:pb-16">
<Hashtags /> <Hashtags />
{activeHashtag === "همه" ? (
<>
<Single /> <Single />
<Header title={window.t(" تازهترینها از وبلاگ")} /> <Header title={window.t(" تازهترینها از وبلاگ")} />
{isMobile ? ( <div className=" w-full flex lg:hidden overflow-x-scroll no-scrollbar gap-4">
<div className="w-full flex overflow-x-scroll no-scrollbar gap-4">
{blogs.map((blog, index) => ( {blogs.map((blog, index) => (
<New blog={blog} key={index} /> <New blog={blog} key={index} />
))} ))}
</div> </div>
) : ( <div
<div className="w-full relative" style={{ direction: "ltr" }}> className="hidden lg:flex w-full relative"
style={{ direction: "ltr" }}
>
{blogs.length > 0 && ( {blogs.length > 0 && (
<Carousel <Carousel
show={3} show={3}
@ -75,16 +78,16 @@ export const Blogs = ({ isMobile, getList, blogs, setHeaderOptions }) => {
</Carousel> </Carousel>
)} )}
</div> </div>
)}
<Header title={window.t("پیشنهاد سردبیر")} /> <Header title={window.t("پیشنهاد سردبیر")} />
{isMobile ? ( <div className="w-full flex lg:hidden overflow-x-scroll no-scrollbar gap-4">
<div className="w-full flex overflow-x-scroll no-scrollbar gap-4">
{blogs.map((blog, index) => ( {blogs.map((blog, index) => (
<New blog={blog} key={index} /> <New blog={blog} key={index} />
))} ))}
</div> </div>
) : ( <div
<div className="w-full relative" style={{ direction: "ltr" }}> className="hidden lg:flex w-full relative"
style={{ direction: "ltr" }}
>
{blogs.length > 0 && ( {blogs.length > 0 && (
<Carousel <Carousel
show={4} show={4}
@ -115,9 +118,19 @@ export const Blogs = ({ isMobile, getList, blogs, setHeaderOptions }) => {
</Carousel> </Carousel>
)} )}
</div> </div>
)}
<Header title={window.t("از دنیای آموزش")} /> <Header title={window.t("از دنیای آموزش")} />
<Target blogs={blogs?.slice(0, 4)} /> <Target blogs={blogs?.slice(0, 4)} />
</>
) : (
<div className="flex flex-wrap items-center">
{blogs
?.filter((blog) => blog?.tag === activeHashtag)
?.map((blog, index) => (
<Blog blog={blog} key={index} />
))}
</div>
)}
<Join /> <Join />
</div> </div>
); );
@ -126,6 +139,7 @@ export const Blogs = ({ isMobile, getList, blogs, setHeaderOptions }) => {
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
isMobile: state.publicApi.isMobile, isMobile: state.publicApi.isMobile,
blogs: state.blog.list, blogs: state.blog.list,
activeHashtag: state.blog.activeHashtag,
}); });
const mapDispatchToProps = { const mapDispatchToProps = {

@ -0,0 +1,45 @@
import React from "react";
import { connect } from "react-redux";
import { useNavigate } from "react-router-dom";
const height = {
mobile: "calc((100vw - 32px) / 16 * 9)",
tablet: "calc((100vw - 32px) / 16 * 9)",
desktop: "calc((100vw / 12 * 11) / 4 / 16 * 9)",
};
export const Blog = ({ blog, device }) => {
const navigation = useNavigate();
return (
<article className="flex w-full lg:w-1/4 p-2">
<div
className="cursor-pointer flex flex-col gap-4 w-full"
onClick={() =>
navigation(`/blogs/${blog?.id}`, { state: { id: blog?.id } })
}
>
<div
className="w-full rounded-md"
style={{
backgroundImage: `url(https://dnvn.ir/api/v1/file/${blog?.fileIds})`,
backgroundRepeat: "no-repeat",
backgroundPosition: "center",
backgroundSize: "cover",
minHeight: height[device],
}}
></div>
<strong className="text-sm lg:text-tiny xl:text-base text-backgroundText h-20">
{blog?.title}
</strong>
</div>
</article>
);
};
const mapStateToProps = (state) => ({
device: state.config.device,
});
const mapDispatchToProps = {};
export default connect(mapStateToProps, mapDispatchToProps)(Blog);

@ -1,17 +1,25 @@
import React from "react"; import React from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { blog } from "../../../redux/actions";
//assets //assets
import arrowIcon from "../arrow.svg"; import arrowIcon from "../arrow.svg";
export const Hashtags = ({ hashtags }) => { export const Hashtags = ({ hashtags, setActive, activeHashtag }) => {
return ( return (
<div className="flex py-3 px-2 rounded-full border-2 border-green-50 dark:border-opacity-20 shadow-sm border-solid items-center w-full mb-7 overflow-x-scroll no-scrollbar"> <div className="flex py-1 lg:py-3 px-2 rounded-full border-2 border-green-50 dark:border-opacity-20 shadow-sm border-solid items-center w-full mb-7 overflow-x-scroll no-scrollbar">
<img src={arrowIcon} alt="" className="w-7" /> <img src={arrowIcon} alt="" className="w-7" />
<ul className="list-none flex justify-around items-center lg:flex-1 lg:ml-0 ml-4"> <ul className="list-none flex items-center lg:flex-1 lg:ml-0 ml-4">
{hashtags.map((hashtag, index) => ( {hashtags.map((hashtag, index) => (
<li className="text-tiny font-semibold cursor-pointer mx-4 lg:px-0 flex-1"> <li
{hashtag} className={`text-tiny w-16 lg:w-28 font-medium cursor-pointer rounded-md text-center py-2 transition-all mx-4 flex-1 ${
activeHashtag === hashtag
? "bg-green-400 text-white"
: "text-green79"
}`}
onClick={() => setActive(hashtag)}
>
{"#" + hashtag}
</li> </li>
))} ))}
</ul> </ul>
@ -21,8 +29,11 @@ export const Hashtags = ({ hashtags }) => {
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
hashtags: state.blog.hashtags, hashtags: state.blog.hashtags,
activeHashtag: state.blog.activeHashtag,
}); });
const mapDispatchToProps = {}; const mapDispatchToProps = {
setActive: blog.setActiveHashtag,
};
export default connect(mapStateToProps, mapDispatchToProps)(Hashtags); export default connect(mapStateToProps, mapDispatchToProps)(Hashtags);

@ -97,7 +97,7 @@ export const Join = ({ isMobile, join, userId }) => {
}; };
const mapStateToProps = (state) => ({ const mapStateToProps = (state) => ({
isMobile: state.publicApi.isMobile, isMobile: state.config.device === 'mobile',
userId: state.user.status?.id, userId: state.user.status?.id,
}); });

@ -36,7 +36,7 @@ export const New = ({ blog, isMobile, setActive }) => {
<Avatar size={60} /> <Avatar size={60} />
<div className="flex flex-col py-2 mr-2 justify-center"> <div className="flex flex-col py-2 mr-2 justify-center">
<strong className="lg:text-tiny lg:font-black text-gray1"> <strong className="lg:text-tiny lg:font-black text-gray1">
{"نوشته از:" + " " + "کامران ایزدی"} {`{window.t("نوشته از:")}` + " " + `{window.t("کامران ایزدی")}`}
</strong> </strong>
<p className="lg:text-sm lg:font-semibold text-gray70 mt-2"> <p className="lg:text-sm lg:font-semibold text-gray70 mt-2">
{window.t("سردبیر بخش وبلاگ دانوین")} {window.t("سردبیر بخش وبلاگ دانوین")}
@ -45,7 +45,7 @@ export const New = ({ blog, isMobile, setActive }) => {
</div> </div>
<div className="flex flex-col i justify-center items-end"> <div className="flex flex-col i justify-center items-end">
<span className="lg:text-sm text-gray1 lg:font-black"> <span className="lg:text-sm text-gray1 lg:font-black">
{"زمان مطالعه" + " " + "۳۰ دقیقه"} {`{window.t("زمان مطالعه")}` + " " + `{window.t("۳۰ دقیقه")}`}
</span> </span>
<span className="mt-2 lg:text-sm text-gray1 lg:font-black"> <span className="mt-2 lg:text-sm text-gray1 lg:font-black">
{window.t("1400/11/24")} {window.t("1400/11/24")}

@ -20,7 +20,7 @@ export const Suggest = ({ blog }) => {
className="w-full rounded-md" className="w-full rounded-md"
style={{ height: "calc(100vw / 12 * 11 / 3 / 21 * 9)" }} style={{ height: "calc(100vw / 12 * 11 / 3 / 21 * 9)" }}
/> />
<strong className="text-lg my-4 leading-7">{blog?.title}</strong> <strong className="text-tiny my-4 leading-7">{blog?.title}</strong>
</Link> </Link>
); );
}; };

@ -78,12 +78,12 @@ export const Target = ({ blogs, isMobile }) => {
const Small = ({ blogs }) => { const Small = ({ blogs }) => {
return ( return (
<div className="w-full lg:w-1/2 flex flex-row flex-wrap lg:flex-col justify-between"> <div className="w-full lg:w-1/2 flex flex-wrap lg:flex-col justify-between">
{blogs.map((blog, index) => ( {blogs.map((blog, index) => (
<Link <Link
to={"/blogs/" + blog.id} to={"/blogs/" + blog.id}
key={index} key={index}
className="lg:mb-0 mb-3 lg:flex-row lg:flex lg:gap-2" className="lg:mb-0 mb-3 flex flex-col lg:flex-row lg:gap-2"
style={{ width: isMobile ? "48%" : "100%" }} style={{ width: isMobile ? "48%" : "100%" }}
> >
<img <img
@ -115,7 +115,7 @@ export const Target = ({ blogs, isMobile }) => {
); );
}; };
return ( return (
<div className="flex flex-col lg:flex-row gap-10"> <div className="flex flex-col lg:flex-row lg:gap-10">
<Large blog={blogs[0]} /> <Large blog={blogs[0]} />
<Small blogs={blogs?.slice(0, 3)} /> <Small blogs={blogs?.slice(0, 3)} />
</div> </div>

@ -32,7 +32,7 @@ function Contact({ headerOptions, setHeaderOptions, info, isMobile, isDark }) {
> >
<Header <Header
bg={isMobile ? contactBgImage : desktopContactBgImage} bg={isMobile ? contactBgImage : desktopContactBgImage}
title="تماس با ما" title={window.t("تماس با ما")}
/> />
{isMobile ? ( {isMobile ? (
<div className="w-full flex flex-col px-4 transform -translate-y-16"> <div className="w-full flex flex-col px-4 transform -translate-y-16">
@ -41,14 +41,14 @@ function Contact({ headerOptions, setHeaderOptions, info, isMobile, isDark }) {
))} ))}
<NotFound <NotFound
title={""} title={""}
subTitle={ subTitle={window.t(
"شاید سوالی که بدنبال آن هستید را در قسمت پرسشهای متداول بتوانید پیدا کنید" "شاید سوالی که بدنبال آن هستید را در قسمت پرسشهای متداول بتوانید پیدا کنید"
} )}
link="/faq" link="/faq"
/> />
</div> </div>
) : ( ) : (
<div className="flex flex-row gap-10 transform -translate-y-12 w-11/12 mx-auto"> <div className="flex gap-10 transform -translate-y-12 w-11/12 mx-auto">
<div className="w-1/3"> <div className="w-1/3">
<Ticket /> <Ticket />
</div> </div>
@ -59,9 +59,9 @@ function Contact({ headerOptions, setHeaderOptions, info, isMobile, isDark }) {
<Divider type="vertical" /> <Divider type="vertical" />
<NotFound <NotFound
title={""} title={""}
subTitle={ subTitle={window.t(
"شاید سوالی که بدنبال آن هستید را در قسمت پرسشهای متداول بتوانید پیدا کنید" "پششاید سوالی که بدنبال آن هستید را در قسمت پرسشهای متداول بتوانید پیدا کنید"
} )}
link="/faq" link="/faq"
/> />
</div> </div>
@ -91,13 +91,15 @@ Contact.defaultProps = {
info: { info: {
onlineSupport: { onlineSupport: {
icon: onlineSupportIcon, icon: onlineSupportIcon,
title: { text: "پشتیبانی آنلاین", color: "#D3B702" }, title: { text: window.t("پشتیبانی آنلاین"), color: "#D3B702" },
description: { description: {
text: "همکاران ما در قسمت فروش و پشتیبانی، پاسخگوی شما هستند هر سوالی در مورد کتابهای ما داشتید بپرسید", text: window.t(
"همکاران ما در قسمت فروش و پشتیبانی، پاسخگوی شما هستند هر سوالی در مورد کتابهای ما داشتید بپرسید"
),
color: "#766600", color: "#766600",
}, },
link: { link: {
title: "ارتباط با بخش پشتیبانی", title: window.t("ارتباط با بخش پشتیبانی"),
link: "/support", link: "/support",
color: "#766600", color: "#766600",
}, },
@ -106,9 +108,11 @@ Contact.defaultProps = {
}, },
call: { call: {
icon: callIcon, icon: callIcon,
title: { text: "شماره تماس", color: "#06A02A" }, title: { text: window.t("شماره تماس"), color: "#06A02A" },
description: { description: {
text: "در صورت هرگونه سوال شما میتوانید در ساعات اداری 9 الی 17 با شماره 021۸۸۸۱۴۶۳۷ تماس حاصل فرمایید", text: window.t(
"در صورت هرگونه سوال شما میتوانید در ساعات اداری 9 الی 17 با شماره ۰۲۱۸۸۸۱۴۶۳۷ تماس حاصل فرمایید"
),
color: "#025816", color: "#025816",
}, },
link: null, link: null,
@ -117,13 +121,15 @@ Contact.defaultProps = {
}, },
address: { address: {
icon: addressIcon, icon: addressIcon,
title: { text: "نشانی", color: "#0EAD98" }, title: { text: window.t("نشانی"), color: "#0EAD98" },
description: { description: {
text: "نشانی دفتر مرکزی: تهران میدان فردوسی خیابان عباس موسوی پلاک 30", text: window.t(
"نشانی دفتر مرکزی: تهران میدان فردوسی خیابان عباس موسوی پلاک 30"
),
color: "#066A5C", color: "#066A5C",
}, },
link: { link: {
title: "لیست نمایندگیهای فروش", title: window.t("لیست نمایندگیهای فروش"),
link: "/sell", link: "/sell",
color: "#0A7769", color: "#0A7769",
}, },

@ -5,7 +5,7 @@ import { connect } from "react-redux";
function Info({ info, isDark }) { function Info({ info, isDark }) {
return ( return (
<div <div
className="flex flex-row py-4 px-3 rounded-md mt-4" className="flex py-4 px-3 rounded-md mt-4"
style={{ style={{
backgroundColor: info.bg, backgroundColor: info.bg,
border: `1px solid ${info.borderColor}`, border: `1px solid ${info.borderColor}`,

@ -29,7 +29,12 @@ export const Ticket = ({
setDialog, setDialog,
}) => { }) => {
let opt = useMemo( let opt = useMemo(
() => ["واحد مورد نظر", "واحد فروش", "واحد فنی", "واحد محتوایی"], () => [
window.t("واحد مورد نظر"),
window.t("واحد فروش"),
window.t("واحد فنی"),
window.t("واحد محتوایی"),
],
[status] [status]
); );
@ -50,17 +55,14 @@ export const Ticket = ({
const send = useCallback(async () => { const send = useCallback(async () => {
if (!ticket?.subject) { if (!ticket?.subject) {
setDialog({ setDialog({
text: "موضوع پیام خود را وارد کنید.", text: window.t("موضوع پیام خود را وارد کنید."),
type: "alert", type: "alert",
accept: () => {}, accept: () => {},
open: true, open: true,
}); });
// console.log("mahdi");
console.log(ticket?.subject);
// console.log("mahdi");
} else if (!ticket?.unit) { } else if (!ticket?.unit) {
setDialog({ setDialog({
text: "واحد مورد نظر خود را وارد نکرده اید.", text: window.t("واحد مورد نظر خود را وارد نکرده اید."),
type: "alert", type: "alert",
accept: () => {}, accept: () => {},
open: true, open: true,
@ -78,7 +80,7 @@ export const Ticket = ({
}; };
await submit(data); await submit(data);
} }
}, [status]); }, [status, ticket]);
useEffect(() => { useEffect(() => {
window.scrollTo(0, 0); window.scrollTo(0, 0);
@ -115,7 +117,7 @@ export const Ticket = ({
backgroundColor={isDark ? "dark:bg-transparent dark:text-white" : ""} backgroundColor={isDark ? "dark:bg-transparent dark:text-white" : ""}
fill={isDark ? "fill-white" : "fill-gray-600"} fill={isDark ? "fill-white" : "fill-gray-600"}
/> />
{ticket?.unit === "واحد محتوایی" && ( {ticket?.unit === window.t("1400/11/24") && (
<> <>
<div className="mt-2"></div> <div className="mt-2"></div>
<Select <Select
@ -124,7 +126,7 @@ export const Ticket = ({
...new Set( ...new Set(
myProductList?.map((item) => [ myProductList?.map((item) => [
item?.product?.book?.id, item?.product?.book?.id,
`${item?.product?.book.name} پایه ${ `${item?.product?.book.name} {window.t("پایه")} ${
Object.values(grades)[item.product.book.gradeId] Object.values(grades)[item.product.book.gradeId]
}`, }`,
]) || [] ]) || []
@ -145,10 +147,10 @@ export const Ticket = ({
onChange={(name, value) => setTicket({ name, value })} onChange={(name, value) => setTicket({ name, value })}
value={ticket?.subject || ""} value={ticket?.subject || ""}
regex={(val) => val} regex={(val) => val}
label="موضوع" label={window.t("موضوع")}
/> />
<Textarea <Textarea
placeholder="پیام خود را اینجا بنویسید" placeholder={window.t("پیام خود را اینجا بنویسید")}
name="text" name="text"
onChange={(name, value) => setTicket({ name, value })} onChange={(name, value) => setTicket({ name, value })}
value={ticket?.text || ""} value={ticket?.text || ""}
@ -161,7 +163,7 @@ export const Ticket = ({
/> />
<br /> <br />
<Button <Button
title="ارسال پیام" title={window.t("ارسال پیام")}
backgroundColor={isDark ? "bg-blueC0" : "bg-blueC0"} backgroundColor={isDark ? "bg-blueC0" : "bg-blueC0"}
border={{ color: isDark ? "#ffffff55" : "#196EC055", width: "0px" }} border={{ color: isDark ? "#ffffff55" : "#196EC055", width: "0px" }}
width="100%" width="100%"

@ -21,10 +21,10 @@ function Document({ onChange, name, value, isMobile }) {
margin: "auto", margin: "auto",
}} }}
> >
{value?.name || "تصویر بارگزاری شد"} {value?.name || window.t("تصویر بارگزاری شد")}
</span> </span>
) : ( ) : (
<span>در صورت نیاز تصویر مرتبط را انتخاب کنید.</span> <span>{window.t("در صورت نیاز تصویر مرتبط را انتخاب کنید.")} </span>
)} )}
</div> </div>
) : ( ) : (
@ -42,7 +42,7 @@ function Document({ onChange, name, value, isMobile }) {
margin: "auto", margin: "auto",
}} }}
> >
{value?.name || "فایل ثبت شد"} {value?.name || window.t("فایل ثبت شد")}
</span> </span>
) : ( ) : (
<span <span
@ -52,7 +52,7 @@ function Document({ onChange, name, value, isMobile }) {
margin: "auto", margin: "auto",
}} }}
> >
در صورت نیاز تصویر مرتبط را انتخاب کنید. {window.t("در صورت نیاز تصویر مرتبط را انتخاب کنید.")}
</span> </span>
)} )}
</div> </div>

@ -30,7 +30,7 @@ export const Dashboard = ({ isMobile, headerOptions, setHeaderOptions }) => {
</div> </div>
) : ( ) : (
<div className="w-full"> <div className="w-full">
<div className="gap-5 w-full h-screen pt-20 mx-auto flex flex-row bg-transparent justify-end"> <div className="gap-5 w-full h-screen pt-20 mx-auto flex bg-transparent justify-end">
<Sidebar page={page} setPage={setPage} /> <Sidebar page={page} setPage={setPage} />
<Main page={page} /> <Main page={page} />
</div> </div>

@ -51,7 +51,7 @@ const ProfileAddress = ({
isMobile ? "p-0" : "px-10" isMobile ? "p-0" : "px-10"
} mx-auto`} } mx-auto`}
> >
<div className="w-full flex flex-row justify-between items-center mt-4"> <div className="w-full flex justify-between items-center mt-4">
<button <button
className={`flex justify-center text-tiny lg:text-sm rounded-md py-3 bg-grayF9 dark:bg-blueC0 dark:bg-opacity-30 cursor:pointer ${ className={`flex justify-center text-tiny lg:text-sm rounded-md py-3 bg-grayF9 dark:bg-blueC0 dark:bg-opacity-30 cursor:pointer ${
isDark ? "text-white" : "text-gray70" isDark ? "text-white" : "text-gray70"
@ -63,7 +63,8 @@ const ProfileAddress = ({
border: `1px solid ${isDark ? "#DBDBDB22" : "#DBDBDB"}`, border: `1px solid ${isDark ? "#DBDBDB22" : "#DBDBDB"}`,
}} }}
> >
&nbsp;یک آدرس جدید اضافه کنید &nbsp;
{window.t("یک آدرس جدید اضافه کنید")}
<strong className="text-lg transform translate-y-0.5 mr-1">+</strong> <strong className="text-lg transform translate-y-0.5 mr-1">+</strong>
</button> </button>
</div> </div>
@ -116,7 +117,7 @@ const Location = ({
const delAddress = (id) => { const delAddress = (id) => {
setMenu(); setMenu();
setDialog({ setDialog({
text: "آدرس رو حذف کنیم؟", text: window.t("آدرس رو حذف کنیم؟"),
type: "confirm", type: "confirm",
accept: () => deleteAddress({ id }), accept: () => deleteAddress({ id }),
open: true, open: true,
@ -155,24 +156,30 @@ const Location = ({
{active && ( {active && (
<div className="w-full flex justify-between mb-3"> <div className="w-full flex justify-between mb-3">
<div className="flex items-center"> <div className="flex items-center">
<strong className="text-base">آدرس انتخابی شما</strong> <strong className="text-base">
<span className="mr-4 text-sm">فعال</span> {window.t("آدرس انتخابی شما")}
</strong>
<span className="mr-4 text-sm"> {window.t("فعال")}</span>
</div> </div>
</div> </div>
)} )}
<div className={`flex w-full ${active ? "" : "flex-row"}`}> <div className={`flex w-full ${active ? "" : "flex-row"}`}>
<div className="flex flex-col flex-1 mb-4"> <div className="flex flex-col flex-1 mb-4">
<span className="mb-2 leading-6"> <span className="mb-2 leading-6">
{"آدرس:" + " " + address.address} {`{window.t("آدرس")}` + " " + address.address}
</span> </span>
<span className="mb-2 leading-6"> <span className="mb-2 leading-6">
{"نام:" + " " + address.firstName + " " + address.lastName} {`{window.t("نام:")}` +
" " +
address.firstName +
" " +
address.lastName}
</span> </span>
<span className="mb-2 leading-6"> <span className="mb-2 leading-6">
{"کد پستی:" + " " + address.postalCode} {`{window.t("کد پستی:")}` + " " + address.postalCode}
</span> </span>
<span className="mb-2 leading-6"> <span className="mb-2 leading-6">
{"شماره تماس:" + " " + address.cellphone} {`{window.t("شماره تماس:")}` + " " + address.cellphone}
</span> </span>
</div> </div>
</div> </div>
@ -182,24 +189,24 @@ const Location = ({
<Link <Link
style={{ border: "solid 1px #12CF7F" }} style={{ border: "solid 1px #12CF7F" }}
to={"/editAddress/" + address.id} to={"/editAddress/" + address.id}
className="w-full flex flex-row text-sm items-center justify-between px-2 py-1 rounded-sm cursor-pointer" className="w-full flex text-sm items-center justify-between px-2 py-1 rounded-sm cursor-pointer"
onClick={() => setMenu()} onClick={() => setMenu()}
> >
ویرایش {window.t("ویرایش")}
<img src={editButton} alt="edit-address" className="w-5 mr-3 " /> <img src={editButton} alt="edit-address" className="w-5 mr-3 " />
</Link> </Link>
<div <div
style={{ border: "solid 1px #fca5a5" }} style={{ border: "solid 1px #fca5a5" }}
class="w-full flex flex-row items-center justify-between px-2 py-1 rounded-sm cursor-pointer" class="w-full flex items-center justify-between px-2 py-1 rounded-sm cursor-pointer"
onClick={() => delAddress(address.id)} onClick={() => delAddress(address.id)}
> >
<button class="text-sm ">حذف</button> <button class="text-sm ">{window.t("حذف")}</button>
<img src={trash} alt="delete-address" className="w-5 mr-3" /> <img src={trash} alt="delete-address" className="w-5 mr-3" />
</div> </div>
</div> </div>
</div> </div>
<Button <Button
title="مشاهده روی نقشه" title={window.t("مشاهده روی نقشه")}
backgroundColor={isDark ? "bg-blueC0" : "bg-blueC0"} backgroundColor={isDark ? "bg-blueC0" : "bg-blueC0"}
border={{ color: isDark ? "#ffffff55" : "#196EC055", width: "0px" }} border={{ color: isDark ? "#ffffff55" : "#196EC055", width: "0px" }}
width="100%" width="100%"

@ -50,7 +50,7 @@ export const MyBooks = ({ books, grades, isMobile }) => {
))} */} ))} */}
<div className="w-full scrolling-carousel mt-4 pb-2"> <div className="w-full scrolling-carousel mt-4 pb-2">
<p className="text-green7B font-bold text-2xl lg:text-base"> <p className="text-green7B font-bold text-2xl lg:text-base">
کتاب های من {window.t("کتاب های من")}
</p> </p>
<ScrollingCarousel className="py-3"> <ScrollingCarousel className="py-3">
{books?.map((book, index) => ( {books?.map((book, index) => (

@ -15,32 +15,32 @@ const List = ({ mobile }) => {
const pages = [ const pages = [
{ {
icon: <img src={userGreenIcon} alt="" />, icon: <img src={userGreenIcon} alt="" />,
name: "اطلاعات حساب کاربری", name: window.t("اطلاعات حساب کاربری"),
link: "/editProfile", link: "/editProfile",
}, },
{ {
icon: <img src={cartGreenIcon} />, icon: <img src={cartGreenIcon} />,
name: "سفارشات", name: window.t("سفارشات"),
link: "/Orders", link: "/Orders",
}, },
{ {
icon: <img src={bookGreenIcon} />, icon: <img src={bookGreenIcon} />,
name: "کتابهای من", name: window.t("کتابهای من"),
link: "/AR", link: "/AR",
}, },
{ {
icon: <img src={videoGreenIcon} />, icon: <img src={videoGreenIcon} />,
name: "دورههای من", name: window.t("دورههای من"),
link: "#", link: "#",
}, },
{ {
icon: <img src={bookmarkGreenIcon} />, icon: <img src={bookmarkGreenIcon} />,
name: "لیست علاقهمندیها", name: window.t("لیست علاقهمندیها"),
link: "/favorites", link: "/favorites",
}, },
{ {
icon: <img src={addressGreenIcon} />, icon: <img src={addressGreenIcon} />,
name: "آدرسها", name: window.t("آدرسها"),
link: "/addresses", link: "/addresses",
}, },
]; ];
@ -51,7 +51,7 @@ const List = ({ mobile }) => {
<Link <Link
key={index} key={index}
to={page.link} to={page.link}
className={`w-full flex items-center justify-between mb-6 pb-4 flex-row shadow-sm`} className={`w-full flex items-center justify-between mb-6 pb-4 shadow-sm`}
> >
<div className={`flex items-center flex-row`}> <div className={`flex items-center flex-row`}>
{page.icon} {page.icon}

@ -63,7 +63,7 @@ const ProfileAddress = ({
</div> </div>
</div> </div>
) : ( ) : (
<Empty text="هیچ آدرسی ثبت نشده :(" /> <Empty title={window.t("هیچ آدرسی ثبت نشده")} />
)} )}
<FloatingButton <FloatingButton
action={() => navigation("/createAddress", { state: { panel: true } })} action={() => navigation("/createAddress", { state: { panel: true } })}
@ -102,7 +102,7 @@ const Location = ({
const delAddress = (id) => { const delAddress = (id) => {
setMenu(); setMenu();
setDialog({ setDialog({
text: "آدرس رو حذف کنیم؟", text: window.t("آدرس رو حذف کنیم؟"),
type: "confirm", type: "confirm",
accept: () => deleteAddress({ id }), accept: () => deleteAddress({ id }),
open: true, open: true,
@ -140,7 +140,7 @@ const Location = ({
className="py-3 pr-2 pl-10 text-sm font-bold bg-blue-300" className="py-3 pr-2 pl-10 text-sm font-bold bg-blue-300"
onClick={() => setMenu()} onClick={() => setMenu()}
> >
ویرایش {window.t("ویرایش")}
</Link> </Link>
<button <button
className="py-3 pr-2 pl-10 border-none m-0 text-sm text-red19 font-bold" className="py-3 pr-2 pl-10 border-none m-0 text-sm text-red19 font-bold"
@ -151,12 +151,14 @@ const Location = ({
</div> </div>
<div className={"flex flex-col flex-1 mr-2"}> <div className={"flex flex-col flex-1 mr-2"}>
{active && ( {active && (
<div className={"w-full flex flex-row justify-between mb-3"}> <div className={"w-full flex justify-between mb-3"}>
<div className={"flex flex-row items-center"}> <div className={"flex items-center"}>
<strong className={"text-base font-bold text-gray1"}> <strong className={"text-base font-bold text-gray1"}>
آدرس انتخابی شما {window.t("آدرس انتخابی شما")}
</strong> </strong>
<span className={"text-xs text-gray1 mr-2.5"}>فعال</span> <span className={"text-xs text-gray1 mr-2.5"}>
{window.t("فعال")}
</span>
</div> </div>
<svg <svg
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
@ -177,16 +179,20 @@ const Location = ({
<div className={`flex w-full ${active ? "" : "flex-row"}`}> <div className={`flex w-full ${active ? "" : "flex-row"}`}>
<div className={"flex flex-col flex-1 mb-4"}> <div className={"flex flex-col flex-1 mb-4"}>
<span className={"text-sm leading-6"}> <span className={"text-sm leading-6"}>
{"آدرس:" + " " + address.address} {`{window.t("آدرس:")}` + " " + address.address}
</span> </span>
<span className={"text-sm leading-6 mt-1.5"}> <span className={"text-sm leading-6 mt-1.5"}>
{"نام:" + " " + address.firstName + " " + address.lastName} {`{window.t("نام:")}` +
" " +
address.firstName +
" " +
address.lastName}
</span> </span>
<span className={"text-sm leading-6 mt-1.5"}> <span className={"text-sm leading-6 mt-1.5"}>
{"کد پستی:" + " " + address.postalCode} {`{window.t("کد پستی:")}` + " " + address.postalCode}
</span> </span>
<span className={"text-sm leading-6 mt-1.5"}> <span className={"text-sm leading-6 mt-1.5"}>
{"شماره تماس:" + " " + address.cellphone} {`{window.t("شماره تماس:")}` + " " + address.cellphone}
</span> </span>
</div> </div>
{!active && ( {!active && (
@ -207,7 +213,7 @@ const Location = ({
)} )}
</div> </div>
<Button <Button
title="مشاهده روی نقشه" title={window.t("مشاهده روی نقشه")}
backgroundColor={isDark ? "bg-transparent" : "bg-blueC0"} backgroundColor={isDark ? "bg-transparent" : "bg-blueC0"}
border={{ border={{
color: isDark ? "#ffffff55" : "#196EC055", color: isDark ? "#ffffff55" : "#196EC055",

@ -46,12 +46,12 @@ const ProfileBookmark = ({ bookmarkList, getList }) => {
backgroundColor: "white", backgroundColor: "white",
}} }}
> >
x x headerOptions=
headerOptions={{ {{
logo: false, logo: false,
menu: false, menu: false,
hamburgerMenu: false, hamburgerMenu: false,
title: "لیست علاقهمندیها", title: window.t("لیست علاقهمندیها"),
bookmark: false, bookmark: false,
qr: false, qr: false,
back: true, back: true,
@ -71,7 +71,7 @@ const ProfileBookmark = ({ bookmarkList, getList }) => {
</View> </View>
</ScrollView> </ScrollView>
) : ( ) : (
<Empty text="لیست علاقهمندیها خالی است." /> <Empty text={window.t("لیست علاقهمندیها خالی است.")} />
)} )}
</SafeAreaView> </SafeAreaView>
); );

@ -6,9 +6,9 @@ const Trophy = ({}) => {
const [dropdown, setDropdown] = React.useState(true); const [dropdown, setDropdown] = React.useState(true);
return ( return (
<div <div
className={`w-full flex py-5 px-3 justify-between items-center flex-row bg-yellow4 bg-opacity-40`} className={`w-full flex py-5 px-3 justify-between items-center bg-yellow4 bg-opacity-40`}
> >
<div className={`flex flex-row items-center`}> <div className={`flex items-center`}>
<svg xmlns="http://www.w3.org/2000/svg" width={23.862} height={23.862}> <svg xmlns="http://www.w3.org/2000/svg" width={23.862} height={23.862}>
<g fill="none" stroke="#d6d020" data-name="vuesax/linear/cup"> <g fill="none" stroke="#d6d020" data-name="vuesax/linear/cup">
<path <path
@ -39,11 +39,11 @@ const Trophy = ({}) => {
</g> </g>
</svg> </svg>
<strong className="text-sm mr-2.5 text-green4F"> <strong className="text-sm mr-2.5 text-green4F">
{"امتیاز شما" + " " + 14560} {`{window.t("امتیاز شما")}` + " " + 14560}
</strong> </strong>
</div> </div>
<Link to="#" className="text-sm text-green4F"> <Link to="#" className="text-sm text-green4F">
مشاهده جوایز {window.t("مشاهده جوایز")}
</Link> </Link>
</div> </div>
); );

@ -7,7 +7,7 @@ const User = ({ user, mobile }) => {
return ( return (
<div className={`w-full`}> <div className={`w-full`}>
<button <button
className={`w-full mt-2 mb-2 flex flex-row justify-between items-center border-none`} className={`w-full mt-2 mb-2 flex justify-between items-center border-none`}
onClick={() => setDropdown(!dropdown)} onClick={() => setDropdown(!dropdown)}
> >
<div className={`flex items-center flex-row`}> <div className={`flex items-center flex-row`}>
@ -49,10 +49,10 @@ const User = ({ user, mobile }) => {
}`} }`}
> >
<div <div
className={`flex items-center w-full pb-3 mb-3 flex-row border-b border-solid border-gray-100`} className={`flex items-center w-full pb-3 mb-3 border-b border-solid border-gray-100`}
> >
<strong className="text-sm text-gray1"> <strong className="text-sm text-gray1">
افزودن حساب کاربری جدید {window.t("افزودن حساب کاربری جدید")}
</strong> </strong>
<span className="mr-1 mt-1 text-xl text-gray1">+</span> <span className="mr-1 mt-1 text-xl text-gray1">+</span>
</div> </div>

@ -40,7 +40,7 @@ const SidebarMenu = ({
return ( return (
<div className="flex flex-col"> <div className="flex flex-col">
<div <div
className="flex flex-row justify-between items-center py-2 my-2 cursor-pointer group hover:bg-blueC0 hover:bg-opacity-10 rounded-md px-1" className="flex justify-between items-center py-2 my-2 cursor-pointer group hover:bg-blueC0 hover:bg-opacity-10 rounded-md px-1"
onClick={() => onClick={() =>
setToggleList({ ...toggleList, [name]: !toggleList[name] }) setToggleList({ ...toggleList, [name]: !toggleList[name] })
} }
@ -69,7 +69,7 @@ const SidebarMenu = ({
{list.map((item, index) => ( {list.map((item, index) => (
<li <li
key={index} key={index}
className={`flex flex-row items-center cursor-pointer rounded-md hover:bg-gray-100`} className={`flex items-center cursor-pointer rounded-md hover:bg-gray-100`}
onClick={() => (page !== item.value ? setPage(item.value) : {})} onClick={() => (page !== item.value ? setPage(item.value) : {})}
> >
<span <span
@ -91,42 +91,42 @@ const SidebarMenu = ({
const buttons = [ const buttons = [
{ {
icon: myBooksIcon, icon: myBooksIcon,
title: "کتاب های من", title: window.t("کتاب های من"),
onClick: () => setPage("mybooks"), onClick: () => setPage("mybooks"),
name: "mybooks", name: "mybooks",
}, },
{ {
icon: myVideosIcon, icon: myVideosIcon,
title: "ویدئوهای من", title: window.t("ویدئوهای من"),
onClick: () => setPage("myvideos"), onClick: () => setPage("myvideos"),
name: "myvideos", name: "myvideos",
}, },
{ {
icon: ordersIcon, icon: ordersIcon,
title: "سفارشات", title: window.t("سفارشات"),
onClick: () => setPage("orders"), onClick: () => setPage("orders"),
name: "orders", name: "orders",
}, },
{ {
icon: favoritesIcon, icon: favoritesIcon,
title: "علاقمندی ها", title: window.t("علاقمندی ها"),
onClick: () => setPage("favorites"), onClick: () => setPage("favorites"),
name: "favorites", name: "favorites",
}, },
{ {
icon: addressIcon, icon: addressIcon,
title: "آدرس ها", title: window.t("آدرس ها"),
onClick: () => setPage("addresses"), onClick: () => setPage("addresses"),
name: "addresses", name: "addresses",
}, },
{ icon: moon, title: "حالت شب", onClick: () => {}, name: "dark" }, { icon: moon, title: window.t("حالت شب"), onClick: () => {}, name: "dark" },
{ {
icon: logoutIcon, icon: logoutIcon,
title: "خروج از حساب کاربری", title: window.t("خروج از حساب کاربری"),
// onClick: () => logout(), // onClick: () => logout(),
onClick: () => onClick: () =>
setDialog({ setDialog({
text: "میخوای تنهامون بذاری؟", text: window.t("میخوای تنهامون بذاری؟"),
type: "confirm", type: "confirm",
accept: () => logout(), accept: () => logout(),
open: true, open: true,
@ -150,7 +150,7 @@ const SidebarMenu = ({
}} }}
> >
{/* profile */} {/* profile */}
<div className="flex flex-row items-center mb-10"> <div className="flex items-center mb-10">
<Avatar size={60} rounded={true} /> <Avatar size={60} rounded={true} />
<p className="text-green7B font-bold text-base flex-1 mx-2"> <p className="text-green7B font-bold text-base flex-1 mx-2">
{user.firstName === null ? "" : user.firstName + " " + user.lastName} {user.firstName === null ? "" : user.firstName + " " + user.lastName}
@ -177,7 +177,7 @@ const SidebarMenu = ({
key={i} key={i}
> >
<div <div
className={`flex flex-row items-center cursor-pointer rounded-md py-0 my-3 px-1`} className={`flex items-center cursor-pointer rounded-md py-0 my-3 px-1`}
> >
<img src={button.icon} alt="" /> <img src={button.icon} alt="" />
<strong <strong
@ -214,16 +214,16 @@ SidebarMenu.defaultProps = {
profile: { profile: {
name: "profile", name: "profile",
icon: userEdit, icon: userEdit,
title: "حساب کاربری", title: window.t("حساب کاربری"),
notification: null, notification: null,
list: [{ title: "ویرایش حساب کاربری", value: "profile" }], list: [{ title: window.t("ویرایش حساب کاربری"), value: "profile" }],
}, },
support: { support: {
name: "support", name: "support",
icon: sms, icon: sms,
title: "پشتیبانی", title: window.t("پشتیبانی"),
notification: null, notification: null,
list: [{ title: "ثبت نظر", value: "setTicket" }], list: [{ title: window.t("ثبت نظر"), value: window.t("setTicket") }],
}, },
}; };

@ -62,16 +62,16 @@ function Address({
<div className="flex items-center gap-x-4 mt-2"> <div className="flex items-center gap-x-4 mt-2">
<div <div
style={{ border: "solid 1px #fca5a5" }} style={{ border: "solid 1px #fca5a5" }}
class="w-full flex flex-row items-center justify-between px-2 py-1 rounded-sm cursor-pointer" class="w-full flex items-center justify-between px-2 py-1 rounded-sm cursor-pointer"
> >
<button class="text-sm">حذف</button> <button class="text-sm">{window.t("حذف")}</button>
<img src={trash} alt="delete-address" className="w-5 mr-3" /> <img src={trash} alt="delete-address" className="w-5 mr-3" />
</div> </div>
<div <div
style={{ border: "solid 1px #12CF7F" }} style={{ border: "solid 1px #12CF7F" }}
class="w-full flex flex-row items-center justify-between px-2 py-1 rounded-sm cursor-pointer" class="w-full flex items-center justify-between px-2 py-1 rounded-sm cursor-pointer"
> >
<button class="text-sm">ویرایش</button> <button class="text-sm">{window.t("ویرایش")}</button>
<img src={editButton} alt="edit-address" className="w-5 mr-3 " /> <img src={editButton} alt="edit-address" className="w-5 mr-3 " />
</div> </div>
</div> </div>
@ -106,34 +106,38 @@ function Address({
)} )}
<div className="flex flex-col gap-y-2"> <div className="flex flex-col gap-y-2">
<li className="text-right text-tiny leading-6 text-blue52 dark:text-white"> <li className="text-right text-tiny leading-6 text-blue52 dark:text-white">
آدرس:&nbsp;{address.address} {window.t(" آدرس:")}
&nbsp;{address.address}
</li> </li>
<li className="text-right text-tiny leading-6 text-blue52 dark:text-white"> <li className="text-right text-tiny leading-6 text-blue52 dark:text-white">
کد پستی:&nbsp;{address.postalCode} {window.t("کد پستی:")}
&nbsp;{address.postalCode}
</li> </li>
</div> </div>
</div> </div>
<div className="flex flex-col"> <div className="flex flex-col">
<li className="text-right text-tiny leading-6 text-blue52 dark:text-white"> <li className="text-right text-tiny leading-6 text-blue52 dark:text-white">
نام تحویل گیرنده:&nbsp;{address.firstName + " " + address.lastName} {window.t("نام تحویل گیرنده:")}
&nbsp;{address.firstName + " " + address.lastName}
</li> </li>
<li className="text-right text-tiny leading-6 text-blue52 dark:text-white mt-3"> <li className="text-right text-tiny leading-6 text-blue52 dark:text-white mt-3">
شماره تماس:&nbsp;{address.cellphone} {window.t("شماره تماس:")}
&nbsp;{address.cellphone}
</li> </li>
</div> </div>
<div className="flex flex-col items-center gap-y-2"> <div className="flex flex-col items-center gap-y-2">
<div <div
style={{ border: "solid 1px #fca5a5" }} style={{ border: "solid 1px #fca5a5" }}
class="w-full flex flex-row items-center justify-between px-2 py-1 rounded-sm cursor-pointer" class="w-full flex items-center justify-between px-2 py-1 rounded-sm cursor-pointer"
> >
<button class="text-sm">حذف</button> <button class="text-sm">{window.t("حذف")}</button>
<img src={trash} alt="delete-address" className="w-5 mr-3" /> <img src={trash} alt="delete-address" className="w-5 mr-3" />
</div> </div>
<div <div
style={{ border: "solid 1px #12CF7F" }} style={{ border: "solid 1px #12CF7F" }}
class="w-full flex flex-row items-center justify-between px-2 py-1 rounded-sm cursor-pointer" class="w-full flex items-center justify-between px-2 py-1 rounded-sm cursor-pointer"
> >
<button class="text-sm">ویرایش</button> <button class="text-sm">{window.t("ویرایش")}</button>
<img src={editButton} alt="edit-address" className="w-5 mr-3 " /> <img src={editButton} alt="edit-address" className="w-5 mr-3 " />
</div> </div>
</div> </div>
@ -148,7 +152,7 @@ function Address({
return isMobile ? ( return isMobile ? (
<section className="mt-2 w-full"> <section className="mt-2 w-full">
<strong className="font-bold text-green7B dark:text-white lg:text-tiny"> <strong className="font-bold text-green7B dark:text-white lg:text-tiny">
انتخاب آدرس {window.t("انتخاب آدرس")}
</strong> </strong>
<ul className="list-none p-0 m-0 flex flex-col gap-y-3"> <ul className="list-none p-0 m-0 flex flex-col gap-y-3">
{addresses.map((address, index) => ( {addresses.map((address, index) => (
@ -159,7 +163,7 @@ function Address({
/> />
))} ))}
</ul> </ul>
<div className="w-full flex flex-row justify-between items-center mt-4"> <div className="w-full flex justify-between items-center mt-4">
<button <button
className={`flex justify-center text-tiny py-3 rounded-md bg-grayF9 dark:bg-blueC0 dark:bg-opacity-10 w-full ${ className={`flex justify-center text-tiny py-3 rounded-md bg-grayF9 dark:bg-blueC0 dark:bg-opacity-10 w-full ${
isDark ? "text-white" : "text-gray70" isDark ? "text-white" : "text-gray70"
@ -169,14 +173,17 @@ function Address({
border: `1px solid ${isDark ? "#DBDBDB22" : "#DBDBDB"}`, border: `1px solid ${isDark ? "#DBDBDB22" : "#DBDBDB"}`,
}} }}
> >
&nbsp;یک آدرس جدید اضافه کنید &nbsp;
{window.t("یک آدرس جدید اضافه کنید")}
<strong className="text-lg transform translate-y-0.5 mr-1">+</strong> <strong className="text-lg transform translate-y-0.5 mr-1">+</strong>
</button> </button>
</div> </div>
</section> </section>
) : ( ) : (
<section className="mt-0.5 w-full"> <section className="mt-0.5 w-full">
<strong className="font-medium dark:text-white">انتخاب آدرس</strong> <strong className="font-medium dark:text-white">
{window.t("انتخاب آدرس")}
</strong>
<ul className="list-none p-0 m-0 flex flex-col gap-y-2"> <ul className="list-none p-0 m-0 flex flex-col gap-y-2">
{addresses.map((address, index) => ( {addresses.map((address, index) => (
<Location <Location
@ -186,7 +193,7 @@ function Address({
/> />
))} ))}
</ul> </ul>
<div className="w-full flex flex-row justify-between items-center mt-4"> <div className="w-full flex justify-between items-center mt-4">
<button <button
className={`flex justify-center text-tiny lg:text-sm rounded-md py-3 bg-grayF9 dark:bg-blueC0 dark:bg-opacity-30 ${ className={`flex justify-center text-tiny lg:text-sm rounded-md py-3 bg-grayF9 dark:bg-blueC0 dark:bg-opacity-30 ${
isDark ? "text-white" : "text-gray70" isDark ? "text-white" : "text-gray70"
@ -196,7 +203,8 @@ function Address({
border: `1px solid ${isDark ? "#DBDBDB22" : "#DBDBDB"}`, border: `1px solid ${isDark ? "#DBDBDB22" : "#DBDBDB"}`,
}} }}
> >
&nbsp;یک آدرس جدید اضافه کنید &nbsp;
{window.t("یک آدرس جدید اضافه کنید")}
<strong className="text-lg transform translate-y-0.5 mr-1">+</strong> <strong className="text-lg transform translate-y-0.5 mr-1">+</strong>
</button> </button>
</div> </div>

@ -19,8 +19,10 @@ function PaymentMethods({ paymentMethods }) {
}; };
return ( return (
<section className="mt-8"> <section className="mt-8">
<strong className="font-medium dark:text-white text-base">انتخاب شیوه پرداخت</strong> <strong className="font-medium dark:text-white text-base">
<ul className="list-none p-0 m-0 flex flex-row justify-between flex-wrap"> {window.t("انتخاب شیوه پرداخت")}
</strong>
<ul className="list-none p-0 m-0 flex justify-between flex-wrap">
{paymentMethods.map((method, index) => ( {paymentMethods.map((method, index) => (
<Method method={method} key={index} /> <Method method={method} key={index} />
))} ))}

@ -50,7 +50,7 @@ function TransportDate({ transportDate, isMobile }) {
activeDate === time ? "text-green7B" : "text-blue52" activeDate === time ? "text-green7B" : "text-blue52"
}`} }`}
> >
تکمیل ظرفیت {window.t("تکمیل ظرفیت")}
</span> </span>
)} )}
</button> </button>
@ -62,7 +62,7 @@ function TransportDate({ transportDate, isMobile }) {
{/* <strong className="font-bold text-green7B dark:text-white lg:text-tiny"> {/* <strong className="font-bold text-green7B dark:text-white lg:text-tiny">
زمان ارسال را انتخاب کنید زمان ارسال را انتخاب کنید
</strong> </strong>
<ul className="list-none p-0 m-0 flex flex-row justify-between flex-wrap w-full gap-4 mt-4"> <ul className="list-none p-0 m-0 flex justify-between flex-wrap w-full gap-4 mt-4">
{transportDate.times.map((time, index) => ( {transportDate.times.map((time, index) => (
<Time time={time} key={index} /> <Time time={time} key={index} />
))} ))}
@ -73,7 +73,7 @@ function TransportDate({ transportDate, isMobile }) {
{/* <strong className="font-medium dark:text-white"> {/* <strong className="font-medium dark:text-white">
زمان ارسال را انتخاب کنید زمان ارسال را انتخاب کنید
</strong> </strong>
<ul className="list-none p-0 m-0 flex flex-row flex-wrap w-full gap-2"> <ul className="list-none p-0 m-0 flex flex-wrap w-full gap-2">
{transportDate.times.map((time, index) => ( {transportDate.times.map((time, index) => (
<Time time={time} key={index} /> <Time time={time} key={index} />
))} ))}

@ -102,7 +102,7 @@ function TransportMethod({
<strong className="font-medium dark:text-white"> <strong className="font-medium dark:text-white">
لطفا یک روش ارسال انتخاب کنید لطفا یک روش ارسال انتخاب کنید
</strong> </strong>
<ul className="list-none p-0 m-0 flex flex-row gap-5 flex-wrap"> <ul className="list-none p-0 m-0 flex gap-5 flex-wrap">
{list.map((method, index) => ( {list.map((method, index) => (
<Method <Method
method={method} method={method}

@ -34,7 +34,7 @@ export const DeliveryForm = ({
const PriceStatus = ({ name, value, type }) => { const PriceStatus = ({ name, value, type }) => {
return ( return (
<div className="w-full flex flex-row justify-between py-2"> <div className="w-full flex justify-between py-2">
<strong className="font-light text-sm dark:text-white">{name}</strong> <strong className="font-light text-sm dark:text-white">{name}</strong>
<span <span
className="font-bold text-sm dark:text-white" className="font-bold text-sm dark:text-white"
@ -50,13 +50,13 @@ export const DeliveryForm = ({
return isMobile ? ( return isMobile ? (
<div className="w-full flex flex-col pt-4 pb-4"> <div className="w-full flex flex-col pt-4 pb-4">
<div className="w-full flex flex-row gap-5"> <div className="w-full flex gap-5">
<Address addresses={list} setPhase={setPhase} /> <Address addresses={list} setPhase={setPhase} />
</div> </div>
<div className="w-full flex flex-row gap-5 mt-8"> <div className="w-full flex gap-5 mt-8">
<TransportMethod /> <TransportMethod />
</div> </div>
<div className="w-full flex flex-row gap-5 mt-8"> <div className="w-full flex gap-5 mt-8">
<TransportDate transportDate={form.transportDate} /> <TransportDate transportDate={form.transportDate} />
</div> </div>
{isMobile && ( {isMobile && (
@ -80,19 +80,19 @@ export const DeliveryForm = ({
</div> </div>
) : ( ) : (
<div className="w-full flex flex-col px-4 pb-10"> <div className="w-full flex flex-col px-4 pb-10">
<div className="w-full flex flex-row gap-5"> <div className="w-full flex gap-5">
<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={list} setPhase={setPhase} /> <Address addresses={list} setPhase={setPhase} />
</div> </div>
<div className="w-full flex flex-row gap-5 mt-8"> <div className="w-full flex 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">
2 2
</span> </span>
<TransportMethod /> <TransportMethod />
</div> </div>
{/* <div className="w-full flex flex-row gap-5 mt-8"> {/* <div className="w-full flex 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">
3 3
</span> </span>

@ -8,7 +8,7 @@ function NotFound({ title, subTitle, link }) {
return ( return (
<Link <Link
to={link} to={link}
className="flex flex-row items-center justify-between py-3.5 px-2 rounded-sm bg-blueC0 bg-opacity-10 mt-4 self-end lg:self-auto lg:ml-1/2 w-full lg:w-auto" className="flex items-center justify-between py-3.5 px-2 rounded-sm bg-blueC0 bg-opacity-10 mt-4 self-end lg:self-auto lg:ml-1/2 w-full lg:w-auto"
> >
<div className="flex flex-col w-full lg:w-full"> <div className="flex flex-col w-full lg:w-full">
{title && <strong className="text-xs text-green4F text-opacity-70 lg:text-tiny">{title}</strong>} {title && <strong className="text-xs text-green4F text-opacity-70 lg:text-tiny">{title}</strong>}

@ -15,7 +15,7 @@ function Question({ item, selectFaq }) {
} }
} }
> >
<div className="flex flex-row justify-between items-center"> <div className="flex justify-between items-center">
<strong className="flex-1 text-green4F text-xs lg:text-tiny font-medium dark:text-white lg:text-green4F"> <strong className="flex-1 text-green4F text-xs lg:text-tiny font-medium dark:text-white lg:text-green4F">
{item.title} {item.title}
</strong> </strong>

@ -41,7 +41,7 @@ function Faq({ headerOptions, setHeaderOptions, isMobile, list, getList, selectF
<Question key={index} item={item} selectFaq={selectFaq} /> <Question key={index} item={item} selectFaq={selectFaq} />
))} ))}
</div> </div>
<div className="w-full flex flex-row lg:w-4/5 justify-end"> <div className="w-full flex lg:w-4/5 justify-end">
<NotFound <NotFound
title={"پرسش خود را در لیست بالا پیدا نکردید؟"} title={"پرسش خود را در لیست بالا پیدا نکردید؟"}
subTitle={"برای ما پیام ارسال کنید"} subTitle={"برای ما پیام ارسال کنید"}

@ -26,7 +26,7 @@ const Favorites = ({
}, []); }, []);
return ( return (
<div className="flex flex-row flex-wrap"> <div className="flex flex-wrap">
{bookmarkList.map((bookmark, index) => ( {bookmarkList.map((bookmark, index) => (
<Bookmark key={index} bookmark={bookmark} /> <Bookmark key={index} bookmark={bookmark} />
))} ))}

@ -23,7 +23,7 @@ const Part2 = ({ books }) => {
<div> <div>
<Link <Link
to="/products" to="/products"
className="py-3 px-4 rounded bg-grayF4 text-blue3D text-tiny flex flex-row items-center" className="py-3 px-4 rounded bg-grayF4 text-blue3D text-tiny flex items-center"
> >
مشاهده بیشتر مشاهده بیشتر
<div className="transform rotate-90 translate-y-px mr-1"> <div className="transform rotate-90 translate-y-px mr-1">

@ -15,7 +15,7 @@ const Part4 = ({ books, grades }) => {
<div> <div>
<Link <Link
to="/products" to="/products"
className="py-3 px-4 rounded bg-grayF4 text-blue3D text-tiny flex flex-row items-center" className="py-3 px-4 rounded bg-grayF4 text-blue3D text-tiny flex items-center"
> >
مشاهده بیشتر مشاهده بیشتر
<div className="transform rotate-90 translate-y-px mr-1"> <div className="transform rotate-90 translate-y-px mr-1">

@ -14,7 +14,7 @@ const SalesContainer = ({ books }) => {
return ( return (
<div className="w-full my-10"> <div className="w-full my-10">
<div className="w-full py-10 pl-2 bg-white flex justify-between items-center gap-3"> <div className="w-full py-10 pl-2 bg-white flex justify-between items-center gap-3">
<div className="flex flex-row items-center pl-4"> <div className="flex items-center pl-4">
{/* <div className="w-6 h-6 bg-blue-300 ml-4 rounded-full"></div> */} {/* <div className="w-6 h-6 bg-blue-300 ml-4 rounded-full"></div> */}
<div className="text-3xl leading-normal"> <div className="text-3xl leading-normal">
<h3 className=" bg-blueC0 text-white text-center bold text-7xl"> <h3 className=" bg-blueC0 text-white text-center bold text-7xl">

@ -6,7 +6,7 @@ import _ from "lodash";
export default function Lights({ degrees}) { export default function Lights({ degrees}) {
return ( return (
<div className="w-full"> <div className="w-full">
<header className="container hidden flex-row px-12 lg:px-0 justify-between z-20 transform -translate-y-16 lg:-translate-y-24"> <header className="container hidden px-12 lg:px-0 justify-between z-20 transform -translate-y-16 lg:-translate-y-24">
{degrees.map((light, index) => ( {degrees.map((light, index) => (
<Light degree={light} key={index} /> <Light degree={light} key={index} />
))} ))}

@ -101,10 +101,10 @@ function Page1({ list, top }) {
/> />
</div> </div>
<div <div
className="container flex flex-row justify-between relative transform translate-y-12" className="container flex justify-between relative transform translate-y-12"
style={{ alignItems: "start" }} style={{ alignItems: "start" }}
> >
<div className="list-none flex flex-row bg-blueB0 bg-opacity-40 p-2.5 rounded-md backdrop-filter backdrop-blur-md"> <div className="list-none flex bg-blueB0 bg-opacity-40 p-2.5 rounded-md backdrop-filter backdrop-blur-md">
<strong className="text-white text-sm font-light ml-1 border-l-2 pl-2 border-gray-300"> <strong className="text-white text-sm font-light ml-1 border-l-2 pl-2 border-gray-300">
لیست محصولات لیست محصولات
</strong> </strong>
@ -129,7 +129,7 @@ function Page1({ list, top }) {
</p> </p>
<Link <Link
to="/products" to="/products"
className="flex flex-row items-center text-white text-xs bg-blueC0 px-4 py-3 rounded-md backdrop-filter backdrop-blur-md mt-5 self-end animate-bounce" className="flex items-center text-white text-xs bg-blueC0 px-4 py-3 rounded-md backdrop-filter backdrop-blur-md mt-5 self-end animate-bounce"
> >
ورود به فروشگاه <img src={arrowLeftWhite} alt="" className="mr-2" /> ورود به فروشگاه <img src={arrowLeftWhite} alt="" className="mr-2" />
</Link> </Link>

@ -5,7 +5,7 @@ export default function PDF({ link }) {
return ( return (
<a <a
href={link.value} href={link.value}
className="w-full flex flex-row justify-between py-3 px-4 rounded-md bg-yellow2 my-2" className="w-full flex justify-between py-3 px-4 rounded-md bg-yellow2 my-2"
> >
<p className="text-xs font-medium text-yellow1">{link.name}</p> <p className="text-xs font-medium text-yellow1">{link.name}</p>
<img src={linkIcon} className="w-5 h-5" /> <img src={linkIcon} className="w-5 h-5" />

@ -6,7 +6,7 @@ export default function PDF({ pdf }) {
<a <a
download download
href={pdf.value} href={pdf.value}
className="w-full flex flex-row justify-between py-3 px-4 rounded-md bg-redFF my-2" className="w-full flex justify-between py-3 px-4 rounded-md bg-redFF my-2"
> >
<p className="text-xs font-medium text-red5F">{pdf.name}</p> <p className="text-xs font-medium text-red5F">{pdf.name}</p>
<img src={pdfIcon} className="w-5 h-5" /> <img src={pdfIcon} className="w-5 h-5" />

@ -44,7 +44,7 @@ function QrResult({ book, grades, checked, dataTypes, list }) {
)} )}
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
> >
<div className="w-full flex flex-row items-center"> <div className="w-full flex items-center">
<img src={book.imageUrl} alt={book.name} className="rounded-md w-1/3" /> <img src={book.imageUrl} alt={book.name} className="rounded-md w-1/3" />
<div className="flex flex-col"> <div className="flex flex-col">
<h1 className="font-semibold text-primary">{book.name}</h1> <h1 className="font-semibold text-primary">{book.name}</h1>
@ -60,7 +60,7 @@ function QrResult({ book, grades, checked, dataTypes, list }) {
className="flex flex-col justify-start rounded-md border border-blueFE overflow-hidden" className="flex flex-col justify-start rounded-md border border-blueFE overflow-hidden"
style={{ borderWidth: 1, borderColor: "#C1E0FE", borderStyle: "solid" }} style={{ borderWidth: 1, borderColor: "#C1E0FE", borderStyle: "solid" }}
> >
<ul className="w-full flex flex-row list-none items-center"> <ul className="w-full flex list-none items-center">
{dataTypes.map((item, index) => ( {dataTypes.map((item, index) => (
<li <li
key={index} key={index}

@ -10,7 +10,7 @@ function Page3({ top, translateY }) {
<div <div
className={_.join( className={_.join(
[ [
"fixed left-0 h-screen w-full bg-white transition-opacity duration-1000 flex flex-row justify-center items-end z-30", "fixed left-0 h-screen w-full bg-white transition-opacity duration-1000 flex justify-center items-end z-30",
top > 50 ? "opacity-0" : "opacity-100", top > 50 ? "opacity-0" : "opacity-100",
], ],
" " " "

@ -35,7 +35,7 @@ function Page4({ top }) {
رنگی پر نشد، به یاد هم باشیم شاید فردا ما هم در کنار هم نباشیم رنگی پر نشد، به یاد هم باشیم شاید فردا ما هم در کنار هم نباشیم
</p> </p>
<div <div
className="flex flex-row justify-center w-full mt-5" className="flex justify-center w-full mt-5"
style={{ width: "30%" }} style={{ width: "30%" }}
> >
<img src={bazarImage} alt="" className="w-36 mx-5 cursor-pointer" /> <img src={bazarImage} alt="" className="w-36 mx-5 cursor-pointer" />

@ -18,7 +18,7 @@ export default function Question({ question }) {
onClick={() => setSelect(option)} onClick={() => setSelect(option)}
className={_.join( className={_.join(
[ [
"rounded-md w-full overflow-hidden flex flex-row items-center my-2 cursor-pointer transition-all duration-500", "rounded-md w-full overflow-hidden flex items-center my-2 cursor-pointer transition-all duration-500",
], ],
" " " "
)} )}

@ -15,17 +15,17 @@ function Test({ title, duration, questions, translateY }) {
}} }}
> >
<header <header
className="w-3/4 flex flex-row justify-between py-3 px-3 rounded-md" className="w-3/4 flex justify-between py-3 px-3 rounded-md"
style={{ border: "1px solid #777" }} style={{ border: "1px solid #777" }}
> >
<div className="flex flex-row items-center"> <div className="flex items-center">
<span <span
className="w-2 h-2 rounded-full ml-2" className="w-2 h-2 rounded-full ml-2"
style={{ backgroundColor: "#CEFDFF" }} style={{ backgroundColor: "#CEFDFF" }}
></span> ></span>
<h1 className="text-blueE8 text-md font-medium">{title}</h1> <h1 className="text-blueE8 text-md font-medium">{title}</h1>
</div> </div>
<div className="flex flex-row items-center"> <div className="flex items-center">
<img src={timerIcon} className="w-4 h-4 ml-1" /> <img src={timerIcon} className="w-4 h-4 ml-1" />
<div className="text-sm text-green71"> <div className="text-sm text-green71">
{_.join(["زمان باقیمانده", duration], " ")} {_.join(["زمان باقیمانده", duration], " ")}

@ -36,7 +36,7 @@ function LessonPlayList({
{ {
<div className={_.join(["w-full mb-2.5 flex flex-col border"], " ")}> <div className={_.join(["w-full mb-2.5 flex flex-col border"], " ")}>
{/* {bookId && ( {/* {bookId && (
<header className="mb-1 flex flex-row items-center"> <header className="mb-1 flex items-center">
<h3 className="py-1 px-2.5 m-0 bg-white inline"> <h3 className="py-1 px-2.5 m-0 bg-white inline">
{ {
realCategories.filter( realCategories.filter(
@ -57,7 +57,7 @@ function LessonPlayList({
<div <div
className={_.join( className={_.join(
[ [
"flex flex-row items-center py-2", "flex items-center py-2",
video?.id === selectedVideo?.id ? "bg-white" : "", video?.id === selectedVideo?.id ? "bg-white" : "",
], ],
" " " "

@ -31,7 +31,7 @@ function VodTube({
onClick={(e) => e.stopPropagation()} onClick={(e) => e.stopPropagation()}
className={_.join( className={_.join(
[ [
"fixed flex flex-row rtl pt-20 lg:px-5 xl:px-10 w-full bg-white dark:bg-black bg-opacity-80 transition-opacity duration-500 min-h-screen backdrop-filter backdrop-blur-md", "fixed flex rtl pt-20 lg:px-5 xl:px-10 w-full bg-white dark:bg-black bg-opacity-80 transition-opacity duration-500 min-h-screen backdrop-filter backdrop-blur-md",
top > 10 ? "opacity-0 z-0" : "opacity-100 z-10", top > 10 ? "opacity-0 z-0" : "opacity-100 z-10",
], ],
" " " "
@ -59,7 +59,7 @@ function VodTube({
{/* <p className="desktop">{selectedVideo.text}</p> */} {/* <p className="desktop">{selectedVideo.text}</p> */}
</section> </section>
<section className="md:hidden sm:hidden xs:hidden pb-7 flex flex-col"> <section className="md:hidden sm:hidden xs:hidden pb-7 flex flex-col">
<header className="flex flex-row justify-between items-center px-5 py-0"> <header className="flex justify-between items-center px-5 py-0">
<h2 className="m-0">نظرات</h2> <h2 className="m-0">نظرات</h2>
<button className="border-0">بستن نظرات</button> <button className="border-0">بستن نظرات</button>
</header> </header>

@ -12,7 +12,7 @@ function Blogs({ list, isDark, setActive }) {
return ( return (
<div className="w-full pr-4"> <div className="w-full pr-4">
<div className="w-full flex flex-col rounded-md py-4 overflow-hidden"> <div className="w-full flex flex-col rounded-md py-4 overflow-hidden">
<header className="w-full flex flex-row justify-between items-center"> <header className="w-full flex justify-between items-center">
<strong className="text-green7B dark:text-white font-bold text-base lg:text-sm"> <strong className="text-green7B dark:text-white font-bold text-base lg:text-sm">
خواندنیها خواندنیها
</strong> </strong>
@ -32,7 +32,7 @@ function Blogs({ list, isDark, setActive }) {
)} )}
</Link> </Link>
</header> </header>
<ul className="list-none w-full overflow-x-scroll pt-3 flex flex-row pb-16 no-scrollbar"> <ul className="list-none w-full overflow-x-scroll pt-3 flex pb-16 no-scrollbar">
{list.map((blog, index) => ( {list.map((blog, index) => (
<Blog blog={blog} key={index} setActive={setActive} /> <Blog blog={blog} key={index} setActive={setActive} />
))} ))}
@ -47,7 +47,7 @@ const Blog = ({ blog, setActive }) => {
<li className="flex flex-col ml-3"> <li className="flex flex-col ml-3">
<Link <Link
to={"/blogs/" + blog?.id} to={"/blogs/" + blog?.id}
className="flex flex-row justify-center items-end rounded-md" className="flex justify-center items-end rounded-md"
style={{ style={{
background: `url(https://dnvn.ir/api/v1/file/${blog?.fileIds})`, background: `url(https://dnvn.ir/api/v1/file/${blog?.fileIds})`,
backgroundPosition: "contain", backgroundPosition: "contain",
@ -65,8 +65,8 @@ const Blog = ({ blog, setActive }) => {
<h2 className="text-xs font-semibold text-blue5F dark:text-white leading-5"> <h2 className="text-xs font-semibold text-blue5F dark:text-white leading-5">
{blog.title} {blog.title}
</h2> </h2>
<div className="w-full flex flex-row justify-between items-center mt-3"> <div className="w-full flex justify-between items-center mt-3">
<div className="flex flex-row items-center"> <div className="flex items-center">
<img <img
src={`https://dnvn.ir/api/v1/file/${blog?.fileIds}`} src={`https://dnvn.ir/api/v1/file/${blog?.fileIds}`}
alt="" alt=""
@ -76,7 +76,7 @@ const Blog = ({ blog, setActive }) => {
{"حامد دژبانی نسب"} {"حامد دژبانی نسب"}
</span> </span>
</div> </div>
<div className="flex flex-row items-center"> <div className="flex items-center">
<span className="text-xs font-light text-gray70 dark:text-greenBA"> <span className="text-xs font-light text-gray70 dark:text-greenBA">
{_.join(["زمان مناسب", "30"], " ")} {_.join(["زمان مناسب", "30"], " ")}
</span> </span>

@ -1,14 +1,23 @@
import React from "react"; import React from "react";
import { Link } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { ScrollingCarousel } from "@trendyol-js/react-carousel"; import { ScrollingCarousel } from "@trendyol-js/react-carousel";
//components
import Progress from "../../../../../components/Progress"; import Progress from "../../../../../components/Progress";
import Modal from "../../../../../components/Modal";
//assets
import exitImage from "../../../../../assets/icons/exit.svg";
function MyBooks({ books, grades, isMobile }) { function MyBooks({ books, grades, isMobile }) {
const Book = ({ book }) => { const [selectedModal, setSelectedModal] = React.useState(null);
const Book = React.useCallback(
({ book }) => {
return ( return (
<li className=" flex flex-col lg:ml-6 lg:p-2 lg:border lg:border-solid lg:border-green-200 lg:rounded-md lg:pt-4"> <li className=" flex flex-col lg:ml-6 lg:p-2 lg:border lg:border-solid lg:border-green-200 lg:rounded-md lg:pt-4">
<Link to={"/products/" + book.id}> <div onClick={() => setSelectedModal(book?.id)}>
<img <img
src={`https://dnvn.ir/api/v1/file/${book.fileIds}`} src={`https://dnvn.ir/api/v1/file/${book.fileIds}`}
alt="" alt=""
@ -22,6 +31,7 @@ function MyBooks({ books, grades, isMobile }) {
maxWidth: isMobile ? 70 : "", maxWidth: isMobile ? 70 : "",
}} }}
/> />
<h2 className="mt-2 text-tiny lg:text-tiny font-semibold text-blue5F dark:text-white lg:mt-4"> <h2 className="mt-2 text-tiny lg:text-tiny font-semibold text-blue5F dark:text-white lg:mt-4">
{book.name} {book.name}
</h2> </h2>
@ -29,10 +39,45 @@ function MyBooks({ books, grades, isMobile }) {
grades[book.gradeId] grades[book.gradeId]
}`}</p> }`}</p>
<Progress percent={60} direction="float-right" /> <Progress percent={60} direction="float-right" />
</div>
<Modal
open={selectedModal === book?.id}
onClose={() => setSelectedModal(null)}
>
<div
className="w-2/3 rounded-md flex flex-col items-center p-2 gap-3 bg-white relative"
onClick={(e) => e.stopPropagation()}
>
<img
src={exitImage}
alt="خروج"
className="p-2 rounded-full w-8 bg-white absolute right-1 -top-6"
onClick={() => setSelectedModal(null)}
/>
<img
src={`https://dnvn.ir/api/v1/file/${book.fileIds}`}
alt={book?.name}
className="w-full object-cover"
/>
<Link
to={"/scan"}
className="w-full text-center py-3 bg-blueC0 text-white font-medium rounded-sm text-tiny"
>
اسکن کد QR
</Link> </Link>
<a
href={`https://ar.dnvn.ir/lunch?id=${book.id}`}
className="w-full text-center py-3 bg-gray-400 text-white font-medium rounded-sm text-tiny"
>
واقعیت افزوده
</a>
</div>
</Modal>
</li> </li>
); );
}; },
[isMobile, grades, books, selectedModal]
);
return ( return (
<div className="px-4 mb-5 lg:mb-0" style={{ maxWidth: "100%" }}> <div className="px-4 mb-5 lg:mb-0" style={{ maxWidth: "100%" }}>
@ -40,21 +85,18 @@ function MyBooks({ books, grades, isMobile }) {
<strong className="text-green7B dark:text-white font-bold text-base lg:text-base mb-2"> <strong className="text-green7B dark:text-white font-bold text-base lg:text-base mb-2">
کتابهای من کتابهای من
</strong> </strong>
{isMobile ? ( <ul className=" list-none w-full overflow-x-scroll pt-2 flex lg:hidden lg:pt-5 lg:flex-wrap lg:overflow-y-scroll gap-3 lg:gap-10 no-scrollbar">
<ul className="list-none w-full overflow-x-scroll pt-2 flex flex-row lg:pt-5 lg:flex-wrap lg:overflow-y-scroll gap-3 lg:gap-10 no-scrollbar">
{books?.slice(0, 5)?.map((book, index) => ( {books?.slice(0, 5)?.map((book, index) => (
<Book book={book} key={index} /> <Book book={book} key={index} />
))} ))}
</ul> </ul>
) : ( <div className="hidden lg:flex w-full scrolling-carousel mt-4 pb-2">
<div className="w-full scrolling-carousel mt-4 pb-2">
<ScrollingCarousel className="py-3"> <ScrollingCarousel className="py-3">
{books?.map((book, index) => ( {books?.map((book, index) => (
<Book book={book} key={index} /> <Book book={book} key={index} />
))} ))}
</ScrollingCarousel> </ScrollingCarousel>
</div> </div>
)}
</div> </div>
</div> </div>
); );

@ -47,7 +47,7 @@ function Videos({ videos, grades, isDark, isMobile }) {
return ( return (
<div className="w-full px-4 lg:py-4"> <div className="w-full px-4 lg:py-4">
<div className="w-full flex flex-col py-4 lg:px-3 overflow-hidden lg:border lg:border-solid lg:border-gray-200 rounded-md lg:bg-blueC0 lg:bg-opacity-5"> <div className="w-full flex flex-col py-4 lg:px-3 overflow-hidden lg:border lg:border-solid lg:border-gray-200 rounded-md lg:bg-blueC0 lg:bg-opacity-5">
<header className="w-full flex flex-row justify-between items-center"> <header className="w-full flex justify-between items-center">
<strong className="text-green7B dark:text-white font-bold text-base lg:text-base mt-2"> <strong className="text-green7B dark:text-white font-bold text-base lg:text-base mt-2">
دورههای ویدئویی شما دورههای ویدئویی شما
</strong> </strong>
@ -66,7 +66,7 @@ function Videos({ videos, grades, isDark, isMobile }) {
)} )}
</header> </header>
{isMobile ? ( {isMobile ? (
<ul className="list-none w-full overflow-x-scroll pt-3 gap-3 lg:gap-5 flex flex-row lg:pt-5 lg:flex-wrap lg:overflow-y-scroll no-scrollbar"> <ul className="list-none w-full overflow-x-scroll pt-3 gap-3 lg:gap-5 flex lg:pt-5 lg:flex-wrap lg:overflow-y-scroll no-scrollbar">
{videos?.slice(0, 5)?.map((video, index) => ( {videos?.slice(0, 5)?.map((video, index) => (
<Video video={video} key={index} /> <Video video={video} key={index} />
))} ))}

@ -6,7 +6,7 @@ import interactiveIcon from "../../../../../assets/icons/interactive.svg";
function Features({ features }) { function Features({ features }) {
return ( return (
<div className="w-full flex flex-row flex-wrap justify-between px-2"> <div className="w-full flex flex-wrap justify-between px-2">
{features.map((feature, index) => ( {features.map((feature, index) => (
<Feature feature={feature} key={index} /> <Feature feature={feature} key={index} />
))} ))}

@ -66,7 +66,7 @@ function Header({ list }) {
<div className="w-full flex justify-center mt-5"> <div className="w-full flex justify-center mt-5">
<Link <Link
to="/products" to="/products"
className="flex flex-row items-center text-white text-tiny bg-blueC0 px-4 py-3 rounded-md backdrop-filter backdrop-blur-md mt-5 self-end" className="flex items-center text-white text-tiny bg-blueC0 px-4 py-3 rounded-md backdrop-filter backdrop-blur-md mt-5 self-end"
> >
ورود به فروشگاه ورود به فروشگاه
</Link> </Link>
@ -79,7 +79,7 @@ function Header({ list }) {
</div> </div>
<h1 className="inline">با طعم لذت</h1> <h1 className="inline">با طعم لذت</h1>
</div> </div>
<div className="flex flex-row my-1.5"> <div className="flex my-1.5">
<h1 className="inline">از اول تا یازدهم &nbsp;</h1> <h1 className="inline">از اول تا یازدهم &nbsp;</h1>
<div className="relative"> <div className="relative">
<h1 className="inline z-20 pb-1">کنارتونیم</h1> <h1 className="inline z-20 pb-1">کنارتونیم</h1>

@ -15,7 +15,7 @@ function Platforms({ platforms }) {
const Platform = ({ platform }) => { const Platform = ({ platform }) => {
return ( return (
<div <div
className="w-full flex flex-row rounded-sm p-4 items-start mb-5" className="w-full flex rounded-sm p-4 items-start mb-5"
style={{ style={{
backgroundColor: platform.backgroundColor, backgroundColor: platform.backgroundColor,
border: `1px solid ${platform.borderColor}`, border: `1px solid ${platform.borderColor}`,

@ -13,12 +13,12 @@ function Responsive() {
}} }}
> >
<div className="flex flex-col items-center text-center font-extrabold text-blue5F dark:text-gray-300 text-lg mt-3 transform translate-y-4"> <div className="flex flex-col items-center text-center font-extrabold text-blue5F dark:text-gray-300 text-lg mt-3 transform translate-y-4">
<div className="flex flex-row "> <div className="flex ">
<h1 className="inline z-50"> <h1 className="inline z-50">
از طریق موبایل یا کامپیوتر میتونی از طریق موبایل یا کامپیوتر میتونی
</h1> </h1>
</div> </div>
<div className="flex flex-row my-1.5"> <div className="flex my-1.5">
<div className="relative"> <div className="relative">
<h1 className="inline z-50 pb-1">به محتوای دیجیتال &nbsp;</h1> <h1 className="inline z-50 pb-1">به محتوای دیجیتال &nbsp;</h1>
<span className="h-1 w-full absolute bottom-0 left-0 bg-green1"></span> <span className="h-1 w-full absolute bottom-0 left-0 bg-green1"></span>

@ -3,8 +3,8 @@ import _ from "lodash";
export default function Book({ book }) { export default function Book({ book }) {
return ( return (
<div className="w-full flex flex-row justify-between py-3 border-b border-solid border-blueFF1 dark:border-gray45"> <div className="w-full flex justify-between py-3 border-b border-solid border-blueFF1 dark:border-gray45">
<div className="flex flex-row items-center flex-1"> <div className="flex items-center flex-1">
<img <img
src={book} src={book}
className="rounded-md" className="rounded-md"
@ -16,7 +16,7 @@ export default function Book({ book }) {
<span className="mt-2 text-xs lg:text-sm text-gray70 dark:text-white">نسخه دیجیتال</span> <span className="mt-2 text-xs lg:text-sm text-gray70 dark:text-white">نسخه دیجیتال</span>
</div> </div>
</div> </div>
<div className="flex flex-row items-center"> <div className="flex items-center">
<span className="py-1 px-2 rounded-sm text-green4F2 text-sm lg:text-base bg-grayF9 dark:bg-gray-500 dark:text-white"> <span className="py-1 px-2 rounded-sm text-green4F2 text-sm lg:text-base bg-grayF9 dark:bg-gray-500 dark:text-white">
1 1
</span> </span>

@ -25,11 +25,11 @@ function OrderDetails({ order, setHeaderOptions, headerOptions }) {
},[]); },[]);
return ( return (
<div className="px-4 flex flex-col py-5 lg:pt-24 lg:w-3/5 lg:mx-auto"> <div className="px-4 flex flex-col py-5 lg:pt-24 lg:w-3/5 lg:mx-auto">
<div className="flex flex-row w-full justify-between items-center p-3 bg-blueC0 bg-opacity-10 rounded-t-md dark:bg-blueC0 dark:bg-opacity-10"> <div className="flex w-full justify-between items-center p-3 bg-blueC0 bg-opacity-10 rounded-t-md dark:bg-blueC0 dark:bg-opacity-10">
<strong className="font-medium text-sm lg:text-tiny text-blue52 dark:text-white"> <strong className="font-medium text-sm lg:text-tiny text-blue52 dark:text-white">
{_.join(["شماره سفارش:", order.number], " ")} {_.join(["شماره سفارش:", order.number], " ")}
</strong> </strong>
<div className="flex flex-row items-center"> <div className="flex items-center">
<span className="text-xs lg:text-tiny font-light text-blue52 dark:text-white"> <span className="text-xs lg:text-tiny font-light text-blue52 dark:text-white">
{status[order.status]} {status[order.status]}
</span> </span>
@ -39,20 +39,20 @@ function OrderDetails({ order, setHeaderOptions, headerOptions }) {
></div> ></div>
</div> </div>
</div> </div>
<div className="w-full flex flex-row items-center py-4 border-b border-solid border-blueFF1 dark:border-gray45"> <div className="w-full flex items-center py-4 border-b border-solid border-blueFF1 dark:border-gray45">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white">آدرس تحویل:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white">آدرس تحویل:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{order.address} {order.address}
</span> </span>
</div> </div>
<div className="w-full flex flex-row justify-between py-0 border-b border-solid border-blueFF1 dark:border-gray45"> <div className="w-full flex justify-between py-0 border-b border-solid border-blueFF1 dark:border-gray45">
<div className="flex flex-row py-4"> <div className="flex py-4">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white">مشخصات تحویل گیرنده:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white">مشخصات تحویل گیرنده:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{order.name} {order.name}
</span> </span>
</div> </div>
<div className="flex flex-row py-4"> <div className="flex py-4">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white">شماره موبایل:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white">شماره موبایل:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{order.cellphone} {order.cellphone}
@ -72,50 +72,50 @@ function OrderDetails({ order, setHeaderOptions, headerOptions }) {
<Book book={item} key={index} /> <Book book={item} key={index} />
))} ))}
</div> </div>
<div className="w-full flex flex-row justify-between py-2 border-b border-solid border-blueFF1 dark:border-gray45"> <div className="w-full flex justify-between py-2 border-b border-solid border-blueFF1 dark:border-gray45">
<div className="flex flex-row py-4"> <div className="flex py-4">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white">مبلغ سبد خرید:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white">مبلغ سبد خرید:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{_.join([order.shoppingCardPrice, "تومان"], " ")} {_.join([order.shoppingCardPrice, "تومان"], " ")}
</span> </span>
</div> </div>
<div className="flex flex-row py-4"> <div className="flex py-4">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white">تخفیف:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white">تخفیف:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{_.join([order.discountPrice, "تومان"], " ")} {_.join([order.discountPrice, "تومان"], " ")}
</span> </span>
</div> </div>
</div> </div>
<div className="w-full flex flex-row justify-between py-2 border-b border-solid border-blueFF1 dark:border-gray45"> <div className="w-full flex justify-between py-2 border-b border-solid border-blueFF1 dark:border-gray45">
<div className="flex flex-row py-4"> <div className="flex py-4">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white"> هزینه ارسال کالا:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white"> هزینه ارسال کالا:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{_.join([order.sendPrice, "تومان"], " ")} {_.join([order.sendPrice, "تومان"], " ")}
</span> </span>
</div> </div>
<div className="flex flex-row py-4 border"> <div className="flex py-4 border">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white">جمع هزینه پرداختی:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white">جمع هزینه پرداختی:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{_.join([order.totalPrice, "تومان"], " ")} {_.join([order.totalPrice, "تومان"], " ")}
</span> </span>
</div> </div>
</div> </div>
<div className="w-full flex flex-row justify-between py-2 border-b border-solid border-blueFF1 dark:border-gray45"> <div className="w-full flex justify-between py-2 border-b border-solid border-blueFF1 dark:border-gray45">
<div className="flex flex-row py-4"> <div className="flex py-4">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white">نحوه پرداخت:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white">نحوه پرداخت:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{order.payMethod} {order.payMethod}
</span> </span>
</div> </div>
<div className="flex flex-row py-4"> <div className="flex py-4">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white"> شماره تراکنش:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white"> شماره تراکنش:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{order.transactionNumber} {order.transactionNumber}
</span> </span>
</div> </div>
</div> </div>
<div className="w-full flex flex-row justify-between py-2"> <div className="w-full flex justify-between py-2">
<div className="w-full flex flex-row py-4"> <div className="w-full flex py-4">
<strong className="text-xs lg:text-tiny text-green4F dark:text-white">تاریخ تحویل:</strong> <strong className="text-xs lg:text-tiny text-green4F dark:text-white">تاریخ تحویل:</strong>
<span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white"> <span className="flex-1 font-light text-right mr-2 text-xs lg:text-tiny text-green4F dark:text-white">
{order.date} {order.date}

@ -21,11 +21,11 @@ const status = {
function Order({ order, isMobile }) { function Order({ order, isMobile }) {
return ( return (
<div className="w-full flex flex-col rounded-md overflow-hidden my-3 border border-solid border-blueC0 border-opacity-50 dark:border-blueC0 dark:border-opacity-10 lg:w-4/5 mx-auto"> <div className="w-full flex flex-col rounded-md overflow-hidden my-3 border border-solid border-blueC0 border-opacity-50 dark:border-blueC0 dark:border-opacity-10 lg:w-4/5 mx-auto">
<div className="flex flex-row w-full justify-between items-center p-3 bg-blueC0 bg-opacity-10 dark:bg-blueC0 dark:bg-opacity-10"> <div className="flex w-full justify-between items-center p-3 bg-blueC0 bg-opacity-10 dark:bg-blueC0 dark:bg-opacity-10">
<strong className="font-medium text-sm lg:text-tiny text-green4F dark:text-white"> <strong className="font-medium text-sm lg:text-tiny text-green4F dark:text-white">
{_.join(["شماره سفارش:", order.number], " ")} {_.join(["شماره سفارش:", order.number], " ")}
</strong> </strong>
<div className="flex flex-row items-center"> <div className="flex items-center">
<span className="text-xs lg:text-tiny font-light text-green4F dark:text-white"> <span className="text-xs lg:text-tiny font-light text-green4F dark:text-white">
{status[order.status]} {status[order.status]}
</span> </span>
@ -35,9 +35,9 @@ function Order({ order, isMobile }) {
></div> ></div>
</div> </div>
</div> </div>
<div className="w-full flex flex-row justify-between p-3"> <div className="w-full flex justify-between p-3">
<div className="flex flex-col"> <div className="flex flex-col">
<div className="flex flex-row mb-2"> <div className="flex mb-2">
{order.items.length < 2 {order.items.length < 2
? order?.items?.map((item, index) => ( ? order?.items?.map((item, index) => (
<img <img
@ -63,7 +63,7 @@ function Order({ order, isMobile }) {
))} ))}
{isMobile && order.items.length >= 2 && ( {isMobile && order.items.length >= 2 && (
<div <div
className="flex flex-row items-center justify-center relative rounded-md overflow-hidden bg-grayEE dark:bg-gray-400" className="flex items-center justify-center relative rounded-md overflow-hidden bg-grayEE dark:bg-gray-400"
style={{ style={{
width: 60, width: 60,
height: 90, height: 90,
@ -104,7 +104,7 @@ function Order({ order, isMobile }) {
</strong> </strong>
<Link <Link
to="/orders/order" to="/orders/order"
className="rounded-md flex flex-row justify-center px-5 py-2.5 border border-solid border-blueC0 text-green4F bg-blueC0 bg-opacity-10" className="rounded-md flex justify-center px-5 py-2.5 border border-solid border-blueC0 text-green4F bg-blueC0 bg-opacity-10"
> >
جزئیات سفارش جزئیات سفارش
<img <img

@ -7,8 +7,8 @@ function Comment({ comment }) {
className="flex flex-col py-3 px-2 rounded-md shadow-all border border-gray-200 border-solid dark:border-opacity-10 ml-4 w-auto" className="flex flex-col py-3 px-2 rounded-md shadow-all border border-gray-200 border-solid dark:border-opacity-10 ml-4 w-auto"
style={{ minWidth: "250px" }} style={{ minWidth: "250px" }}
> >
<header className="flex flex-row justify-between"> <header className="flex justify-between">
<div className="flex flex-row items-center"> <div className="flex items-center">
<img src={userImage} alt="" className="h-10 w-10 rounded-full" /> <img src={userImage} alt="" className="h-10 w-10 rounded-full" />
<strong className="text-blue5F text-md mr-1 dark:text-white"> <strong className="text-blue5F text-md mr-1 dark:text-white">
{comment?.name} {comment?.name}

@ -16,7 +16,7 @@ export const ProductOverAll = ({ book, grades, isDark, loading }) => {
const [type, setType] = useState("1"); const [type, setType] = useState("1");
return ( return (
<div className="w-full flex flex-col"> <div className="w-full flex flex-col">
<header className={`w-full flex flex-row justify-between gap-5`}> <header className={`w-full flex justify-between gap-5`}>
<ProductImages images={book?.fileIds} /> <ProductImages images={book?.fileIds} />
<div className="flex flex-col w-1/2 divide-y divide-solid divide-gray-200"> <div className="flex flex-col w-1/2 divide-y divide-solid divide-gray-200">
<div className="w-full flex flex-col pr-2 py-2 border-0"> <div className="w-full flex flex-col pr-2 py-2 border-0">
@ -43,7 +43,7 @@ export const ProductOverAll = ({ book, grades, isDark, loading }) => {
به من کمک کن انتخاب کنم به من کمک کن انتخاب کنم
</p> </p>
</div> </div>
<div className="w-full flex flex-row justify-between items-center mt-4 gap-5"> <div className="w-full flex justify-between items-center mt-4 gap-5">
<Button <Button
title="نسخه فیزیکی" title="نسخه فیزیکی"
backgroundColor={isDark ? "bg-transparent" : "bg-white"} backgroundColor={isDark ? "bg-transparent" : "bg-white"}
@ -102,7 +102,7 @@ export const ProductOverAll = ({ book, grades, isDark, loading }) => {
<div className="flex py-4"> <div className="flex py-4">
<Link <Link
to={"/videos/" + book?.id} to={"/videos/" + book?.id}
className="bg-blueC0 text-green7B bg-opacity-5 font-semibold text-tiny rounded-md border border-solid border-blueC0 w-2/3 py-4 text-center flex flex-row items-center justify-center" className="bg-blueC0 text-green7B bg-opacity-5 font-semibold text-tiny rounded-md border border-solid border-blueC0 w-2/3 py-4 text-center flex items-center justify-center"
> >
مشاهده دوره ویدیویی این محصول مشاهده دوره ویدیویی این محصول
<img <img

@ -1,73 +1,112 @@
import React from "react"; import React from "react";
import separate from '../../../utils/separate'; import separate from "../../../utils/separate";
//components //components
import StarRating from "../../../components/StarRating"; import StarRating from "../../../components/StarRating";
import Progress from "../../../components/Progress"; import Progress from "../../../components/Progress";
function Rate({ desktop, productId, rateDetail }) {
const fiveCount = React.useMemo(() => {
return rateDetail?.find((rate) => rate?.rate === 5);
}, [rateDetail]);
const fourCount = React.useMemo(() => {
return rateDetail?.find((rate) => rate?.rate === 4);
}, [rateDetail]);
const threeCount = React.useMemo(() => {
return rateDetail?.find((rate) => rate?.rate === 3);
}, [rateDetail]);
const twoCount = React.useMemo(() => {
return rateDetail?.find((rate) => rate?.rate === 2);
}, [rateDetail]);
const oneCount = React.useMemo(() => {
return rateDetail?.find((rate) => rate?.rate === 1);
}, [rateDetail]);
const allCount = React.useMemo(() => {
return rateDetail?.reduce((a, b) => a + b?.count, 0);
}, [rateDetail]);
const rate = React.useMemo(() => {
return rateDetail?.length
? ((oneCount?.count || 0) * 1 +
(twoCount?.count || 0) * 2 +
(threeCount?.count || 0) * 3 +
(fourCount?.count || 0) * 4 +
(fiveCount?.count || 0) * 5) /
rateDetail?.length
: 0;
}, [rateDetail]);
function Rate({ avarage, all, fields, desktop }) {
return ( return (
<div className="w-full flex flex-row justify-between items-center mt-5"> <div className="w-full flex justify-between items-center mt-5">
<div className="flex flex-col items-center justify-center h-full ml-4"> <div className="flex flex-col items-center justify-center h-full ml-4">
{ {desktop ? (
desktop ?
<h1 className={`text-gray-600 mb-2 font-bold dark:text-white`}> <h1 className={`text-gray-600 mb-2 font-bold dark:text-white`}>
{avarage} {rate}
</h1> </h1>
: ) : (
<strong className={`text-blue5F mb-2 font-bold dark:text-white`} style={{ fontSize: 'calc(100vw / 10)' }}> <strong
{avarage} className={`text-blue5F mb-2 font-bold dark:text-white`}
style={{ fontSize: "calc(100vw / 10)" }}
>
{rate}
</strong> </strong>
} )}
<div className=""> <div className="">
<StarRating /> <StarRating value={rate} />
</div> </div>
<span className="text-base text-gray70 mt-2 dark:text-white">{separate(all)}</span> <span className="text-base text-gray70 mt-2 dark:text-white">
{" "}
{`از بین ${allCount} نفر`}
</span>
</div> </div>
<ul className="p-0 m-0 list-none flex flex-col flex-1"> <ul className="p-0 m-0 list-none flex flex-col flex-1">
{fields.map((item, index) => ( {[
<li key={index} className="w-full flex flex-row-reverse items-center justify-between">
<span className="mr-2 text-xs text-blue5F dark:text-white">{item.name}</span>
{
desktop ? <Progress deskTop percent={item.percent} /> : <Progress percent={item.percent} />
}
<span className="ml-2 text-xs text-blue5F dark:text-white">{item.percent + "%"}</span>
</li>
))}
</ul>
</div>
);
}
export default Rate;
Rate.defaultProps = {
avarage: 4.8,
all: 4780,
fields: [
{ {
name: "5 ستاره", name: "یک ستاره",
percent: 49, value: ((oneCount?.count || 0) / allCount) * 100,
}, },
{ {
name: "4 ستاره", name: "دو ستاره",
percent: 31, value: ((twoCount?.count || 0) / allCount) * 100,
}, },
{ {
name: "3 ستاره", name: "سه ستاره",
percent: 9, value: ((threeCount?.count || 0) / allCount) * 100,
}, },
{ {
name: "2 ستاره", name: "چهار ستاره",
percent: 5, value: ((fourCount?.count || 0) / allCount) * 100,
}, },
{ {
name: "1 ستاره", name: "پنج ستاره",
percent: 6, value: ((fiveCount?.count || 0) / allCount) * 100,
}, },
], ].map((item, index) => (
}; <li
key={index}
className="w-full flex flex-row-reverse items-center justify-between"
>
<span className="mr-2 text-xs text-blue5F dark:text-white">
{item.name}
</span>
{desktop ? (
<Progress deskTop percent={item.value} />
) : (
<Progress percent={item.value} />
)}
<span className="ml-2 text-xs text-blue5F dark:text-white">
{item.value + "%"}
</span>
</li>
))}
</ul>
</div>
);
}
export default Rate;

@ -1,7 +1,7 @@
import React, { useState, useEffect } from "react"; import React, { useState, useEffect } from "react";
import { connect } from "react-redux"; import { connect } from "react-redux";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import { book, userProduct, publicApi } from "../../redux/actions"; import { book, userProduct, publicApi, dialog } from "../../redux/actions";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import proxy from "../../redux/proxy"; import proxy from "../../redux/proxy";
import location from "../../utils/location"; import location from "../../utils/location";
@ -22,6 +22,7 @@ import arrow from "../../assets/icons/dropdown-blue.svg";
export const Product = ({ export const Product = ({
isMobile, isMobile,
productType, productType,
userProducts,
getInfo, getInfo,
book, book,
grades, grades,
@ -29,15 +30,62 @@ export const Product = ({
userId, userId,
pushToCart, pushToCart,
headerOptions, headerOptions,
userProductLoading,
setHeaderOptions, setHeaderOptions,
availableForSell,
setDialog,
}) => { }) => {
const [type, setType] = useState("physical"); const [whichTypeAdded, setWhichTypeAdded] = React.useState(null);
const [desktopContentTransform, setDesktopContentTransform] = useState(false); const [desktopContentTransform, setDesktopContentTransform] = useState(false);
const navigation = useNavigate(); const navigation = useNavigate();
const physicalAvailableForSell = React.useMemo(() => {
return availableForSell?.find((product) => product === 2);
}, [availableForSell]);
const digitalAvailableForSell = React.useMemo(() => {
return availableForSell?.find((product) => product === 1);
}, [availableForSell]);
const videoAvailableForSell = React.useMemo(() => {
return availableForSell?.find((product) => product === 4);
}, [availableForSell]);
const physicalProduct = React.useMemo(() => {
return book?.product?.find((product) => product?.productType === 2);
}, [book]);
const digitalProduct = React.useMemo(() => {
return book?.product?.find((product) => product?.productType === 1);
}, [book]);
const videoProduct = React.useMemo(() => {
return book?.product?.find((product) => product?.productType === 4);
}, [book]);
const physicalAvailabileInCart = React.useMemo(() => {
return userProducts?.find(
(product) =>
product?.productId === physicalProduct?.id && product?.condition < 2
);
}, [userProducts, book]);
const digitalAvailabileInCart = React.useMemo(() => {
return userProducts?.find(
(product) =>
product?.productId === digitalProduct?.id && product?.condition < 2
);
}, [userProducts, book]);
const videoAvailabileInCart = React.useMemo(() => {
return userProducts?.find(
(product) =>
product?.productId === videoProduct?.id && product?.condition < 2
);
}, [userProducts, book]);
useEffect(() => { useEffect(() => {
getInfo({ id: location.getId(), vod: true }); getInfo({ id: location.getId(), vod: true });
setHeaderOptions(headerOptions);
if (!isMobile) { if (!isMobile) {
window.addEventListener("scroll", () => { window.addEventListener("scroll", () => {
if (window.scrollY >= 64) { if (window.scrollY >= 64) {
@ -49,6 +97,18 @@ export const Product = ({
} }
}, []); }, []);
useEffect(() => {
if (!userProductLoading) {
setWhichTypeAdded(null);
}
}, [userProductLoading]);
useEffect(() => {
if (book) {
setHeaderOptions({ ...headerOptions, productId: book?.id });
window.scroll({ top: 0, behavior: "smooth" });
}
}, [book]);
return ( return (
<> <>
{/* Portrait */} {/* Portrait */}
@ -79,52 +139,112 @@ export const Product = ({
</div> </div>
</header> </header>
<ul <ul
className="list-none flex flex-row divide-x items-center mt-5" className="list-none flex divide-x items-center mt-5"
style={{ direction: "ltr" }} style={{ direction: "ltr" }}
> >
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white"> <li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white">
{book?.pagesNum} <br /> صفحه {book?.pagesNum} <br /> صفحه
</li> </li>
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white"> <li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white">
{"فیزیکی - دیجیتالی"} <br /> در دسترس <span>{videoAvailableForSell ? "ویدئویی - " : ""}</span>
<span>{digitalAvailableForSell ? "دیجیتال - " : ""}</span>
<span>{physicalAvailableForSell ? "فیزیکی" : ""}</span>
<br /> در دسترس
</li> </li>
{book?.rate ? (
<li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white"> <li className="border-solid border-blueFE flex-1 flex-shrink-0 text-center text-tiny leading-5 font-medium text-green7B dark:text-white">
{book?.rate} <br /> امتیاز {book?.rate} <br /> امتیاز
</li> </li>
) : null}
</ul> </ul>
<h2 className="text-green7B text-base font-semibold mt-10 dark:text-greenBA"> <h2 className="text-green7B text-base font-semibold mt-10 dark:text-greenBA">
نسخه محصول را انتخاب کنید نسخه محصول را انتخاب کنید
</h2> </h2>
<div className="w-full flex flex-row justify-between items-center mt-5"> {physicalProduct && physicalAvailableForSell ? (
<div className="w-full flex justify-between items-center mt-5 gap-2">
<ButtonBetween <ButtonBetween
width="100%" width="72%"
item={"خرید نسخه فیزیکی کتاب"} item={"خرید نسخه فیزیکی کتاب"}
status={separate(book?.product[1]?.price) + " " + "تومان"} status={separate(physicalProduct?.price) + " " + "تومان"}
onClick={() => onClick={() => {
userId if (userId) {
? pushToCart({ if (physicalAvailabileInCart) {
productId: book?.product[1]?.id, setDialog({
userId, text: window.t(
"این محصول قبلا به سبد خرید شما اضافه شده است."
),
type: "confirm",
accept: () => navigation("/cart"),
open: true,
});
} else {
setWhichTypeAdded("physical");
pushToCart({
productId: physicalProduct?.id,
userId: userId,
count: 1, count: 1,
}) });
: toast.info("ابتدا وارد حساب کاربری خود شوید.") }
} else {
setDialog({
text: window.t(
"ابتدا میبایست وارد حساب کاربری خود شوید."
),
type: "confirm",
accept: () => navigation("/login"),
open: true,
});
} }
}}
loading={userProductLoading && whichTypeAdded === "physical"}
/> />
<a
href={`https://dnvn.ir/xpdf/${book?.sampleFileId}`}
className="flex-1 border-2 border-solid text-sm border-green-500 bg-green-50 bg-opacity-70 rounded-sm font-bold text-green-700 text-center"
style={{ padding: "18px 0px" }}
>
مشاهده نمونه
</a>
</div> </div>
<div className="w-full flex flex-row justify-between items-center mt-4 gap-2"> ) : null}
{digitalProduct && digitalAvailableForSell ? (
<div className="w-full flex justify-between items-center mt-4 gap-2">
<ButtonBetween <ButtonBetween
width="72%" width="72%"
item={"خرید نسخه دیجیتال کتاب"} item={"خرید نسخه دیجیتال کتاب"}
status={separate(book?.product[0]?.price) + " " + "تومان"} status={separate(digitalProduct?.price) + " " + "تومان"}
onClick={() => onClick={() => {
userId if (userId) {
? pushToCart({ if (digitalAvailabileInCart) {
productId: book?.product[0]?.id, setDialog({
userId, text: window.t(
"این محصول قبلا به سبد خرید شما اضافه شده است."
),
type: "confirm",
accept: () => navigation("/cart"),
open: true,
});
} else {
setWhichTypeAdded("digital");
pushToCart({
productId: digitalProduct?.id,
userId: userId,
count: 1, count: 1,
}) });
: toast.info("ابتدا وارد حساب کاربری خود شوید.")
} }
} else {
setDialog({
text: window.t(
"ابتدا میبایست وارد حساب کاربری خود شوید."
),
type: "confirm",
accept: () => navigation("/login"),
open: true,
});
}
}}
loading={userProductLoading && whichTypeAdded === "digital"}
/> />
<a <a
href={`https://dnvn.ir/xpdf/${book?.sampleFileId}`} href={`https://dnvn.ir/xpdf/${book?.sampleFileId}`}
@ -134,20 +254,44 @@ export const Product = ({
مشاهده نمونه مشاهده نمونه
</a> </a>
</div> </div>
<div className="w-full flex flex-row justify-between items-center mt-4"> ) : null}
{videoProduct && videoAvailableForSell ? (
<div className="w-full flex justify-between items-center mt-4">
<ButtonBetween <ButtonBetween
width="72%" width="72%"
item={"خرید نسخه ویدئویی کتاب"} item={"خرید نسخه ویدئویی کتاب"}
status={separate(book?.product[2]?.price) + " " + "تومان"} status={separate(videoProduct?.price) + " " + "تومان"}
onClick={() => onClick={() => {
userId if (userId) {
? pushToCart({ if (videoAvailabileInCart) {
productId: book?.product[2]?.id, setDialog({
userId, text: window.t(
"این محصول قبلا به سبد خرید شما اضافه شده است."
),
type: "confirm",
accept: () => navigation("/cart"),
open: true,
});
} else {
setWhichTypeAdded("video");
pushToCart({
productId: videoProduct?.id,
userId: userId,
count: 1, count: 1,
}) });
: toast.info("ابتدا وارد حساب کاربری خود شوید.") }
} else {
setDialog({
text: window.t(
"ابتدا میبایست وارد حساب کاربری خود شوید."
),
type: "confirm",
accept: () => navigation("/login"),
open: true,
});
} }
}}
loading={userProductLoading && whichTypeAdded === "video"}
/> />
<ButtonBetween <ButtonBetween
width="25%" width="25%"
@ -155,6 +299,8 @@ export const Product = ({
onClick={() => navigation("/videos/" + book?.id)} onClick={() => navigation("/videos/" + book?.id)}
/> />
</div> </div>
) : null}
<div className="w-full flex flex-col justify-between items-center mt-8"> <div className="w-full flex flex-col justify-between items-center mt-8">
<Header title="توضیحات" link="#" /> <Header title="توضیحات" link="#" />
<p className="text-sm text-gray70 mt-2 dark:text-white leading-6"> <p className="text-sm text-gray70 mt-2 dark:text-white leading-6">
@ -170,14 +316,18 @@ export const Product = ({
</div> </div>
<div className="w-full flex flex-col justify-between items-center mt-10"> <div className="w-full flex flex-col justify-between items-center mt-10">
<Header title="امتیازات و نظرات" link="#" /> <Header title="امتیازات و نظرات" link="#" />
<Rate value={book?.rate || 0} /> <Rate
value={book?.rate || 0}
productId={physicalProduct?.id}
rateDetail={physicalProduct?.rateDetail}
/>
</div> </div>
<div <div
className="flex flex-row w-full pb-4 mt-10 no-scrollbar" className="flex w-full pb-4 mt-10 no-scrollbar"
style={{ overflowX: "scroll" }} style={{ overflowX: "scroll" }}
> >
{[0, 1, 2, 2].map((comment, index) => ( {book?.comment?.map((comment, index) => (
<Comment key={index} /> <Comment comment={comment} key={index} />
))} ))}
</div> </div>
</div> </div>
@ -196,12 +346,17 @@ const mapStateToProps = (state) => ({
isMobile: state.publicApi.isMobile, isMobile: state.publicApi.isMobile,
isDark: state.publicApi.isDark, isDark: state.publicApi.isDark,
userId: state.user.status?.id, userId: state.user.status?.id,
bookmarkLoading: state.userFavorite.loading,
availableForSell: state.config.availableForSell,
userProduct: state.userProduct.list,
userProductLoading: state.userProduct.loading,
}); });
const mapDispatchToProps = { const mapDispatchToProps = {
getInfo: book.info, getInfo: book.info,
pushToCart: userProduct.add, pushToCart: userProduct.add,
setHeaderOptions: publicApi.setHeaderOptions, setHeaderOptions: publicApi.setHeaderOptions,
setDialog: dialog.set,
}; };
export default connect(mapStateToProps, mapDispatchToProps)(Product); export default connect(mapStateToProps, mapDispatchToProps)(Product);

@ -23,6 +23,7 @@ export const Products = ({
useEffect(() => { useEffect(() => {
getList({ vod: true }); getList({ vod: true });
setHeaderOptions(headerOptions); setHeaderOptions(headerOptions);
window.scroll({top: 0, behavior : 'smooth'});
}, []); }, []);
return ( return (
@ -40,9 +41,9 @@ export const Products = ({
</div> </div>
) : ( ) : (
<div <div
className={`w-full flex flex-row gap-10 px-5 overflow-y-hidden mt-3 justify-center lg:pt-24 lg:mt-0`} className={`w-full flex gap-10 px-5 overflow-y-hidden mt-3 justify-center lg:pt-24 lg:mt-0`}
> >
<div className="w-11/12 flex flex-row gap-5 justify-end"> <div className="w-11/12 flex gap-5 justify-end">
<Sidebar /> <Sidebar />
<Main books={books} grades={grades} /> <Main books={books} grades={grades} />
</div> </div>

@ -14,6 +14,7 @@ import moment from "jalali-moment";
import dropdownIcon from "../../../../assets/icons/dropdown-blue.svg"; import dropdownIcon from "../../../../assets/icons/dropdown-blue.svg";
import Posts from "./Posts"; import Posts from "./Posts";
import Pagination from "./Pagination"; import Pagination from "./Pagination";
const num = 6;
export const Main = ({ export const Main = ({
books, books,
@ -24,18 +25,26 @@ export const Main = ({
isMobile, isMobile,
}) => { }) => {
const [filterLoading, setFilterLoading] = useState(false); const [filterLoading, setFilterLoading] = useState(false);
const [page, setPage] = useState(1);
console.log(page);
const [total, setTotal] = useState(books.length);
useEffect(() => { useEffect(() => {
setFilterLoading(() => true); // setFilterLoading(() => true);
setTimeout(() => { // setTimeout(() => {
setFilterLoading(() => false); // setFilterLoading(() => false);
}, 500); // }, 500);
setPage(1);
}, [filterOptions]); }, [filterOptions]);
useEffect(() => { useEffect(() => {
window.scrollTo(0, 0); window.scrollTo(0, 0);
}, []); }, []);
useEffect(() => {
setTotal(books.length);
}, [books]);
const Items = (type) => { const Items = (type) => {
const { grade, subject, available, sort, productType } = filterOptions; const { grade, subject, available, sort, productType } = filterOptions;
let byGradeFilter; let byGradeFilter;
@ -82,91 +91,23 @@ export const Main = ({
} else { } else {
bySortFilter = byAvailableFilter; bySortFilter = byAvailableFilter;
} }
return type === 2 console.log("render here !");
? bySortFilter?.map((item, index) => ( return bySortFilter;
<VodProduct // setTotal(bySortFilter.length);
video={item}
key={index}
index={index}
height={"calc(100vh / 5)"}
grades={grades}
/>
))
: bySortFilter?.map((product, index) => (
<>
{(productType ? productType === "کتاب دیجیتال" : true) && (
<Link
to={"/products/" + product?.id}
className="w-full lg:w-1/3 xl:w-1/4 2xl:w-1/5"
>
<Product
key={index}
product={product}
index={Number(index)}
grades={grades}
imageSize={4.5}
type={0}
/>
</Link>
)}
{(productType ? productType === "کتاب فیزیکی" : true) && (
<Link
to={"/products/" + product?.id}
className="w-full lg:w-1/3 xl:w-1/4 2xl:w-1/5"
>
<Product
key={index}
product={product}
index={Number(index)}
grades={grades}
imageSize={4.5}
type={1}
/>
</Link>
)}
</>
));
};
// pagination
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(false);
const [currentPage, setCurrentPage] = useState(1);
const [postsPerPage] = useState(10);
useEffect(() => {
const fetchPosts = async () => {
setLoading(true);
const res = await axios.get("https://jsonplaceholder.typicode.com/posts");
setPosts(res.data);
setLoading(false);
}; };
fetchPosts(); const elements = Items(1);
}, []); const vods = Items(2);
console.log(elements.length);
// get current post
const indexOfLastPost = currentPage * postsPerPage;
const indexOfFirstPost = indexOfLastPost - postsPerPage;
const currentPosts = posts.slice(indexOfFirstPost, indexOfLastPost);
// change page const lastPage = Math.floor((elements.length - 1) / num) + 1;
const paginate = (pageNumber) => setCurrentPage(pageNumber); const pages = lastPage > 1 ? [...Array(lastPage)].map((e, i) => i + 1) : [];
return ( return (
<div <div
className="flex flex-col w-3/4 pb-20 min-h-screen" className="flex flex-col w-3/4 pb-20 min-h-screen"
style={{ minWidth: "calc(100% * 3 / 4)" }} style={{ minWidth: "calc(100% * 3 / 4)" }}
> >
<div className="bg-red-400 ">
<h1 className="mb-5">My Blog</h1>
<Posts posts={currentPosts} loading={loading} />
<Pagination
postsPerPage={postsPerPage}
totalPosts={posts.length}
paginate={paginate}
/>
</div>
<div className="flex w-full bg-blue rounded-lg border border-solid border-gray-200 p-2 items-center my-1.5 justify-center text-blue52"> <div className="flex w-full bg-blue rounded-lg border border-solid border-gray-200 p-2 items-center my-1.5 justify-center text-blue52">
<div className="flex text-sm items-center mr-2 ml-4"> <div className="flex text-sm items-center mr-2 ml-4">
<svg <svg
@ -258,6 +199,7 @@ export const Main = ({
<Loading size={4} color="bg-green-400" /> <Loading size={4} color="bg-green-400" />
</div> </div>
)} )}
{books.length > 0 && ( {books.length > 0 && (
<div className="relative w-full mt-7 " style={{ direction: "ltr" }}> <div className="relative w-full mt-7 " style={{ direction: "ltr" }}>
<Carousel <Carousel
@ -293,12 +235,46 @@ export const Main = ({
/> />
} }
> >
{Items(2)} {vods.map((item, index) => (
<VodProduct
video={item}
key={index}
index={index}
height={"calc(100vh / 5)"}
grades={grades}
/>
))}
</Carousel> </Carousel>
</div> </div>
)} )}
<div className="w-full flex flex-row flex-wrap mt-0 border-t-2 border-solid border-gray-100 overflow-y-hidden gap-4 justify-evenly pt-3">
{Items(1)} <div className="w-full flex flex-wrap mt-0 border-t-2 border-solid border-gray-100 overflow-y-hidden gap-4 justify-evenly pt-3">
{elements
?.slice((page - 1) * num, page * num)
.map((product, index) => (
<Product
key={index}
product={product}
index={Number(index)}
grades={grades}
imageSize={4.5}
type={0}
/>
))}
{/* pagination */}
<div className="w-full flex justify-center gap-x-2">
{pages.map((e) => (
<div
className={`w-8 p-2 text-sm text-center rounded-md text-green7B cursor-pointer transform translate ${
page === true ? "bg-red-400" : "bg-blue-600"
}`}
onClick={() => setPage(e)}
>
{e}
</div>
))}
</div>
</div> </div>
</div> </div>
</div> </div>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save