From def62d4215736cee3b7ae8b7e93af583611c1453 Mon Sep 17 00:00:00 2001 From: zojgame Date: Thu, 30 May 2024 17:38:05 +0500 Subject: [PATCH] search page tablet version + filters modal --- src/components/Checkbox.tsx | 4 +- src/components/MultiRangeSlider.tsx | 2 +- .../complexPage/ComplexTopPanel.tsx | 3 + .../header/Header/DesktopHeader.tsx | 2 +- src/components/header/Header/MobileHeader.tsx | 2 +- src/components/icons/FilterIcon.tsx | 1 - src/components/modals/HelpModal.tsx | 3 +- src/components/modals/MasterplanFilters.tsx | 2 +- .../modals/mobile/MobileModalWrapper.tsx | 51 +++++ .../modals/mobile/SearchFiltersModal.tsx | 182 ++++++++++++++++++ src/components/searchPage/LayoutOptions.tsx | 36 +++- src/components/searchPage/SidebarFilters.tsx | 2 +- .../virtualTour/VirtualTourSidebar.tsx | 2 +- .../virtualTour/VirtualTourTopPanel.tsx | 5 +- 14 files changed, 278 insertions(+), 19 deletions(-) create mode 100644 src/components/modals/mobile/MobileModalWrapper.tsx create mode 100644 src/components/modals/mobile/SearchFiltersModal.tsx diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 901d4cb..59ee96e 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -35,7 +35,9 @@ const Checkbox = ({ onClick, checkbox }: CheckboxProps) => { {!checkbox.disabled ? (
-
8
+
+ 8 +
) : (
diff --git a/src/components/MultiRangeSlider.tsx b/src/components/MultiRangeSlider.tsx index 549ab3d..18aa4ad 100644 --- a/src/components/MultiRangeSlider.tsx +++ b/src/components/MultiRangeSlider.tsx @@ -68,7 +68,7 @@ const MultiRangeSlider = ({ }, [multirangeSlider.endValue]); return ( -
+
{ buttonType="fab" icon={} onClick={handleOnFullScreenClick} + isCircleRounded /> ) : (
diff --git a/src/components/header/Header/DesktopHeader.tsx b/src/components/header/Header/DesktopHeader.tsx index efef467..ec0f21c 100644 --- a/src/components/header/Header/DesktopHeader.tsx +++ b/src/components/header/Header/DesktopHeader.tsx @@ -4,7 +4,7 @@ import Navbar from "../Navbar/Navbar"; import Location from "../Location"; const DesktopHeader = () => ( -
+
diff --git a/src/components/header/Header/MobileHeader.tsx b/src/components/header/Header/MobileHeader.tsx index 13cec40..f5204af 100644 --- a/src/components/header/Header/MobileHeader.tsx +++ b/src/components/header/Header/MobileHeader.tsx @@ -18,7 +18,7 @@ const MobileHeader = () => { isToggled ? "rounded-ee-lg rounded-es-lg shadow-[#00000026] shadow-md" : "" - } text-white flex flex-col text-sm items-center transition-all duration-500 ease-in-out absolute top-0 left-0 z-30 overflow-hidden font-usual ${ + } text-white flex flex-col text-sm items-center transition-all duration-500 ease-in-out absolute top-0 left-0 z-[99999900] overflow-hidden font-usual ${ isToggled ? "max-h-[472px]" : "max-h-14" }`} > diff --git a/src/components/icons/FilterIcon.tsx b/src/components/icons/FilterIcon.tsx index d4d729f..0b801e2 100644 --- a/src/components/icons/FilterIcon.tsx +++ b/src/components/icons/FilterIcon.tsx @@ -26,7 +26,6 @@ const FilterIcon = () => { rx="2.08333" ry="2.08333" fill="currentColor" - // fill="#0D1922" /> { const handleOnCloseClick = () => setModal(null); return ( -
+
@@ -21,6 +21,7 @@ const HelpModal = () => { icon={} buttonType="fab" onClick={handleOnCloseClick} + isCircleRounded />
{ }; return ( -
+
diff --git a/src/components/modals/mobile/MobileModalWrapper.tsx b/src/components/modals/mobile/MobileModalWrapper.tsx new file mode 100644 index 0000000..917b2bd --- /dev/null +++ b/src/components/modals/mobile/MobileModalWrapper.tsx @@ -0,0 +1,51 @@ +import { + SetStateAction, + createContext, + useEffect, + useState, + Dispatch, +} from "react"; + +interface MobileModalWrapperContext { + setIsAnimate: Dispatch> | null; + isAnimate: boolean | null; +} + +export const MobileModalWrapperContext = + createContext({ + setIsAnimate: null, + isAnimate: null, + }); + +interface MobileModalWrapperProps { + children: React.ReactNode; +} + +const MobileModalWrapper = ({ children }: MobileModalWrapperProps) => { + const [isAnimate, setIsAnimate] = useState(false); + + useEffect(() => { + setIsAnimate(true); + }, []); + + return ( +
+
+ + {children} + +
+
+ ); +}; + +export { MobileModalWrapper }; diff --git a/src/components/modals/mobile/SearchFiltersModal.tsx b/src/components/modals/mobile/SearchFiltersModal.tsx new file mode 100644 index 0000000..f3a6b9f --- /dev/null +++ b/src/components/modals/mobile/SearchFiltersModal.tsx @@ -0,0 +1,182 @@ +import { useContext } from "react"; +import useModal from "../../../store/useModal"; +import Button from "../../Button"; +import CrossIcon from "../../icons/CrossIcon"; +import { MobileModalWrapperContext } from "./MobileModalWrapper"; +import { + initialApartmentTypeCheckboxes, + initialSliders, + initialSwitchers, + initialRoveHomeCheckboxes, +} from "../../consts/initialSearchFilters"; +import useSearchFilters from "../../../store/useSearchFilters"; +import Checkbox from "../../Checkbox"; +import MultiRangeSlider from "../../MultiRangeSlider"; +import Switch from "../../Switch"; +import ResetIcon from "../../icons/ResetIcon"; + +const SearchFiltersModal = () => { + const { setModal } = useModal(); + const { setIsAnimate } = useContext(MobileModalWrapperContext); + const { + multirangeSliders, + setMultirangeSliders, + switchers, + setSwitchers, + apartmentTypeCheckboxes, + setApartmentTypeCheckboxes, + roveHomeTypeCheckboxes, + setRoveHomeTypeCheckboxes, + } = useSearchFilters(); + + const handleOnCrossClick = () => { + if (setIsAnimate) { + setIsAnimate(false); + const timeout = setTimeout(() => { + setModal(null); + clearTimeout(timeout); + }, 300); + } + }; + + const handleOnCheckboxApartmentClick = (checkboxId: string) => { + const updatedCheckboxes = apartmentTypeCheckboxes.map((cbox) => { + if (checkboxId !== cbox.id) return cbox; + const isSelected = !cbox.selected; + + return { ...cbox, selected: isSelected }; + }); + + setApartmentTypeCheckboxes(updatedCheckboxes); + }; + + const handleOnCheckboxRoveHomeClick = (checkboxId: string) => { + const updatedCheckboxes = roveHomeTypeCheckboxes.map((cbox) => { + if (checkboxId !== cbox.id) return cbox; + const isSelected = !cbox.selected; + + return { ...cbox, selected: isSelected }; + }); + + setRoveHomeTypeCheckboxes(updatedCheckboxes); + }; + + const handleOnSwitcherClick = (switcherId: string) => { + const updatedSwitchers = switchers.map((switcher) => { + if (switcherId !== switcher.id) return switcher; + const { isSwitched } = switcher; + + return { ...switcher, isSwitched: !isSwitched }; + }); + + setSwitchers(updatedSwitchers); + }; + + const handleOnSliderValueChange = ( + sliderId: string, + e: [a: number, b: number] + ) => { + const updatedSliders = multirangeSliders.map((slider) => { + if (sliderId !== slider.id) return slider; + + return { ...slider, startValue: e[0], endValue: e[1] }; + }); + + setMultirangeSliders(updatedSliders); + }; + + const handleOnShowApartmentClick = () => { + if (setIsAnimate) { + setIsAnimate(false); + const timeout = setTimeout(() => { + setModal(null); + clearTimeout(timeout); + }, 300); + } + }; + + return ( +
+
+

+ Filters +

+
+
+

Rove Home

+
+ {roveHomeTypeCheckboxes.map((checkbox) => ( + + ))} +
+
+
+

+ Apartment type +

+
+ {apartmentTypeCheckboxes.map((checkbox) => ( + + ))} +
+
+
+ {multirangeSliders.map((slider) => ( +
+
+

+ {slider.title} +

+

+ {slider.unit} +

+
+ +
+ ))} +
+ {switchers.map((switcher) => ( +
+

{switcher.title}

+ +
+ ))} +
+
+
+

195 apartments found

+
+
+ ); +}; + +export default SearchFiltersModal; diff --git a/src/components/searchPage/LayoutOptions.tsx b/src/components/searchPage/LayoutOptions.tsx index 824cc26..97d7b05 100644 --- a/src/components/searchPage/LayoutOptions.tsx +++ b/src/components/searchPage/LayoutOptions.tsx @@ -5,10 +5,16 @@ import useSearchFilters from "../../store/useSearchFilters"; import { initialSortList, layoutsCards } from "../../consts/initialSearchPage"; import SearchIcon from "../icons/SearchIcon"; import { sortCardBy } from "../../calc/sortCard"; +import Button from "../Button"; +import FilterIcon from "../icons/FilterIcon"; +import useModal from "../../store/useModal"; +import { MobileModalWrapper } from "../modals/mobile/MobileModalWrapper"; +import SearchFiltersModal from "../modals/mobile/SearchFiltersModal"; const LayoutOptions = () => { const [sortList, setSortList] = useState(initialSortList); const [cards, setCards] = useState(layoutsCards); + const { setModal } = useModal(); const { roveHomeTypeCheckboxes, apartmentTypeCheckboxes, multirangeSliders } = useSearchFilters(); @@ -20,6 +26,14 @@ const LayoutOptions = () => { setSortList(updatedSortList); }; + const handleOnFilterClick = () => { + setModal( + + + + ); + }; + useEffect(() => { const sortedCards = sortCardBy(sortList, layoutsCards); @@ -32,14 +46,24 @@ const LayoutOptions = () => { ]); return (
-
-
-

Layout options

-

145

+
+
+
+

Units

+

145

+
+ +
+
+
-
-
+
{cards.map((layoutsCard) => ( ))} diff --git a/src/components/searchPage/SidebarFilters.tsx b/src/components/searchPage/SidebarFilters.tsx index c857ed9..3e4ced6 100644 --- a/src/components/searchPage/SidebarFilters.tsx +++ b/src/components/searchPage/SidebarFilters.tsx @@ -78,7 +78,7 @@ const SidebarFilters = () => { return (
-
+

Filters

diff --git a/src/components/virtualTour/VirtualTourSidebar.tsx b/src/components/virtualTour/VirtualTourSidebar.tsx index 5f1cf6a..947fceb 100644 --- a/src/components/virtualTour/VirtualTourSidebar.tsx +++ b/src/components/virtualTour/VirtualTourSidebar.tsx @@ -22,7 +22,7 @@ const VirtualTourSidebar = ({ currentAppartment }: VirtualTourSidebarProps) => { }; return ( -
+
diff --git a/src/components/virtualTour/VirtualTourTopPanel.tsx b/src/components/virtualTour/VirtualTourTopPanel.tsx index 3bb68d7..be01f2a 100644 --- a/src/components/virtualTour/VirtualTourTopPanel.tsx +++ b/src/components/virtualTour/VirtualTourTopPanel.tsx @@ -41,11 +41,8 @@ const VirtualTourTopPanel = () => { return ( <> -
- -