reza added global Search

temp
Reza_ashrafi 3 years ago
parent adc8846aa3
commit 4523580573
  1. 113
      src/components/Navbar/SearchResult/index.js
  2. 56
      src/components/Navbar/index.js
  3. 5
      src/components/Search/index.js
  4. 45
      src/views/Home/Desktop/Part4/index.js

@ -0,0 +1,113 @@
import React, { useEffect, useState } from "react";
import { connect } from "react-redux";
import { Link } from "react-router-dom";
const Pages = [
{
strings : 'خانه - home - Home - Landing - landing', link : '/', name : 'خانه'
},
{
strings : 'ورود - ثبت نام - لاگین - login - Login', link : '/signup', name : 'ورود یا ثبت نام'
},
{
strings : 'کتاب - محصول - ویدئو - book - video - books - videos - خرید - ریاضی - علوم - شیمی - زیست - محصولات - ویدئوها - کتابها', link : '/products', name : 'محصولات'
},
{
strings : 'آدرس - شماره تماس - ارتباط با ما - نقشه - تیکت - شکایت - address - map - phone number - contact us', link : '/contact-us', name : 'ارتباط با ما'
},
]
export const SearchResult = ({ text, books, setText }) => {
const [relatedBooks, setRelatedBooks] = useState([]);
const [relatedPages, setRelatedPages] = useState([]);
useEffect(() => {
if (text && books.length > 0) {
let list = books.filter(
(book) =>
book.product[0].name.indexOf(text) !== -1 ||
book.product[1].name.indexOf(text) !== -1
);
let pages = Pages.filter((page) => page.strings.indexOf(text) !== -1);
setRelatedPages(pages);
setRelatedBooks(list);
}
}, [text]);
return (
<div
className="w-full list-none relative"
// style={{ height: 300 }}
>
<div
onClick={(e) => e.stopPropagation()}
className="absolute -top-1 w-full left-0 px-6 pt-5 bg-white pb-5 shadow-lg rounded-md flex flex-col overflow-y-scroll"
style={{ maxHeight: "calc(100vh / 1.5)", direction : 'ltr' }}
>
<header className="w-full flex flex-row-reverse items-center gap-4">
<strong className="text-greenBA font-normal text-sm">محصولات</strong>
<span
className="flex-1 bg-greenBA bg-opacity-30"
style={{ height: 1 }}
></span>
</header>
{relatedBooks.length > 0 ? (
<ul className="list-none p-0 m-0 mt-4 flex flex-col gap-3 divide-solid divide-y divide-gray-200">
{relatedBooks.map((book, index) => (
<Link
to={"/products/" + book.id}
className="flex flex-row-reverse w-full gap-4 items-center"
ley={index}
onClick={() => setText(null)}
>
<img
style={{
height: "calc(100vh / 17)",
width: "calc(100vh / 17 * 2 / 3)",
}}
className="rounded-sm"
src={`https://dnvn.ir/api/v1/file/${book.fileIds}`}
alt=""
></img>
<strong className="text-sm pt-2 text-blueC0 font-semibold">
{book.product[1].name}
</strong>
</Link>
))}
</ul>
) : <span style={{direction: "rtl"}} className="text-blueC0 text-sm text-right py-4 font-semibold">هیچ محصولی یافت نشد.</span>}
<header className="w-full flex flex-row-reverse items-center gap-4 mt-5">
<strong className="text-greenBA font-normal text-sm">صفحات</strong>
<span
className="flex-1 bg-greenBA bg-opacity-30"
style={{ height: 1 }}
></span>
</header>
{relatedPages.length > 0 ? (
<ul className="list-none p-0 m-0 mt-4 flex flex-col gap-3 divide-solid divide-y divide-gray-200">
{relatedPages.map((page, index) => (
<Link
to={page.link}
className="flex flex-row-reverse w-full gap-4 items-center text-green-800 text-tiny font-semibold underline"
ley={index}
onClick={() => setText(null)}
>
{page.name}
</Link>
))}
</ul>
) : <span style={{direction: "rtl"}} className="text-blueC0 text-sm text-right py-4 font-semibold">هیچ محصولی یافت نشد.</span>}
</div>
</div>
);
};
const mapStateToProps = (state) => ({
books: state.book.list,
});
const mapDispatchToProps = {};
export default connect(mapStateToProps, mapDispatchToProps)(SearchResult);

