Filters
@@ -59,47 +83,38 @@ const MasterplanFilters = () => {
{checkboxes.map((checkbox) => (
))}
-
-
-
Cost
-
AED
+ {sliders.map((slider) => (
+
+
+
+ {slider.title}
+
+
+ {slider.unit}
+
+
+
-
-
-
-
-
- Total Area
-
-
Sqft
-
-
-
-
+ ))}
-
-
Not the first floor
-
-
-
+ {switchers.map((switcher) => (
+
+ ))}
diff --git a/src/components/searchPage/LayoutCard.tsx b/src/components/searchPage/LayoutCard.tsx
new file mode 100644
index 0000000..0aff256
--- /dev/null
+++ b/src/components/searchPage/LayoutCard.tsx
@@ -0,0 +1,49 @@
+import { ILayoutCard } from "../../types/layoutCard";
+
+interface LayoutCardProps {
+ layoutCard: ILayoutCard;
+}
+
+const LayoutCard = ({ layoutCard }: LayoutCardProps) => {
+ const {
+ floorEnd,
+ floorStart,
+ apartmentType,
+ roveHome,
+ wing,
+ units,
+ square,
+ cost,
+ } = layoutCard;
+
+ return (
+
+
+
+
+ Rove Home {roveHome}
+
+
+
{wing}
+
+
+ Floor {floorStart}-{floorEnd}
+
+
+
+
+ {units} units
+
+
+
+
+
+ {apartmentType}, {square} Sqft
+
+
AED {cost}
+
+
+ );
+};
+
+export default LayoutCard;
diff --git a/src/components/searchPage/LayoutOptions.tsx b/src/components/searchPage/LayoutOptions.tsx
new file mode 100644
index 0000000..8fc8dec
--- /dev/null
+++ b/src/components/searchPage/LayoutOptions.tsx
@@ -0,0 +1,192 @@
+import { useState } from "react";
+import { ILayoutCard } from "../../types/layoutCard";
+import { ISort } from "../../types/sortType";
+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,
+ },
+];
+
+const LayoutOptions = () => {
+ const [sortList, setSortList] = useState(initialSortList);
+ const handleOnSortClick = (sortId: string) => {
+ const updatedSortList = sortList.map((sort) => {
+ const isSelected = sort.id === sortId;
+ return { ...sort, isSelected: isSelected };
+ });
+ setSortList(updatedSortList);
+ };
+ return (
+
+
+
+ {layoutsCards.map((layoutsCard) => (
+
+ ))}
+
+
+ );
+};
+
+export default LayoutOptions;
diff --git a/src/components/searchPage/SidebarFilters.tsx b/src/components/searchPage/SidebarFilters.tsx
new file mode 100644
index 0000000..ffa0212
--- /dev/null
+++ b/src/components/searchPage/SidebarFilters.tsx
@@ -0,0 +1,153 @@
+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";
+
+const SidebarFilters = () => {
+ const [apartmentTypeCheckboxes, setApartmentTypeCheckboxes] = useState<
+ ICheckbox[]
+ >(initialApartmentTypeCheckboxes);
+ const [roveHomeCheckboxes, setRoveHomeCheckboxes] = useState
(
+ initialRoveHomeCheckboxes
+ );
+ const [sliders, setSliders] = useState(initialSliders);
+ const [switchers, setSwitchers] = useState(initialSwitchers);
+
+ 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 = roveHomeCheckboxes.map((cbox) => {
+ if (checkboxId !== cbox.id) return cbox;
+ const isSelected = !cbox.selected;
+
+ return { ...cbox, selected: isSelected };
+ });
+
+ setRoveHomeCheckboxes(updatedCheckboxes);
+ };
+
+ const handleOnSliderValueChange = (
+ sliderId: string,
+ e: [a: number, b: number]
+ ) => {
+ const updatedSliders = sliders.map((slider) => {
+ if (sliderId !== slider.id) return slider;
+
+ return { ...slider, startValue: e[0], endValue: e[1] };
+ });
+
+ setSliders(updatedSliders);
+ };
+
+ 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 handleOnResetClick = () => {
+ setApartmentTypeCheckboxes(initialApartmentTypeCheckboxes);
+ setRoveHomeCheckboxes(initialRoveHomeCheckboxes);
+ setSliders(initialSliders);
+ setSwitchers(initialSwitchers);
+ };
+
+ return (
+
+
+
+
+
Filters
+ }
+ buttonType="fab"
+ onClick={handleOnResetClick}
+ />
+
+
+
+ Rove Home
+
+
+ {roveHomeCheckboxes.map((checkbox) => (
+
+ ))}
+
+
+
+
+ Apartment type
+
+
+ {apartmentTypeCheckboxes.map((checkbox) => (
+
+ ))}
+
+
+
+ {sliders.map((slider) => (
+
+
+
+ {slider.title}
+
+
+ {slider.unit}
+
+
+
+
+ ))}
+
+
+ {switchers.map((switcher) => (
+
+ ))}
+
+
+
+
+
+ );
+};
+
+export default SidebarFilters;
diff --git a/src/components/searchPage/SortButton.tsx b/src/components/searchPage/SortButton.tsx
new file mode 100644
index 0000000..9400d7a
--- /dev/null
+++ b/src/components/searchPage/SortButton.tsx
@@ -0,0 +1,57 @@
+import { useState } from "react";
+import { ISort } from "../../types/sortType";
+import CheckIcon from "../icons/CheckIcon";
+import ChevronDownIcon from "../icons/ChevronDownIcon";
+
+interface SortButtonProps {
+ sortList: ISort[];
+ onClick: (id: string) => void;
+}
+
+const SortButton = ({ sortList, onClick }: SortButtonProps) => {
+ const [isSelected, setIsSelected] = useState(false);
+
+ const handleOnClick = () => {
+ setIsSelected((prev) => !prev);
+ };
+
+ return (
+
+
+
+ {sortList.map((sort) => (
+
+ ))}
+
+
+ );
+};
+
+export default SortButton;
diff --git a/src/consts/initialMasterplanFilters.ts b/src/consts/initialMasterplanFilters.ts
new file mode 100644
index 0000000..2e73725
--- /dev/null
+++ b/src/consts/initialMasterplanFilters.ts
@@ -0,0 +1,46 @@
+import { ICheckbox } from "../types/checkbox";
+import { IMultirangeSlider } from "../types/multirangeSlider";
+import { ISwitcher } from "../types/switcher";
+
+const initialSliders: IMultirangeSlider[] = [
+ {
+ minValue: 1048888,
+ startValue: 1048888,
+ endValue: 2408888,
+ maxValue: 2408888,
+ title: "Cost",
+ unit: "AED",
+ id: "1",
+ },
+ {
+ minValue: 341,
+ startValue: 341,
+ endValue: 891,
+ maxValue: 891,
+ title: "Total Area",
+ unit: "Sqrt",
+ id: "2",
+ },
+ {
+ minValue: 5,
+ startValue: 5,
+ endValue: 81,
+ maxValue: 81,
+ title: "Floor",
+ id: "3",
+ },
+];
+
+const initialCheckboxes: ICheckbox[] = [
+ { title: "Studio Flex", id: "1", disabled: true, selected: false },
+ { title: "Studio", id: "2", selected: false },
+ { title: "1 Bedroom", id: "3", selected: false },
+ { title: "2 Bedroom", id: "4", selected: false },
+];
+
+const initialSwitchers: ISwitcher[] = [
+ { id: "1", title: "Not the first floor", isSwitched: false },
+ { id: "2", title: "Not the top floor", isSwitched: false },
+];
+
+export { initialCheckboxes, initialSliders, initialSwitchers };
diff --git a/src/consts/initialSearchFilters.ts b/src/consts/initialSearchFilters.ts
new file mode 100644
index 0000000..cd76bd1
--- /dev/null
+++ b/src/consts/initialSearchFilters.ts
@@ -0,0 +1,57 @@
+import { ICheckbox } from "../types/checkbox";
+import { IMultirangeSlider } from "../types/multirangeSlider";
+import { ISwitcher } from "../types/switcher";
+
+const initialSliders: IMultirangeSlider[] = [
+ {
+ minValue: 1048888,
+ startValue: 1048888,
+ endValue: 2408888,
+ maxValue: 2408888,
+ title: "Cost",
+ unit: "AED",
+ id: "1",
+ },
+ {
+ minValue: 341,
+ startValue: 341,
+ endValue: 891,
+ maxValue: 891,
+ title: "Total Area",
+ unit: "Sqrt",
+ id: "2",
+ },
+ {
+ minValue: 5,
+ startValue: 5,
+ endValue: 81,
+ maxValue: 81,
+ title: "Floor",
+ id: "3",
+ },
+];
+
+const initialApartmentTypeCheckboxes: ICheckbox[] = [
+ { title: "Studio Flex", id: "1", disabled: true, selected: false },
+ { title: "Studio", id: "2", selected: false },
+ { title: "1 Bedroom", id: "3", selected: false },
+ { title: "2 Bedroom", id: "4", selected: false },
+];
+
+const initialRoveHomeCheckboxes: ICheckbox[] = [
+ { title: "Downtown", id: "1", disabled: false, selected: false },
+ { title: "Marasi Drive", id: "2", selected: false },
+ { title: "Dubai Marina", id: "3", selected: false, disabled: true },
+];
+
+const initialSwitchers: ISwitcher[] = [
+ { id: "1", title: "Not the first floor", isSwitched: false },
+ { id: "2", title: "Not the top floor", isSwitched: false },
+];
+
+export {
+ initialApartmentTypeCheckboxes,
+ initialSliders,
+ initialSwitchers,
+ initialRoveHomeCheckboxes,
+};
diff --git a/src/main.tsx b/src/main.tsx
index e98538a..8acdf4c 100644
--- a/src/main.tsx
+++ b/src/main.tsx
@@ -6,6 +6,7 @@ import Company from "./pages/Company";
import "./index.css";
import Complex from "./pages/Complex";
import ComplexWing from "./pages/ComplexWing";
+import Search from "./pages/Search";
const router = createBrowserRouter([
{
@@ -32,6 +33,10 @@ const router = createBrowserRouter([
path: "/company",
element: ,
},
+ {
+ path: "/search",
+ element: ,
+ },
],
},
]);
diff --git a/src/pages/ComplexWing.tsx b/src/pages/ComplexWing.tsx
index b8a6c40..80f57dc 100644
--- a/src/pages/ComplexWing.tsx
+++ b/src/pages/ComplexWing.tsx
@@ -4,7 +4,7 @@ import SequenceWing from "../components/complexWingPage/SequenceWing";
const ComplexWing = () => {
return (
-
+
diff --git a/src/pages/Search.tsx b/src/pages/Search.tsx
new file mode 100644
index 0000000..e37163d
--- /dev/null
+++ b/src/pages/Search.tsx
@@ -0,0 +1,17 @@
+import Footer from "../components/Footer";
+import LayoutOptions from "../components/searchPage/LayoutOptions";
+import SidebarFilters from "../components/searchPage/SidebarFilters";
+
+const Search = () => {
+ return (
+
+ );
+};
+
+export default Search;
diff --git a/src/types/checkbox.ts b/src/types/checkbox.ts
new file mode 100644
index 0000000..e852868
--- /dev/null
+++ b/src/types/checkbox.ts
@@ -0,0 +1,8 @@
+interface ICheckbox {
+ title: string;
+ id: string;
+ disabled?: boolean;
+ selected: boolean;
+}
+
+export type { ICheckbox };
diff --git a/src/types/layoutCard.ts b/src/types/layoutCard.ts
new file mode 100644
index 0000000..7740abc
--- /dev/null
+++ b/src/types/layoutCard.ts
@@ -0,0 +1,17 @@
+type RoveHome = "Downtown" | "Marasi Drive" | "Dubai Marina";
+type ApartmentType = "Studio Flex" | "Studio" | "1 Bedroom" | "2 Bedroom";
+
+interface ILayoutCard {
+ id: string;
+ roveHome: RoveHome;
+ apartmentType: ApartmentType;
+ wing: string;
+ floorStart: number;
+ floorEnd: number;
+ units: number;
+ cost: number;
+ square: number;
+ imgSrc?: string;
+}
+
+export type { ILayoutCard };
diff --git a/src/types/multirangeSlider.ts b/src/types/multirangeSlider.ts
new file mode 100644
index 0000000..914cdf4
--- /dev/null
+++ b/src/types/multirangeSlider.ts
@@ -0,0 +1,11 @@
+interface IMultirangeSlider {
+ minValue: number;
+ maxValue: number;
+ startValue: number;
+ endValue: number;
+ title: string;
+ unit?: string;
+ id: string;
+}
+
+export type { IMultirangeSlider };
diff --git a/src/types/sortType.ts b/src/types/sortType.ts
new file mode 100644
index 0000000..59f2985
--- /dev/null
+++ b/src/types/sortType.ts
@@ -0,0 +1,7 @@
+interface ISort {
+ id: string;
+ title: string;
+ isSelected: boolean;
+}
+
+export type { ISort };
diff --git a/src/types/switcher.ts b/src/types/switcher.ts
new file mode 100644
index 0000000..fd4ee3c
--- /dev/null
+++ b/src/types/switcher.ts
@@ -0,0 +1,7 @@
+interface ISwitcher {
+ id: string;
+ title: string;
+ isSwitched: boolean;
+}
+
+export type { ISwitcher };