Commit 978f65f9 by Ravindra Kanojiya

updated listing filter

1 parent e5c83327
...@@ -30,7 +30,7 @@ const LetDiscover = ({ categories }) => { ...@@ -30,7 +30,7 @@ const LetDiscover = ({ categories }) => {
</div> </div>
</motion.div> </motion.div>
<div className="view-all-btn"> <div className="view-all-btn">
<Button variant="primary">View All</Button> <Button href="/listing" variant="primary">View All</Button>
</div> </div>
</div> </div>
</div> </div>
......
import Image from "next/image"; import Image from "next/image";
import React from "react"; import React, { useState } from "react";
import {fadeIn, zoomIn, slideFromLeft, slideFromRight } from "../animationvariants.js"; import { fadeIn, zoomIn, slideFromLeft, slideFromRight } from "../animationvariants.js";
import { Button } from "react-bootstrap"; import { Button } from "react-bootstrap";
import { Swiper, SwiperSlide } from "swiper/react"; import { Swiper, SwiperSlide } from "swiper/react";
...@@ -12,6 +12,16 @@ import "swiper/css"; ...@@ -12,6 +12,16 @@ import "swiper/css";
import "swiper/css/pagination"; import "swiper/css/pagination";
import "swiper/css/navigation"; import "swiper/css/navigation";
const LetDiscover = () => { const LetDiscover = () => {
const [activeIndex, setActiveIndex] = useState(null);
const handleTitleClick = (index) => {
// Check if the clicked index is already active
if (activeIndex === index) {
return; // Do nothing if it's already active
}
// Toggle the active index if it's different from the clicked index
setActiveIndex(index);
};
const letDiscoverData = [ const letDiscoverData = [
{ {
image: "/images/discover/01.png", image: "/images/discover/01.png",
...@@ -54,6 +64,39 @@ const LetDiscover = () => { ...@@ -54,6 +64,39 @@ const LetDiscover = () => {
title: "Wellness" title: "Wellness"
} }
]; ];
const [showCloseIcon, setShowCloseIcon] = useState({});
const handleToggleCloseIcon = index => {
setShowCloseIcon(prevShowCloseIcon => ({
...prevShowCloseIcon,
[index]: !prevShowCloseIcon[index]
}));
};
const subCategoriesData = [
{
name: "Boat"
},
{
name: "Games"
},
{
name: "Helicopter"
},
{
name: "Ice-skating"
},
{
name: "Jet-skiing"
},
{
name: "Kayaking"
},
{
name: "Park"
},
{
name: "Rooftop"
}
];
return ( return (
<> <>
<section className="let-discover-session let-discover-listing-session"> <section className="let-discover-session let-discover-listing-session">
...@@ -64,13 +107,12 @@ const LetDiscover = () => { ...@@ -64,13 +107,12 @@ const LetDiscover = () => {
your text or div will come here your text or div will come here
</motion.div> */} </motion.div> */}
<div className="head-btn"> <div className="head-btn">
<motion.div variants={slideFromRight(0.4)} initial={"hidden"} whileInView={"show"} viewport={{ once: false, amount: 0.2 }}> <motion.div variants={slideFromRight(0.4)} initial={"hidden"} whileInView={"show"} viewport={{ once: false, amount: 0.2 }}>
<div className="head01"> <div className="head01">
<div className="title">Lets </div> <div className="title">Lets </div>
<h2>Discover</h2> <h2>Discover</h2>
</div> </div>
</motion.div> </motion.div>
</div> </div>
</div> </div>
</div> </div>
...@@ -104,21 +146,18 @@ const LetDiscover = () => { ...@@ -104,21 +146,18 @@ const LetDiscover = () => {
> >
{letDiscoverData && {letDiscoverData &&
letDiscoverData.map((data, index) => { letDiscoverData.map((data, index) => {
const isActive = activeIndex === index;
return ( return (
<SwiperSlide> <SwiperSlide>
<motion.div <motion.div variants={zoomIn("left", 0.3)} initial={"hidden"} whileInView={"show"} viewport={{ once: false, amount: 0.2 }}>
variants={zoomIn("left", 0.3)} <a className={isActive ? "active" : ""}
initial={"hidden"} onClick={() => handleTitleClick(index)}>
whileInView={"show"} <span className="image-container">
viewport={{ once: false, amount: 0.2 }} <Image layout="fill" alt="" className="image img-fluid" src={data.image} />
> </span>
<a href=""> <div className="title">{data.title}</div>
<span className="image-container"> </a>
<Image layout="fill" alt="" className="image img-fluid" src={data.image} /> </motion.div>
</span>
<div className="title">{data.title}</div>
</a>
</motion.div>
</SwiperSlide> </SwiperSlide>
); );
})} })}
...@@ -140,6 +179,23 @@ const LetDiscover = () => { ...@@ -140,6 +179,23 @@ const LetDiscover = () => {
</div> </div>
</div> </div>
</div> </div>
<div className="row">
<div className="col-12">
<div className="sub-categories">
{subCategoriesData &&
subCategoriesData.map((data, index) => (
<a key={index} onClick={() => handleToggleCloseIcon(index)}>
<span>{data.name}</span>
{showCloseIcon[index] && (
<span className="image-container">
<Image layout="fill" alt="image" className="image" src="/images/icons/close-button.svg" />
</span>
)}
</a>
))}
</div>
</div>
</div>
</div> </div>
</section> </section>
</> </>
......
...@@ -2,13 +2,17 @@ import React, { Fragment } from "react"; ...@@ -2,13 +2,17 @@ import React, { Fragment } from "react";
import ListingInner from "./ListingInner"; import ListingInner from "./ListingInner";
import SignUpToExperienceOurPlatform from "../home/SignUpToExperienceOurPlatform"; import SignUpToExperienceOurPlatform from "../home/SignUpToExperienceOurPlatform";
import LetDiscover from "./LetDiscover"; import LetDiscover from "./LetDiscover";
import { useSelector } from "react-redux";
const Listing = () => { const Listing = () => {
const { allActivitiesData } = useSelector(sate => sate.allActivitiesData);
console.log("allActivitiesData >>>> 123", allActivitiesData)
return ( return (
<Fragment> <Fragment>
<main> <main>
<LetDiscover /> <LetDiscover />
<ListingInner /> <ListingInner allActivitiesData={allActivitiesData} />
<SignUpToExperienceOurPlatform /> <SignUpToExperienceOurPlatform />
</main> </main>
</Fragment> </Fragment>
......
import Image from "next/image"; import Image from "next/image";
import React, { useState } from "react"; import React, { useState } from "react";
import { Accordion, Form } from "react-bootstrap"; import { Accordion, Form } from "react-bootstrap";
// import upArrow from "./assets/up-arrow.png"; import { Slider } from "antd";
// import downArrow from "./assets/down-arrow.png"; import { DatePicker, Space } from "antd";
import upArrow from "../../public/images/icons/up-s.svg";
// import downArrow from "../images/icons/down-s.svg";
import downArrow from "../../public/images/icons/down-s.svg";
const ListingFilter = () => { const ListingFilter = () => {
const [showContent, setShowContent] = useState(false); const [showContent, setShowContent] = useState(false);
...@@ -14,7 +10,9 @@ const ListingFilter = () => { ...@@ -14,7 +10,9 @@ const ListingFilter = () => {
const toggleContent = () => { const toggleContent = () => {
setShowContent(!showContent); setShowContent(!showContent);
}; };
const onChange = (date, dateString) => {
console.log(date, dateString);
};
return ( return (
<> <>
<div className="listing-filter"> <div className="listing-filter">
...@@ -36,9 +34,26 @@ const ListingFilter = () => { ...@@ -36,9 +34,26 @@ const ListingFilter = () => {
<div className="head">Your Budget</div> <div className="head">Your Budget</div>
</div> </div>
<div className="inner"> <div className="inner">
<div className="price">$200 - $5000+</div> <div className="price">
$200 - $5000+ <span className="sub-text">Average price is $5000</span>
</div>
<div className="graph"> <div className="graph">
<img className="img-fluid w-100" src="/images/buget.svg" /> <Slider
range={{
draggableTrack: true
}}
defaultValue={[200, 5000]}
min={200}
max={5000}
tooltip={{
open: true
}}
/>
<div className="graph-price">
<div className="min">$200</div>
<div className="min">$5000</div>
</div>
{/* <img className="img-fluid w-100" src="/images/buget.svg" /> */}
</div> </div>
</div> </div>
</div> </div>
...@@ -253,7 +268,7 @@ const ListingFilter = () => { ...@@ -253,7 +268,7 @@ const ListingFilter = () => {
</div> </div>
</div> </div>
</div> </div>
<div className="box-01"> {/* <div className="box-01">
<div className="p-all"> <div className="p-all">
<div className="head">Rating:</div> <div className="head">Rating:</div>
</div> </div>
...@@ -274,8 +289,8 @@ const ListingFilter = () => { ...@@ -274,8 +289,8 @@ const ListingFilter = () => {
</label> </label>
</div> </div>
</div> </div>
</div> </div> */}
<div className="box-01"> {/* <div className="box-01">
<div className="p-all"> <div className="p-all">
<div className="head">Months:</div> <div className="head">Months:</div>
</div> </div>
...@@ -289,8 +304,8 @@ const ListingFilter = () => { ...@@ -289,8 +304,8 @@ const ListingFilter = () => {
</Form.Select> </Form.Select>
</div> </div>
</div> </div>
</div> </div> */}
<div className="box-01"> {/* <div className="box-01">
<div className="p-all"> <div className="p-all">
<div className="head">Days</div> <div className="head">Days</div>
</div> </div>
...@@ -311,6 +326,27 @@ const ListingFilter = () => { ...@@ -311,6 +326,27 @@ const ListingFilter = () => {
</label> </label>
</div> </div>
</div> </div>
</div> */}
<div className="box-01">
<div className="p-all">
<div className="head">Date</div>
</div>
<div className="inner">
<div className="row">
<div className="col-6">
<div>From</div>
<Space direction="vertical">
<DatePicker onChange={onChange} />
</Space>
</div>
<div className="col-6">
<div>To</div>
<Space direction="vertical">
<DatePicker onChange={onChange} />
</Space>
</div>
</div>
</div>
</div> </div>
<div className="box-01"> <div className="box-01">
<div className="p-all"> <div className="p-all">
......
...@@ -3,11 +3,12 @@ import ListingFilter from "./ListingFilter"; ...@@ -3,11 +3,12 @@ import ListingFilter from "./ListingFilter";
import ListingItems from "./ListingItems"; import ListingItems from "./ListingItems";
import Image from "next/image"; import Image from "next/image";
const ListingInner = () => { const ListingInner = ({allActivitiesData}) => {
console.log("allActivitiesData >>>>>", allActivitiesData)
const [isFilterViewOpen, setIsFilterViewOpen] = useState(false); const [isFilterViewOpen, setIsFilterViewOpen] = useState(false);
const [isGridViewOpen, setIsGridViewOpen] = useState(false); const [isGridViewOpen, setIsGridViewOpen] = useState(false);
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
const [size, setSize] = useState(768); const [size, setSize] = useState(768);
const toggleGridViewDropdown = () => { const toggleGridViewDropdown = () => {
setIsGridViewOpen(!isGridViewOpen); setIsGridViewOpen(!isGridViewOpen);
...@@ -35,15 +36,18 @@ const ListingInner = () => { ...@@ -35,15 +36,18 @@ const ListingInner = () => {
window.removeEventListener("resize", handleResize); window.removeEventListener("resize", handleResize);
}; };
}, []); }, []);
return ( return (
<> <>
<section className="listing-inner-session"> <section className="listing-inner-session">
<div className="container-fluid"> <div className="container-fluid">
<div className="row"> <div className="row">
<div className="col-12"> <div className="col-12">
<div className="filter-dd"> <div className="filter-dd">
<div className="filter-view box-inner"> <div className="filter-view box-inner">
<a onClick={toggleFilterViewDropdown}> <a onClick={toggleFilterViewDropdown}>
<span className="image-container"> <span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/icons/filter-view.svg" /> <Image layout="fill" alt="" className="image img-fluid" src="/images/icons/filter-view.svg" />
...@@ -133,20 +137,19 @@ const ListingInner = () => { ...@@ -133,20 +137,19 @@ const ListingInner = () => {
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div className="row "> <div className="row ">
{ (isFilterViewOpen || size > 768) && ( {(isFilterViewOpen || size > 768) && (
<> <>
<div className={`col-md-3 first-block-content ${isFilterViewOpen ? "show" : ""}`}> <div className={`col-md-3 first-block-content ${isFilterViewOpen ? "show" : ""}`}>
<ListingFilter /> <ListingFilter />
</div> </div>
</> </>
)} )}
<div className="col-md-9"> <div className="col-md-9">
<ListingItems /> <ListingItems allActivitiesData={allActivitiesData} />
</div> </div>
</div> </div>
</div> </div>
......
import Image from "next/image"; import Image from "next/image";
import React from "react"; import React from "react";
import { Button } from "react-bootstrap"; import { Button } from "react-bootstrap";
import { cleanImage } from "../../services/imageHandling";
const ListingItems = () => { const ListingItems = ({allActivitiesData}) => {
const ListingData = [ console.log("allActivitiesData",allActivitiesData )
{
image: "/images/Browse-Experiences/01.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees"
},
{
image: "/images/Browse-Experiences/02.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees"
},
{
image: "/images/Browse-Experiences/03.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees"
},
{
image: "/images/Browse-Experiences/04.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees"
},
{
image: "/images/Browse-Experiences/01.png",
topRated: "Top Rated",
title: "City Climb",
discription: "Lorem ipsum dolor sit amet, consectetur adipiscing elit,",
price: "200",
offPrice: "40%",
days: "For 1 Night",
taxes: "Includes taxes & Fees"
}
];
return ( return (
<> <>
<div className="listing-items"> <div className="listing-items">
<div className="row"> <div className="row">
{ListingData && {allActivitiesData.data &&
ListingData.map(data => { allActivitiesData.data.map(data => {
return ( return (
<div className="col-md-3"> <div className="col-md-3">
<div className="item"> <div className="item">
<div className="browse-experiences-item"> <div className="browse-experiences-item">
<div className="img-wrapper"> <div className="img-wrapper">
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src={data.image} />
</span>
<div className="top-rated">{data.topRated}</div>
</div>
<div className="info">
<div className="top-name">
<div className="title">{data.title}</div>
<div className="rating-wishlist">
<div className="rating">
8.8
<span className="image-container"> <span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/icons/star.svg" /> <Image layout="fill" alt="" className="image img-fluid" src={cleanImage(data.attributes?.image?.data?.attributes)} />
</span> </span>
<div className="top-rated">Top Rated</div>
</div> </div>
<div className="wishlist"> <div className="info">
<span className="image-container"> <div className="top-name">
<Image layout="fill" alt="" className="image img-fluid" src="/images/icons/wishlist.svg" /> <div className="title">{data?.attributes?.name}</div>
</span> <div className="rating-wishlist">
<div className="rating">
{data?.attributes?.rating}
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/icons/star.svg" />
</span>
</div>
<div className="wishlist">
<span className="image-container">
<Image layout="fill" alt="" className="image img-fluid" src="/images/icons/wishlist.svg" />
</span>
</div>
</div>
</div>
<div className="discription">
{data.discription} <a href="">Read More</a>
</div>
<div className="price">
${data?.attributes?.pricePerPerson} <span className="off">{data?.attributes?.off}% OFF</span>
</div>
<div className="detail">
<div className="">For 1 Night</div>
<div className="">Includes taxes & Fees</div>
</div>
<div className="explore-now">
<Button href="/listing" variant="primary">Explore Now</Button>
</div>
</div> </div>
</div> </div>
</div>
<div className="discription">
{data.discription} <a href="">Read More</a>
</div>
<div className="price">
${data.price} <span className="off">{data.offPrice} OFF</span>
</div>
<div className="detail">
<div className="">{data.days}</div>
<div className="">{data.taxes}</div>
</div>
<div className="explore-now">
<Button href="/detail" variant="primary">Explore Now</Button>
</div>
</div>
</div>
</div> </div>
</div> </div>
); );
......
import Home from "../components/home/Home";
import Layout from "../components/layout/Layout"; import Layout from "../components/layout/Layout";
import Listing from "../components/listing/Listing"; import Listing from "../components/listing/Listing";
import { getActivitiesByVendor } from "../redux/actions/activityAction";
import { wrapper } from "../redux/store"; import { wrapper } from "../redux/store";
export default function ListingPage() { export default function ListingPage() {
...@@ -22,13 +22,20 @@ export default function ListingPage() { ...@@ -22,13 +22,20 @@ export default function ListingPage() {
/** For server side rendering */ /** For server side rendering */
export const getStaticProps = wrapper.getStaticProps(store => async ({ req, query }) => { export const getStaticProps = wrapper.getStaticProps(store => async ({ req, query }) => {
// Get the menu data. try {
await store.dispatch(getActivitiesByVendor())
// get the locations data.
return { return {
props: {}, props: {},
// Next.js will attempt to re-generate the page:
// - Any requests to the page after the initial request and before 10 seconds are also cached and instantaneous.
// - After the 10-second window, the next request will still show the cached (stale) page
// - Next.js triggers a regeneration of the page in the background.
// - Once the page generates successfully, Next.js will invalidate the cache and show the updated page. If the background regeneration fails, the old page would still be unaltered.
// In seconds
// revalidate: Number(process.env.NEXT_PUBLIC_ISR_REVALIDATE_AFTER)
}; };
} catch (error) {
console.log("index.js", error);
}
}); });
<svg width="23" height="23" xmlns="http://www.w3.org/2000/svg"><g transform="rotate(45 19.63172804 8.13172796)" fill="none" fill-rule="evenodd"><circle fill="#1E1D24" transform="rotate(45 16.263456 16.263456)" cx="16.263456" cy="16.263456" r="11.5"/><path stroke="#FCFCFF" stroke-width="2" stroke-linecap="round" d="M16.263456 11.663456v9.2M20.863456 16.263456h-9.2"/></g></svg>
...@@ -1832,8 +1832,9 @@ span.form-error, ...@@ -1832,8 +1832,9 @@ span.form-error,
/*--------------------------*/ /*--------------------------*/
.let-discover-carousal a { .let-discover-carousal a {
color: #000; color: #808080;
text-align: center; text-align: center;
cursor: pointer;
} }
.let-discover-carousal a .image{ .let-discover-carousal a .image{
padding: 0.2rem !important; padding: 0.2rem !important;
...@@ -1842,7 +1843,12 @@ span.form-error, ...@@ -1842,7 +1843,12 @@ span.form-error,
.let-discover-carousal a .title { .let-discover-carousal a .title {
padding: 1rem; padding: 1rem;
} }
.let-discover-carousal a.active{
color: #000;
}
.let-discover-carousal a.active .title{
text-decoration: underline;
}
.carousal-c { .carousal-c {
padding: 0 4rem; padding: 0 4rem;
} }
...@@ -2735,6 +2741,72 @@ footer hr { ...@@ -2735,6 +2741,72 @@ footer hr {
width: 33px !important; width: 33px !important;
height: 33px !important; height: 33px !important;
} }
.sub-categories{
display: flex;
align-items: center;
}
.sub-categories a{
cursor: pointer;
display: flex;
align-items: center;
justify-content: space-between;
margin-left: 1rem;
border: 1px solid #000;
border-radius: 2rem;
height: 2.5rem;
padding-left: 1.5rem;
padding-right: 1.5rem;
transition-property: all;
transition-timing-function: cubic-bezier(.4,0,.2,1);
transition-duration: .15s;
}
.sub-categories a .image-container{
width: 20px;
display: inline-block;
margin-left: 0.5rem;
margin-right: -0.8rem;
}
.graph{
padding-top: 3rem;
}
.graph .graph-price{
display: flex;
align-items: center;
justify-content: space-between;
color: #808080;
}
:where(.css-dev-only-do-not-override-1kuana8).ant-tooltip .ant-tooltip-inner {
padding: 5px 8px;
color: #808080;
background-color: transparent;
}
:where(.css-dev-only-do-not-override-1kuana8).ant-tooltip .ant-tooltip-arrow:before {
background: transparent;
}
:where(.css-dev-only-do-not-override-1kuana8).ant-tooltip .ant-tooltip-arrow::after {
box-shadow: 1px 1px 6px #c1c1c1;
}
.graph :where(.css-dev-only-do-not-override-1kuana8).ant-slider:hover .ant-slider-track {
background-color: #0070BD;
}
.graph :where(.css-dev-only-do-not-override-1kuana8).ant-slider .ant-slider-handle::after {
background-color: #0070BD;
box-shadow: 0 0 0 2px #0070BD;
}
.graph :where(.css-dev-only-do-not-override-1kuana8).ant-slider .ant-slider-rail {
background-color: #A1A1A1;
}
.graph :where(.css-dev-only-do-not-override-1kuana8).ant-slider .ant-slider-track {
background-color: #0070BD;
}
.box-01 .inner .price .sub-text{
color: #D1D1D1;
}
@media (min-width: 992px) { @media (min-width: 992px) {
.navbar-expand-lg .navbar-nav .nav-link { .navbar-expand-lg .navbar-nav .nav-link {
margin: 0 2rem; margin: 0 2rem;
......
Styling with Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!