From a9fa869e4c60b4c48ec34d2f5b23eba0728d2064 Mon Sep 17 00:00:00 2001 From: zojgame Date: Mon, 20 May 2024 18:27:38 +0500 Subject: [PATCH] search page --- package.json | 3 +- public/images/layout-1.png | Bin 0 -> 41265 bytes src/calc/sortCard.ts | 24 +++ src/components/Checkbox.tsx | 4 +- src/components/Switch.tsx | 1 - src/components/icons/Heart.tsx | 26 +++ src/components/icons/SearchIcon.tsx | 18 +- src/components/icons/SearchPlusIcon.tsx | 21 ++ src/components/modals/ZoomHintModal.tsx | 2 +- src/components/searchPage/LayoutCard.tsx | 16 +- src/components/searchPage/LayoutOptions.tsx | 188 +++--------------- src/components/searchPage/SidebarFilters.tsx | 39 ++-- src/components/searchPage/SortButton.tsx | 5 +- .../ApartmentCard.tsx | 29 +++ .../ApartmentSidebar.tsx | 52 +++++ .../searchParticularApartmentsPage/Units.tsx | 54 +++++ src/consts/buttonStyles.ts | 4 + src/consts/initialSearchFilters.ts | 2 +- src/consts/initialSearchPage.ts | 162 +++++++++++++++ src/main.tsx | 10 + src/pages/SearchApartment.tsx | 55 +++++ src/pages/SearchParticularApartments.tsx | 17 ++ src/store/useSearchFilters.ts | 37 ++++ src/types/apartment.ts | 14 ++ src/types/button.ts | 8 +- src/types/layoutCard.ts | 2 +- tsconfig.json | 2 +- yarn.lock | 52 +++-- 28 files changed, 629 insertions(+), 218 deletions(-) create mode 100644 public/images/layout-1.png create mode 100644 src/calc/sortCard.ts create mode 100644 src/components/icons/Heart.tsx create mode 100644 src/components/icons/SearchPlusIcon.tsx create mode 100644 src/components/searchParticularApartmentsPage/ApartmentCard.tsx create mode 100644 src/components/searchParticularApartmentsPage/ApartmentSidebar.tsx create mode 100644 src/components/searchParticularApartmentsPage/Units.tsx create mode 100644 src/consts/initialSearchPage.ts create mode 100644 src/pages/SearchApartment.tsx create mode 100644 src/pages/SearchParticularApartments.tsx create mode 100644 src/store/useSearchFilters.ts create mode 100644 src/types/apartment.ts diff --git a/package.json b/package.json index 0de6457..d9f457e 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "preview": "vite preview" }, "dependencies": { + "@types/react-router-dom": "^5.3.3", "gsap": "^3.12.5", "react": "^18.2.0", "react-device-detect": "^2.2.3", @@ -17,7 +18,7 @@ "react-full-screen": "^1.1.1", "react-image-marker": "^1.2.0", "react-range-slider-input": "^3.0.7", - "react-router-dom": "^6.22.3", + "react-router-dom": "^6.23.1", "react-swipeable": "^7.0.1", "react-transition-group": "^4.4.5", "react-zoom-pan-pinch": "^3.4.4", diff --git a/public/images/layout-1.png b/public/images/layout-1.png new file mode 100644 index 0000000000000000000000000000000000000000..2e9df07783b0a0292a5f0c636516e9fd8301ee7c GIT binary patch literal 41265 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 e`_kHH+W!m-sA}AZt*24|0000 { + const sortType = sortTypeList.find((sort) => sort.isSelected); + const sortedList = [...layoutsCards].sort((cardA, cardB) => { + switch (sortType?.title) { + case "Ascending price": + return cardA.cost - cardB.cost; + case "Decreasing price": + return cardB.cost - cardA.cost; + case "Ascending Squares": + return cardA.square - cardB.square; + case "Ascending Floor": + return 1; + default: + return 1; + } + }); + + return sortedList; +}; + +export { sortCardBy }; diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 57a1962..901d4cb 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -12,7 +12,9 @@ const Checkbox = ({ onClick, checkbox }: CheckboxProps) => {
onClick(checkbox.id)} className={`flex justify-between bg-white p-3 rounded-2xl transition-[background] duration-300 ease-in-out select-none ${ - checkbox.disabled ? "" : "hover:bg-[#F3F3F2] cursor-pointer" + checkbox.disabled + ? "pointer-events-none touch-none" + : "hover:bg-[#F3F3F2] cursor-pointer" }`} >
diff --git a/src/components/Switch.tsx b/src/components/Switch.tsx index 8323e29..3fbd63b 100644 --- a/src/components/Switch.tsx +++ b/src/components/Switch.tsx @@ -7,7 +7,6 @@ interface ISwitchProps { const Switch = ({ switcher, onClick }: ISwitchProps) => { function handleOnClick() { - // setIsSwitched((prev) => !prev); onClick(switcher.id); } diff --git a/src/components/icons/Heart.tsx b/src/components/icons/Heart.tsx new file mode 100644 index 0000000..97c8efb --- /dev/null +++ b/src/components/icons/Heart.tsx @@ -0,0 +1,26 @@ +interface HeartIconProps { + isFilled?: boolean; +} + +const HeartIcon = ({ isFilled = false }: HeartIconProps) => { + return ( + + + + ); +}; + +export default HeartIcon; diff --git a/src/components/icons/SearchIcon.tsx b/src/components/icons/SearchIcon.tsx index 9efe52c..92992c6 100644 --- a/src/components/icons/SearchIcon.tsx +++ b/src/components/icons/SearchIcon.tsx @@ -1,21 +1,21 @@ -const SearchPlusIcon = () => { +const SearchIcon = () => { return ( ); }; -export default SearchPlusIcon; +export default SearchIcon; diff --git a/src/components/icons/SearchPlusIcon.tsx b/src/components/icons/SearchPlusIcon.tsx new file mode 100644 index 0000000..9efe52c --- /dev/null +++ b/src/components/icons/SearchPlusIcon.tsx @@ -0,0 +1,21 @@ +const SearchPlusIcon = () => { + return ( + + + + ); +}; + +export default SearchPlusIcon; diff --git a/src/components/modals/ZoomHintModal.tsx b/src/components/modals/ZoomHintModal.tsx index 6199f7f..4a36200 100644 --- a/src/components/modals/ZoomHintModal.tsx +++ b/src/components/modals/ZoomHintModal.tsx @@ -1,5 +1,5 @@ import { useEffect, useRef, useState } from "react"; -import SearchPlusIcon from "../icons/SearchIcon"; +import SearchPlusIcon from "../icons/SearchPlusIcon"; import OpenFullscreenIcon from "../icons/OpenFullscreenIcon"; import LineIcon from "../icons/LineIcon"; import useModal from "../../store/useModal"; diff --git a/src/components/searchPage/LayoutCard.tsx b/src/components/searchPage/LayoutCard.tsx index 0aff256..9dd720b 100644 --- a/src/components/searchPage/LayoutCard.tsx +++ b/src/components/searchPage/LayoutCard.tsx @@ -1,3 +1,4 @@ +import { useNavigate } from "react-router-dom"; import { ILayoutCard } from "../../types/layoutCard"; interface LayoutCardProps { @@ -14,10 +15,19 @@ const LayoutCard = ({ layoutCard }: LayoutCardProps) => { units, square, cost, + id, } = layoutCard; + const navigate = useNavigate(); + + const handleOnClick = () => { + navigate(`${id}`); + }; return ( -
+

@@ -35,7 +45,9 @@ const LayoutCard = ({ layoutCard }: LayoutCardProps) => { {units} units

-
+
+ +

{apartmentType}, {square} Sqft diff --git a/src/components/searchPage/LayoutOptions.tsx b/src/components/searchPage/LayoutOptions.tsx index 8fc8dec..824cc26 100644 --- a/src/components/searchPage/LayoutOptions.tsx +++ b/src/components/searchPage/LayoutOptions.tsx @@ -1,169 +1,17 @@ -import { useState } from "react"; -import { ILayoutCard } from "../../types/layoutCard"; -import { ISort } from "../../types/sortType"; +import { useEffect, useState } from "react"; import LayoutCard from "./LayoutCard"; import SortButton from "./SortButton"; - -const layoutsCards: ILayoutCard[] = [ - { - id: "1", - roveHome: "Marasi Drive", - apartmentType: "Studio Flex", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 10488888, - square: 609, - }, - { - id: "2", - roveHome: "Marasi Drive", - apartmentType: "1 Bedroom", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 1668888, - square: 609, - }, - { - id: "3", - roveHome: "Marasi Drive", - apartmentType: "1 Bedroom", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 1668888, - square: 609, - }, - { - id: "4", - roveHome: "Marasi Drive", - apartmentType: "1 Bedroom", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 1138888, - square: 609, - }, - { - id: "5", - roveHome: "Marasi Drive", - apartmentType: "Studio Flex", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 10488888, - square: 609, - }, - { - id: "6", - roveHome: "Marasi Drive", - apartmentType: "1 Bedroom", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 1668888, - square: 609, - }, - { - id: "7", - roveHome: "Marasi Drive", - apartmentType: "1 Bedroom", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 1668888, - square: 609, - }, - { - id: "8", - roveHome: "Marasi Drive", - apartmentType: "1 Bedroom", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 1138888, - square: 609, - }, - { - id: "9", - roveHome: "Marasi Drive", - apartmentType: "Studio Flex", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 10488888, - square: 609, - }, - { - id: "10", - roveHome: "Marasi Drive", - apartmentType: "1 Bedroom", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 1668888, - square: 609, - }, - { - id: "11", - roveHome: "Marasi Drive", - apartmentType: "1 Bedroom", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 1668888, - square: 609, - }, - { - id: "12", - roveHome: "Marasi Drive", - apartmentType: "1 Bedroom", - wing: "East Wing", - floorStart: 11, - floorEnd: 35, - units: 234, - cost: 1138888, - square: 609, - }, -]; - -const initialSortList: ISort[] = [ - { - id: "1", - title: "Ascending price", - isSelected: true, - }, - { - id: "2", - title: "Decreasing price", - isSelected: false, - }, - { - id: "3", - title: "Ascending Squares", - isSelected: false, - }, - { - id: "4", - title: "Ascending Floor", - isSelected: false, - }, -]; +import useSearchFilters from "../../store/useSearchFilters"; +import { initialSortList, layoutsCards } from "../../consts/initialSearchPage"; +import SearchIcon from "../icons/SearchIcon"; +import { sortCardBy } from "../../calc/sortCard"; const LayoutOptions = () => { const [sortList, setSortList] = useState(initialSortList); + const [cards, setCards] = useState(layoutsCards); + const { roveHomeTypeCheckboxes, apartmentTypeCheckboxes, multirangeSliders } = + useSearchFilters(); + const handleOnSortClick = (sortId: string) => { const updatedSortList = sortList.map((sort) => { const isSelected = sort.id === sortId; @@ -171,20 +19,34 @@ const LayoutOptions = () => { }); setSortList(updatedSortList); }; + + useEffect(() => { + const sortedCards = sortCardBy(sortList, layoutsCards); + + setCards(sortedCards); + }, [ + sortList, + roveHomeTypeCheckboxes, + apartmentTypeCheckboxes, + multirangeSliders, + ]); return (

-
+

Layout options

145

- {layoutsCards.map((layoutsCard) => ( + {cards.map((layoutsCard) => ( ))}
+
+ Show 12 more apartments +
); }; diff --git a/src/components/searchPage/SidebarFilters.tsx b/src/components/searchPage/SidebarFilters.tsx index ffa0212..ded8349 100644 --- a/src/components/searchPage/SidebarFilters.tsx +++ b/src/components/searchPage/SidebarFilters.tsx @@ -1,28 +1,27 @@ -import { useState } from "react"; import Button from "../Button"; import ResetIcon from "../icons/ResetIcon"; import Checkbox from "../Checkbox"; import Switch from "../Switch"; import MultiRangeSlider from "../MultiRangeSlider"; -import { ICheckbox } from "../../types/checkbox"; -import { IMultirangeSlider } from "../../types/multirangeSlider"; -import { ISwitcher } from "../../types/switcher"; import { initialApartmentTypeCheckboxes, initialSliders, initialSwitchers, initialRoveHomeCheckboxes, } from "../../consts/initialSearchFilters"; +import useSearchFilters from "../../store/useSearchFilters"; const SidebarFilters = () => { - const [apartmentTypeCheckboxes, setApartmentTypeCheckboxes] = useState< - ICheckbox[] - >(initialApartmentTypeCheckboxes); - const [roveHomeCheckboxes, setRoveHomeCheckboxes] = useState( - initialRoveHomeCheckboxes - ); - const [sliders, setSliders] = useState(initialSliders); - const [switchers, setSwitchers] = useState(initialSwitchers); + const { + multirangeSliders, + setMultirangeSliders, + switchers, + setSwitchers, + apartmentTypeCheckboxes, + setApartmentTypeCheckboxes, + roveHomeTypeCheckboxes, + setRoveHomeTypeCheckboxes, + } = useSearchFilters(); const handleOnCheckboxApartmentClick = (checkboxId: string) => { const updatedCheckboxes = apartmentTypeCheckboxes.map((cbox) => { @@ -36,27 +35,27 @@ const SidebarFilters = () => { }; const handleOnCheckboxRoveHomeClick = (checkboxId: string) => { - const updatedCheckboxes = roveHomeCheckboxes.map((cbox) => { + const updatedCheckboxes = roveHomeTypeCheckboxes.map((cbox) => { if (checkboxId !== cbox.id) return cbox; const isSelected = !cbox.selected; return { ...cbox, selected: isSelected }; }); - setRoveHomeCheckboxes(updatedCheckboxes); + setRoveHomeTypeCheckboxes(updatedCheckboxes); }; const handleOnSliderValueChange = ( sliderId: string, e: [a: number, b: number] ) => { - const updatedSliders = sliders.map((slider) => { + const updatedSliders = multirangeSliders.map((slider) => { if (sliderId !== slider.id) return slider; return { ...slider, startValue: e[0], endValue: e[1] }; }); - setSliders(updatedSliders); + setMultirangeSliders(updatedSliders); }; const handleOnSwitcherClick = (switcherId: string) => { @@ -72,8 +71,8 @@ const SidebarFilters = () => { const handleOnResetClick = () => { setApartmentTypeCheckboxes(initialApartmentTypeCheckboxes); - setRoveHomeCheckboxes(initialRoveHomeCheckboxes); - setSliders(initialSliders); + setRoveHomeTypeCheckboxes(initialRoveHomeCheckboxes); + setMultirangeSliders(initialSliders); setSwitchers(initialSwitchers); }; @@ -94,7 +93,7 @@ const SidebarFilters = () => { Rove Home

- {roveHomeCheckboxes.map((checkbox) => ( + {roveHomeTypeCheckboxes.map((checkbox) => ( {
- {sliders.map((slider) => ( + {multirangeSliders.map((slider) => (

diff --git a/src/components/searchPage/SortButton.tsx b/src/components/searchPage/SortButton.tsx index 9400d7a..9ee53c7 100644 --- a/src/components/searchPage/SortButton.tsx +++ b/src/components/searchPage/SortButton.tsx @@ -21,7 +21,10 @@ const SortButton = ({ sortList, onClick }: SortButtonProps) => { className="text-[#00BED7] text-m leading-5 flex gap-2" onClick={handleOnClick} > - Sort by ascending price{" "} + Sort by{" "} +

+ {sortList.find((sort) => sort.isSelected)?.title.toLocaleLowerCase()}{" "} +
{ + return ( +
+
+
+

+ Rove Home Marasi Drive +

+
+

East Wing

+
+

Floor 11

+
+

№ 213

+
+
+
+
+ +
+
+ ); +}; + +export default ApartmentCard; diff --git a/src/components/searchParticularApartmentsPage/ApartmentSidebar.tsx b/src/components/searchParticularApartmentsPage/ApartmentSidebar.tsx new file mode 100644 index 0000000..a6ddb15 --- /dev/null +++ b/src/components/searchParticularApartmentsPage/ApartmentSidebar.tsx @@ -0,0 +1,52 @@ +import Button from "../Button"; +import LeftArrowSliderIcon from "../icons/LeftArrowSliderIcon"; +import { useNavigate } from "react-router-dom"; + +const ApartmentSidebar = () => { + const navigate = useNavigate(); + + const handleOnBackClick = () => { + navigate(-1); + }; + + return ( +
+
+
+
+
+
+

+ Rove Home Marasi Drive +

+
+

+ East Wing +

+
+

+ Floor 11-35 +

+
+

+ AED 1668888 +

+
+
+ +
+
+
+
+ ); +}; + +export default ApartmentSidebar; diff --git a/src/components/searchParticularApartmentsPage/Units.tsx b/src/components/searchParticularApartmentsPage/Units.tsx new file mode 100644 index 0000000..a053813 --- /dev/null +++ b/src/components/searchParticularApartmentsPage/Units.tsx @@ -0,0 +1,54 @@ +import { useState, useEffect } from "react"; +import { initialSortList, layoutsCards } from "../../consts/initialSearchPage"; +import useSearchFilters from "../../store/useSearchFilters"; +import SearchIcon from "../icons/SearchIcon"; +import SortButton from "../searchPage/SortButton"; +import { sortCardBy } from "../../calc/sortCard"; +import ApartmentCard from "./ApartmentCard"; + +const Units = () => { + const [sortList, setSortList] = useState(initialSortList); + const [cards, setCards] = useState(layoutsCards); + const { roveHomeTypeCheckboxes, apartmentTypeCheckboxes, multirangeSliders } = + useSearchFilters(); + + const handleOnSortClick = (sortId: string) => { + const updatedSortList = sortList.map((sort) => { + const isSelected = sort.id === sortId; + return { ...sort, isSelected: isSelected }; + }); + setSortList(updatedSortList); + }; + + useEffect(() => { + const sortedCards = sortCardBy(sortList, layoutsCards); + + setCards(sortedCards); + }, [ + sortList, + roveHomeTypeCheckboxes, + apartmentTypeCheckboxes, + multirangeSliders, + ]); + return ( +
+
+
+

Units

+

145

+
+ +
+
+ {cards.map(() => ( + + ))} +
+
+ Show 12 more apartments +
+
+ ); +}; + +export default Units; diff --git a/src/consts/buttonStyles.ts b/src/consts/buttonStyles.ts index d88ab50..de7750b 100644 --- a/src/consts/buttonStyles.ts +++ b/src/consts/buttonStyles.ts @@ -6,6 +6,7 @@ const backgroundColors: ButtonStyle = { secondary: "bg-[#ffffff] hover:bg-[#F3F3F2] active:bg-[#fff]", tertiary: "bg-[#0D192266] hover:bg-[#0D1922B2]", fab: "bg-[#ffffff] hover:bg-[#F3F3F2]", + favorite: "bg-[#FFFFFF] hover:bg-[#F3F3F2]", }; const textColors: ButtonStyle = { @@ -14,6 +15,7 @@ const textColors: ButtonStyle = { secondary: "text-[#0D1922]", tertiary: "text-[#ffffff]", fab: "text-[#0D1922]", + favorite: "text-[#F3F3F2]", }; const borders: ButtonStyle = { @@ -22,6 +24,7 @@ const borders: ButtonStyle = { secondary: "rounded-lg border border-[#E2E2DC] active:border-[#00BED7]", tertiary: "rounded-full", fab: "rounded-full", + favorite: "rounded-lg border border-[#E2E2DC]", }; const paddings: ButtonStyle = { @@ -30,6 +33,7 @@ const paddings: ButtonStyle = { secondary: "py-3 px-6", tertiary: "py-1 px-3", fab: "py-3 px-6", + favorite: "p-[10px]", }; export { textColors, backgroundColors, borders, paddings }; diff --git a/src/consts/initialSearchFilters.ts b/src/consts/initialSearchFilters.ts index cd76bd1..a1dba81 100644 --- a/src/consts/initialSearchFilters.ts +++ b/src/consts/initialSearchFilters.ts @@ -32,7 +32,7 @@ const initialSliders: IMultirangeSlider[] = [ ]; const initialApartmentTypeCheckboxes: ICheckbox[] = [ - { title: "Studio Flex", id: "1", disabled: true, selected: false }, + { title: "Studio Flex", id: "1", selected: false }, { title: "Studio", id: "2", selected: false }, { title: "1 Bedroom", id: "3", selected: false }, { title: "2 Bedroom", id: "4", selected: false }, diff --git a/src/consts/initialSearchPage.ts b/src/consts/initialSearchPage.ts new file mode 100644 index 0000000..034c728 --- /dev/null +++ b/src/consts/initialSearchPage.ts @@ -0,0 +1,162 @@ +import { ILayoutCard } from "../types/layoutCard"; +import { ISort } from "../types/sortType"; + +const layoutsCards: ILayoutCard[] = [ + { + id: "1", + roveHome: "Marasi Drive", + apartmentType: "Studio Flex", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 10488888, + square: 619, + }, + { + id: "2", + roveHome: "Marasi Drive", + apartmentType: "1 Bedroom", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 1668888, + square: 619, + }, + { + id: "3", + roveHome: "Marasi Drive", + apartmentType: "1 Bedroom", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 1668888, + square: 609, + }, + { + id: "4", + roveHome: "Marasi Drive", + apartmentType: "1 Bedroom", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 1138888, + square: 609, + }, + { + id: "5", + roveHome: "Marasi Drive", + apartmentType: "Studio Flex", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 10488888, + square: 609, + }, + { + id: "6", + roveHome: "Marasi Drive", + apartmentType: "1 Bedroom", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 1668888, + square: 609, + }, + { + id: "7", + roveHome: "Marasi Drive", + apartmentType: "1 Bedroom", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 1668888, + square: 609, + }, + { + id: "8", + roveHome: "Marasi Drive", + apartmentType: "1 Bedroom", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 1138888, + square: 609, + }, + { + id: "9", + roveHome: "Marasi Drive", + apartmentType: "Studio Flex", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 10488888, + square: 609, + }, + { + id: "10", + roveHome: "Marasi Drive", + apartmentType: "1 Bedroom", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 1668888, + square: 609, + }, + { + id: "11", + roveHome: "Marasi Drive", + apartmentType: "1 Bedroom", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 1668888, + square: 609, + }, + { + id: "12", + roveHome: "Marasi Drive", + apartmentType: "1 Bedroom", + wing: "East Wing", + floorStart: 11, + floorEnd: 35, + units: 234, + cost: 1138888, + square: 609, + }, +]; + +const initialSortList: ISort[] = [ + { + id: "1", + title: "Ascending price", + isSelected: true, + }, + { + id: "2", + title: "Decreasing price", + isSelected: false, + }, + { + id: "3", + title: "Ascending Squares", + isSelected: false, + }, + { + id: "4", + title: "Ascending Floor", + isSelected: false, + }, +]; + +export { initialSortList, layoutsCards }; diff --git a/src/main.tsx b/src/main.tsx index 8acdf4c..bd39249 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -7,6 +7,8 @@ import "./index.css"; import Complex from "./pages/Complex"; import ComplexWing from "./pages/ComplexWing"; import Search from "./pages/Search"; +import SearchParticularApartments from "./pages/SearchParticularApartments"; +import SearchApartment from "./pages/SearchApartment"; const router = createBrowserRouter([ { @@ -37,6 +39,14 @@ const router = createBrowserRouter([ path: "/search", element: , }, + { + path: "/search/:apartmentType", + element: , + }, + { + path: "/search/:apartmentType/:apartmentId", + element: , + }, ], }, ]); diff --git a/src/pages/SearchApartment.tsx b/src/pages/SearchApartment.tsx new file mode 100644 index 0000000..61d95c3 --- /dev/null +++ b/src/pages/SearchApartment.tsx @@ -0,0 +1,55 @@ +import { useState } from "react"; +import Button from "../components/Button"; +import Footer from "../components/Footer"; +import SwitchToggle from "../components/SwitchToggle"; +import HeartIcon from "../components/icons/Heart"; +import LeftArrowSliderIcon from "../components/icons/LeftArrowSliderIcon"; +import { ISwitchLabel } from "../types/switchLabel"; + +const apartmentLayouts: ISwitchLabel[] = [ + { id: "1", label: "Layout" }, + { id: "2", label: "On the floor" }, +]; + +const SearchApartment = () => { + const [currentLabel, setCurrentLabel] = useState(apartmentLayouts[0]); + const handleOnSwitchClick = (label: ISwitchLabel) => { + setCurrentLabel(label); + }; + return ( +
+
+
+
+
+
+
+
+ +
+ +
+
+
+
+
+
+
+ ); +}; + +export default SearchApartment; diff --git a/src/pages/SearchParticularApartments.tsx b/src/pages/SearchParticularApartments.tsx new file mode 100644 index 0000000..9e88197 --- /dev/null +++ b/src/pages/SearchParticularApartments.tsx @@ -0,0 +1,17 @@ +import Footer from "../components/Footer"; +import ApartmentSidebar from "../components/searchParticularApartmentsPage/ApartmentSidebar"; +import Units from "../components/searchParticularApartmentsPage/Units"; + +const SearchParticularApartments = () => { + return ( +
+
+ + +
+
+
+ ); +}; + +export default SearchParticularApartments; diff --git a/src/store/useSearchFilters.ts b/src/store/useSearchFilters.ts new file mode 100644 index 0000000..b92fe96 --- /dev/null +++ b/src/store/useSearchFilters.ts @@ -0,0 +1,37 @@ +import { create } from "zustand"; +import { ICheckbox } from "../types/checkbox"; +import { + initialApartmentTypeCheckboxes, + initialRoveHomeCheckboxes, + initialSliders, + initialSwitchers, +} from "../consts/initialSearchFilters"; +import { IMultirangeSlider } from "../types/multirangeSlider"; +import { ISwitcher } from "../types/switcher"; + +interface Store { + apartmentTypeCheckboxes: ICheckbox[]; + setApartmentTypeCheckboxes: (typeCheckboxes: ICheckbox[]) => void; + roveHomeTypeCheckboxes: ICheckbox[]; + setRoveHomeTypeCheckboxes: (typeCheckboxes: ICheckbox[]) => void; + multirangeSliders: IMultirangeSlider[]; + setMultirangeSliders: (multirangeSliders: IMultirangeSlider[]) => void; + switchers: ISwitcher[]; + setSwitchers: (switchers: ISwitcher[]) => void; +} + +const useSearchFilters = create((set) => ({ + apartmentTypeCheckboxes: initialApartmentTypeCheckboxes, + setApartmentTypeCheckboxes: (typeCheckboxes) => + set(() => ({ apartmentTypeCheckboxes: typeCheckboxes })), + roveHomeTypeCheckboxes: initialRoveHomeCheckboxes, + setRoveHomeTypeCheckboxes: (typeCheckboxes) => + set(() => ({ roveHomeTypeCheckboxes: typeCheckboxes })), + multirangeSliders: initialSliders, + setMultirangeSliders: (multirangeSliders) => + set(() => ({ multirangeSliders: multirangeSliders })), + switchers: initialSwitchers, + setSwitchers: (switchers) => set(() => ({ switchers: switchers })), +})); + +export default useSearchFilters; diff --git a/src/types/apartment.ts b/src/types/apartment.ts new file mode 100644 index 0000000..4650c60 --- /dev/null +++ b/src/types/apartment.ts @@ -0,0 +1,14 @@ +import { RoveHome } from "./layoutCard"; + +interface IApartmentCard { + id: string; + roveHome: RoveHome; + wing: string; + floor: number; + cost: number; + square: number; + number: number; + imgSrc?: string; +} + +export type { IApartmentCard }; diff --git a/src/types/button.ts b/src/types/button.ts index 9cc5ab9..c485327 100644 --- a/src/types/button.ts +++ b/src/types/button.ts @@ -1,4 +1,10 @@ -type ButtonType = "primary" | "tertiary" | "cta" | "fab" | "secondary"; +type ButtonType = + | "primary" + | "tertiary" + | "cta" + | "fab" + | "secondary" + | "favorite"; type ButtonStyle = { [key in ButtonType]: string; }; diff --git a/src/types/layoutCard.ts b/src/types/layoutCard.ts index 7740abc..86de15c 100644 --- a/src/types/layoutCard.ts +++ b/src/types/layoutCard.ts @@ -14,4 +14,4 @@ interface ILayoutCard { imgSrc?: string; } -export type { ILayoutCard }; +export type { ILayoutCard, ApartmentType, RoveHome }; diff --git a/tsconfig.json b/tsconfig.json index a7fc6fb..b3cde40 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "target": "ES2020", "useDefineForClassFields": true, - "lib": ["ES2020", "DOM", "DOM.Iterable"], + "lib": ["ESNext.Array", "DOM", "ESNext", "DOM.Iterable", "ES2020"], "module": "ESNext", "skipLibCheck": true, diff --git a/yarn.lock b/yarn.lock index 6f0db86..c298fb5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -462,10 +462,10 @@ resolved "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz" integrity sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg== -"@remix-run/router@1.15.3": - version "1.15.3" - resolved "https://registry.npmjs.org/@remix-run/router/-/router-1.15.3.tgz" - integrity sha512-Oy8rmScVrVxWZVOpEF57ovlnhpZ8CCPlnIIumVcV9nFdiSIrus99+Lw78ekXyGvVDlIsFJbSfmSovJUhCWYV3w== +"@remix-run/router@1.16.1": + version "1.16.1" + resolved "https://registry.yarnpkg.com/@remix-run/router/-/router-1.16.1.tgz#73db3c48b975eeb06d0006481bde4f5f2d17d1cd" + integrity sha512-es2g3dq6Nb07iFxGk5GuHN20RwBZOsuDQN7izWIisUcv9r+d2C5jQxqmgkdebXgReWfiyUabcki6Fg77mSNrig== "@rollup/rollup-android-arm-eabi@4.14.3": version "4.14.3" @@ -585,6 +585,11 @@ resolved "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz" integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/history@^4.7.11": + version "4.7.11" + resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.11.tgz#56588b17ae8f50c53983a524fc3cc47437969d64" + integrity sha512-qjDJRrmvBMiTx+jyLxvLfJU7UznFuokDv4f3WRuriHKERccVpFU+8XMQUAbDzoiJCsmexxRExQeMwwCdamSKDA== + "@types/json-schema@^7.0.15": version "7.0.15" resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz" @@ -602,6 +607,23 @@ dependencies: "@types/react" "*" +"@types/react-router-dom@^5.3.3": + version "5.3.3" + resolved "https://registry.yarnpkg.com/@types/react-router-dom/-/react-router-dom-5.3.3.tgz#e9d6b4a66fcdbd651a5f106c2656a30088cc1e83" + integrity sha512-kpqnYK4wcdm5UaWI3fLcELopqLrHgLqNsdpHauzlQktfkHL3npOSwtj1Uz9oKBAzs7lFtVkV8j83voAz2D8fhw== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-router" "*" + +"@types/react-router@*": + version "5.1.20" + resolved "https://registry.yarnpkg.com/@types/react-router/-/react-router-5.1.20.tgz#88eccaa122a82405ef3efbcaaa5dcdd9f021387c" + integrity sha512-jGjmu/ZqS7FjSH6owMcD5qpq19+1RS9DeVRqfl1FeBMxTDQAGwlMWOcs52NDoXaNKyG3d1cYQFMs9rCrb88o9Q== + dependencies: + "@types/history" "^4.7.11" + "@types/react" "*" + "@types/react-transition-group@^4.4.10": version "4.4.10" resolved "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.10.tgz" @@ -1865,20 +1887,20 @@ react-refresh@^0.14.0: resolved "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.0.tgz" integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ== -react-router-dom@^6.22.3: - version "6.22.3" - resolved "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.22.3.tgz" - integrity sha512-7ZILI7HjcE+p31oQvwbokjk6OA/bnFxrhJ19n82Ex9Ph8fNAq+Hm/7KchpMGlTgWhUxRHMMCut+vEtNpWpowKw== +react-router-dom@^6.23.1: + version "6.23.1" + resolved "https://registry.yarnpkg.com/react-router-dom/-/react-router-dom-6.23.1.tgz#30cbf266669693e9492aa4fc0dde2541ab02322f" + integrity sha512-utP+K+aSTtEdbWpC+4gxhdlPFwuEfDKq8ZrPFU65bbRJY+l706qjR7yaidBpo3MSeA/fzwbXWbKBI6ftOnP3OQ== dependencies: - "@remix-run/router" "1.15.3" - react-router "6.22.3" + "@remix-run/router" "1.16.1" + react-router "6.23.1" -react-router@6.22.3: - version "6.22.3" - resolved "https://registry.npmjs.org/react-router/-/react-router-6.22.3.tgz" - integrity sha512-dr2eb3Mj5zK2YISHK++foM9w4eBnO23eKnZEDs7c880P6oKbrjz/Svg9+nxqtHQK+oMW4OtjZca0RqPglXxguQ== +react-router@6.23.1: + version "6.23.1" + resolved "https://registry.yarnpkg.com/react-router/-/react-router-6.23.1.tgz#d08cbdbd9d6aedc13eea6e94bc6d9b29cb1c4be9" + integrity sha512-fzcOaRF69uvqbbM7OhvQyBTFDVrrGlsFdS3AL+1KfIBtGETibHzi3FkoTRyiDJnWNc2VxrfvR+657ROHjaNjqQ== dependencies: - "@remix-run/router" "1.15.3" + "@remix-run/router" "1.16.1" react-swipeable@^7.0.1: version "7.0.1"