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 0000000..2e9df07 Binary files /dev/null and b/public/images/layout-1.png differ diff --git a/src/calc/sortCard.ts b/src/calc/sortCard.ts new file mode 100644 index 0000000..a6d9840 --- /dev/null +++ b/src/calc/sortCard.ts @@ -0,0 +1,24 @@ +import { ILayoutCard } from "../types/layoutCard"; +import { ISort } from "../types/sortType"; + +const sortCardBy = (sortTypeList: ISort[], layoutsCards: ILayoutCard[]) => { + 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"