@ -1,10 +1,11 @@
import React, { useEffect, useState } from "react"; import React, { useEffect, useState } from "react";
import { Link, useNavigate } from "react-router-dom"; import { Link, useNavigate } from "react-router-dom";
import { connect } from "react-redux"; import { connect } from "react-redux";
import {publicApi} from "../../redux/actions"; import { userProduct } from "../../redux/actions";
import _ from "lodash"; import _ from "lodash";
import Drawer from "../Drawer"; import Drawer from "../Drawer";
import Search from "../Search"; import Search from "../Search";
import SearchResult from "./SearchResult";
//assets //assets
import cartIcon from "./cart-blue.svg"; import cartIcon from "./cart-blue.svg";
// import whiteCartIcon from "./white-cart-icon.svg"; // import whiteCartIcon from "./white-cart-icon.svg";
@ -31,6 +32,8 @@ 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";
function Navbar({ function Navbar({
getCartProducts,
cartProductsLength,
pages, pages,
isDark, isDark,
isMobile, isMobile,
@ -50,12 +53,12 @@ function Navbar({
headerOptions; headerOptions;
const [top, setTop] = useState(false); const [top, setTop] = useState(false);
const [search, setSearch] = useState(null);
const [drawerOpen, setDrawerOpen] = useState(false); const [drawerOpen, setDrawerOpen] = useState(false);
const [desktopMiddleFix, setDesktopMiddleFix] = useState(false); const [desktopMiddleFix, setDesktopMiddleFix] = useState(false);
const [desktopEndTransform, setDesktopEndTransform] = useState(false); const [desktopEndTransform, setDesktopEndTransform] = useState(false);
useEffect(() => { useEffect(() => {
var lastScroll = window.scrollY;
if (window.scrollY === 0) { if (window.scrollY === 0) {
setTop(() => true); setTop(() => true);
} }
@ -68,25 +71,13 @@ function Navbar({
} }
}); });
} }
if (!isMobile) {
window.addEventListener("scroll", () => {
if (window.scrollY >= 64) {
setDesktopMiddleFix(() => true);
} else {
setDesktopMiddleFix(() => false);
}
if (window.scrollY > lastScroll && window.scrollY >= 90) {
setDesktopEndTransform(() => true);
} else {
setDesktopEndTransform(() => false);
}
lastScroll = window.scrollY;
});
}
}, []); }, []);
useEffect(() => {
if (!isMobile && isLogin) {
getCartProducts();
}
}, [isLogin]);
return isMobile ? ( return isMobile ? (
<div <div
className={_.join( className={_.join(
@ -241,7 +232,7 @@ function Navbar({
<Link to="/" className="flex flex-row items-center"> <Link to="/" className="flex flex-row items-center">
<img src={logoIcon} className="w-6" /> <img src={logoIcon} className="w-6" />
<span <span
className={`text-base font-bold text-3xl text-blue52 transform translate-y-1 mr-2`} className={`font-bold text-3xl text-blue52 transform translate-y-1 mr-2`}
> >
دانوین دانوین
</span> </span>
@ -252,20 +243,25 @@ function Navbar({
style={{ maxWidth: "calc(100vw / 2)" }} style={{ maxWidth: "calc(100vw / 2)" }}
></div> ></div>
<div <div
className="flex w-full absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2" className="flex flex-col w-full absolute left-1/2 top-1/2 transform -translate-x-1/2 -translate-y-1/2"
style={{ maxWidth: "calc(100vw / 3)" }} style={{ maxWidth: "calc(100vw / 3)" }}
> >
<Search /> <Search onChange={(val) => setSearch(val)} />
{search && <SearchResult text={search} setText={setSearch} />}
</div> </div>
{isLogin && (
<div className="flex justify-end items-center gap-4"> <div className="flex justify-end items-center gap-4">
<Link to="/cart"> <Link to="/cart" className="relative">
<img src={cartIcon} alt="" className="w-9" /> <img src={cartIcon} alt="" className="w-11" />
<span className="absolute -right-2 -top-0.5 w-6 h-6 flex justify-center items-center bg-blue-500 bg-opacity-90 rounded-full text-white text-tiny">
{cartProductsLength}
</span>
</Link> </Link>
{/* <img src={whiteCartIcon} alt="" className="w-5 h-5 ml-2" /> */} {/* <img src={whiteCartIcon} alt="" className="w-5 h-5 ml-2" /> */}
{/* <img src={searchIcon} alt="" className="w-5 h-5 ml-2" /> */} {/* <img src={searchIcon} alt="" className="w-5 h-5 ml-2" /> */}
{/* <img src={profileIcon} alt="" className="w-5 h-5" /> */} {/* <img src={profileIcon} alt="" className="w-5 h-5" /> */}
</div> </div>
)}
</div> </div>
<div <div
@ -286,9 +282,7 @@ function Navbar({
/> />
{/* <img src={whiteHamburgerMenu} alt="" className="w-3 h-3" /> */} {/* <img src={whiteHamburgerMenu} alt="" className="w-3 h-3" /> */}
<span className={`text-sm text-blue52 ${productCategoryTextColor}`}> <span className={`text-sm text-blue52 ${productCategoryTextColor}`}>
دسته بندی کالاها دسته بندی کالاها &nbsp;&nbsp;
&nbsp;&nbsp;
</span> </span>
</div> </div>
<div <div
@ -326,10 +320,14 @@ const mapStateToProps = (state) => ({
isMobile: state.publicApi.isMobile, isMobile: state.publicApi.isMobile,
headerOptions: state.publicApi.headerOptions, headerOptions: state.publicApi.headerOptions,
isLogin: state.user.status, isLogin: state.user.status,
cartProductsLength: state.userProduct.list?.length,
}); });
const mapDispatchToProps = {
getCartProducts: userProduct.list,
};
export default connect(mapStateToProps)(Navbar); export default connect(mapStateToProps, mapDispatchToProps)(Navbar);
Navbar.defaultProps = { Navbar.defaultProps = {
pages: [ pages: [

@ -20,10 +20,11 @@ export default function Search(props) {
</span> </span>
<input <input
type="search" type="search"
name="q" name={props.name}
className="w-full py-3 text-sm text-white border border-solid border-gray-200 rounded-md pr-5 pl-14 outline-none focus:ring-1 focus:text-gray-900 " className="w-full py-3 text-sm lg:text-tiny lg:font-semibold text-gray1 border border-solid border-gray-200 rounded-md pr-5 pl-14 outline-none focus:ring-1 focus:text-gray-900 "
placeholder={_.join([langDetector(props.lang , "جستجو...", "Search...")], " ")} placeholder={_.join([langDetector(props.lang , "جستجو...", "Search...")], " ")}
autoComplete="off" autoComplete="off"
onChange={(e) => props.onChange(e.target.value)}
/> />
</div> </div>
</div> </div>

@ -2,7 +2,7 @@ import React from "react";
import Button from "../../../../components/Button"; import Button from "../../../../components/Button";
import VodProduct from "../../../../components/VodProduct"; import VodProduct from "../../../../components/VodProduct";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import posterImage from '../../../../assets/images/poster.svg' import posterImage from "../../../../assets/images/poster.svg";
const Part4 = () => { const Part4 = () => {
const videosData = [ const videosData = [
{ {
@ -52,19 +52,18 @@ const Part4 = () => {
grade: "پایه چهارم", grade: "پایه چهارم",
imageUrl: "https://dnvn.ir/api/v1/file/2105", imageUrl: "https://dnvn.ir/api/v1/file/2105",
poster: posterImage, poster: posterImage,
} },
]; ];
return <div className="w-full my-6" > return (
<div className="w-full my-6">
<div className="w-full flex justify-between items-center"> <div className="w-full flex justify-between items-center">
<div className="flex items-center text-4xl font-black text-blue52"> <div className="flex items-center text-4xl font-black text-blue52">
<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>
<h1> <h1>جدیدترین دوره های ویدیویی</h1>
جدیدترین دوره های ویدیویی
</h1>
</div> </div>
<div> <div>
<Link to='/products'> <Link to="/products">
<Button <Button
title="مشاهده لیست محصولات" title="مشاهده لیست محصولات"
backgroundColor="bg-blue-100" backgroundColor="bg-blue-100"
@ -74,8 +73,7 @@ const Part4 = () => {
}} }}
width="100%" width="100%"
selectable={true} selectable={true}
color="text-blueC0"
color= "text-blueC0"
onClick={() => null} onClick={() => null}
radius={false} radius={false}
twPaddings="py-4 px-12" twPaddings="py-4 px-12"
@ -83,18 +81,19 @@ const Part4 = () => {
</Link> </Link>
</div> </div>
</div> </div>
<ul className="py-6 my-10 border-t border-b border-solid border-gray-200 justify-center" style={{}}> <ul
className="py-6 my-10 border-t border-b border-solid border-gray-200 justify-center"
style={{}}
>
<ul className="flex flex-wrap justify-center "> <ul className="flex flex-wrap justify-center ">
{ {videosData.slice(0, 6).map((video, index) => (
videosData.slice(0,6).map((video, index) => ( <li
<li className={`flex flex-col border-solid border-gray-200 ${index != 3 && index != 4 && index != 5 ? 'border-b' : null} video ${index != 0 && index != 3 ?'border-r' : null}`} className={`flex flex-col border-solid border-gray-200 ${
style={{width: '33.333333%',}}> index != 3 && index != 4 && index != 5 ? "border-b" : null
<Link } video ${index != 0 && index != 3 ? "border-r" : null}`}
to={"/videos/" + video.id} style={{ width: "33.333333%" }}
> >
<Link to={"/videos/" + video.id}>
<VodProduct <VodProduct
productTitle={`دوره ی ویدیویی ${video.name}`} productTitle={`دوره ی ویدیویی ${video.name}`}
productCat={video.grade} productCat={video.grade}
@ -107,13 +106,11 @@ const Part4 = () => {
/> />
</Link> </Link>
</li> </li>
)) ))}
}
</ul> </ul>
</ul> </ul>
</div> </div>
} );
};
export default Part4; export default Part4;
Loading…
Cancel
Save