search page + sorting starts

This commit is contained in:
2024-05-17 18:29:41 +05:00
parent 338865fb56
commit 891204f2b4
20 changed files with 801 additions and 110 deletions
+11 -20
View File
@@ -1,46 +1,37 @@
import { useState } from "react";
import MinusIcon from "./icons/MinusIcon";
import SelectedCheckboxIcon from "./icons/SelectedCheckboxIcon";
import { ICheckbox } from "../types/checkbox";
interface CheckboxProps {
title: string;
disabled?: boolean;
selected?: boolean;
onClick: (id: string) => void;
checkbox: ICheckbox;
}
const Checkbox = ({ title, disabled, selected = false }: CheckboxProps) => {
const [isSelected, setIsSelected] = useState(selected);
const handleOnClick = () => {
if (!disabled) {
setIsSelected((prev) => !prev);
}
};
const Checkbox = ({ onClick, checkbox }: CheckboxProps) => {
return (
<div
onClick={handleOnClick}
onClick={() => onClick(checkbox.id)}
className={`flex justify-between bg-white p-3 rounded-2xl transition-[background] duration-300 ease-in-out select-none ${
disabled ? "" : "hover:bg-[#F3F3F2] cursor-pointer"
checkbox.disabled ? "" : "hover:bg-[#F3F3F2] cursor-pointer"
}`}
>
<div className="flex gap-3">
{disabled ? (
{checkbox.disabled ? (
<div className="bg-[#E2E2DC] rounded-[4px] w-6 h-6 text-white flex justify-center items-center">
<MinusIcon />
</div>
) : (
<div
className={` rounded-[4px] w-6 h-6 flex justify-center items-center ease-in-out duration-300 transition-[background] ${
isSelected ? "bg-[#00BED7]" : "bg-[#E2E2DC]"
checkbox.selected ? "bg-[#00BED7]" : "bg-[#E2E2DC]"
}`}
>
{isSelected ? <SelectedCheckboxIcon /> : <></>}
{checkbox.selected ? <SelectedCheckboxIcon /> : <></>}
</div>
)}
<p className="text-s text-[#73787C]">{title}</p>
<p className="text-s text-[#73787C]">{checkbox.title}</p>
</div>
{!disabled ? (
{!checkbox.disabled ? (
<div className="bg-[#00BED7] rounded-full text-white w-6 h-6 flex items-center justify-center font-semibold text-caption-s ">
<div className="h-fit align-middle text-center flex">8</div>
</div>
+36 -24
View File
@@ -1,30 +1,35 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
import { useState, useRef, useEffect } from "react";
import { useRef, useEffect } from "react";
import RangeSlider from "react-range-slider-input";
// import "react-range-slider-input/dist/style.css";
import "./multiRangeSlider.css";
import { IMultirangeSlider } from "../types/multirangeSlider";
interface MultiRangeSliderProps {
onChange?: () => void;
min: number;
max: number;
onChange: (sliderId: string, e: [a: number, b: number]) => void;
multirangeSlider: IMultirangeSlider;
}
const MultiRangeSlider = ({ min, max }: MultiRangeSliderProps) => {
const [firstValue, setFirstValue] = useState(min);
const [secondValue, setSecondValue] = useState(max);
const MultiRangeSlider = ({
onChange,
multirangeSlider,
}: MultiRangeSliderProps) => {
const firstInputRef = useRef(null);
const secondInputRef = useRef(null);
const handleOnRangeInputChange = (e: [a: number, b: number]) => {
setFirstValue(e[0]);
setSecondValue(e[1]);
onChange(multirangeSlider.id, e);
};
const handleOnFirstInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const value = Number(e.target.value);
if (value >= min && value <= max) {
setFirstValue(value);
if (
value >= multirangeSlider.minValue &&
value <= multirangeSlider.maxValue
) {
const rangeValue: [a: number, b: number] = [
value,
multirangeSlider.endValue,
];
onChange(multirangeSlider.id, rangeValue);
}
};
@@ -32,20 +37,27 @@ const MultiRangeSlider = ({ min, max }: MultiRangeSliderProps) => {
e: React.ChangeEvent<HTMLInputElement>
) => {
const value = Number(e.target.value);
if (value >= min && value <= max) {
setSecondValue(value);
if (
value >= multirangeSlider.minValue &&
value <= multirangeSlider.maxValue
) {
const rangeValue: [a: number, b: number] = [
multirangeSlider.startValue,
value,
];
onChange(multirangeSlider.id, rangeValue);
}
};
useEffect(() => {
if (!firstInputRef.current) return;
(firstInputRef.current as HTMLInputElement).focus();
}, [firstValue]);
}, [multirangeSlider.startValue]);
useEffect(() => {
if (!secondInputRef.current) return;
(secondInputRef.current as HTMLInputElement).focus();
}, [secondValue]);
}, [multirangeSlider.endValue]);
return (
<div className="px-2">
@@ -53,25 +65,25 @@ const MultiRangeSlider = ({ min, max }: MultiRangeSliderProps) => {
<div className="flex justify-between">
<input
ref={firstInputRef}
key={firstValue}
key={multirangeSlider.startValue}
type="number"
onChange={handleOnFirstInputChange}
defaultValue={firstValue}
defaultValue={multirangeSlider.startValue}
className="focus:outline-none input_number w-1/2"
/>
<input
ref={secondInputRef}
onChange={handleOnSecondInputChange}
key={secondValue}
key={multirangeSlider.endValue}
type="number"
defaultValue={secondValue}
defaultValue={multirangeSlider.endValue}
className="focus:outline-none appearance-none input_number text-right w-1/2"
/>
</div>
<RangeSlider
min={min}
max={max}
value={[firstValue, secondValue]}
min={multirangeSlider.minValue}
max={multirangeSlider.maxValue}
value={[multirangeSlider.startValue, multirangeSlider.endValue]}
className="absolute -bottom-3 left-0 w-[calc(100%-16px)] z-20"
onInput={handleOnRangeInputChange}
/>
+12 -7
View File
@@ -1,21 +1,26 @@
import { useState } from "react";
import { ISwitcher } from "../types/switcher";
const Switch = () => {
const [isSwitched, setIsSwitched] = useState(false);
interface ISwitchProps {
switcher: ISwitcher;
onClick: (id: string) => void;
}
const Switch = ({ switcher, onClick }: ISwitchProps) => {
function handleOnClick() {
setIsSwitched((prev) => !prev);
// setIsSwitched((prev) => !prev);
onClick(switcher.id);
}
return (
<div
className={`w-10 h-6 relative rounded-full cursor-pointer transition-all duration-300 ease-in-out ${
isSwitched ? "bg-[#00BED7]" : "bg-[#E2E2DC]"
switcher.isSwitched ? "bg-[#00BED7]" : "bg-[#E2E2DC]"
}`}
onClick={handleOnClick}
>
<div
className={`w-5 h-5 bg-[#fff] rounded-full absolute transition-all duration-300 ease-in-out ${
isSwitched ? "top-[2px] left-[18px]" : "top-[2px] left-[2px]"
className={`w-5 h-5 bg-[#fff] rounded-full absolute transition-all duration-300 ease-in-out top-[2px] ${
switcher.isSwitched ? "left-[18px]" : "left-[2px]"
}`}
></div>
</div>
+21
View File
@@ -0,0 +1,21 @@
const CheckIcon = () => {
return (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M4.1665 9.16699L8.33317 13.3337L15.8332 6.66699"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export default CheckIcon;
+21
View File
@@ -0,0 +1,21 @@
const ChevronDownIcon = () => {
return (
<svg
width="24"
height="24"
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M19 9.00002L12 16L5 9.00002"
stroke="currentColor"
strokeWidth="1.5"
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
};
export default ChevronDownIcon;
+73 -58
View File
@@ -6,43 +6,67 @@ import ResetIcon from "../icons/ResetIcon";
import Checkbox from "../Checkbox";
import Switch from "../Switch";
import MultiRangeSlider from "../MultiRangeSlider";
interface ICheckbox {
title: string;
id: string;
disabled?: boolean;
selected: boolean;
}
const checkboxes: ICheckbox[] = [
{ title: "Studio Flex", id: "1", disabled: false, selected: false },
{ title: "Studio", id: "2", selected: false },
{ title: "1 Bedroom", id: "3", selected: false },
{ title: "2 Bedroom", id: "4", selected: false },
];
import { ICheckbox } from "../../types/checkbox";
import { IMultirangeSlider } from "../../types/multirangeSlider";
import { ISwitcher } from "../../types/switcher";
import {
initialCheckboxes,
initialSliders,
initialSwitchers,
} from "../../consts/initialMasterplanFilters";
const MasterplanFilters = () => {
const { setModal } = useModal();
// const [currentCheckboxes, setCurrentCheckboxes] =
// useState<ICheckbox[]>(checkboxes);
const [keyIndex, setKeyIndex] = useState(1);
const [checkboxes, setCheckboxes] = useState<ICheckbox[]>(initialCheckboxes);
const [sliders, setSliders] = useState<IMultirangeSlider[]>(initialSliders);
const [switchers, setSwitchers] = useState<ISwitcher[]>(initialSwitchers);
const handleOnCloseClick = () => setModal(null);
const handleOnCheckboxClick = (checkboxId: string) => {
const updatedCheckboxes = checkboxes.map((cbox) => {
if (checkboxId !== cbox.id) return cbox;
const isSelected = !cbox.selected;
return { ...cbox, selected: isSelected };
});
setCheckboxes(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 = () => {
// const updatedCheckboxes = checkboxes.map((checkbox) => {
// return { ...checkbox, selected: false };
// });
// setCurrentCheckboxes(updatedCheckboxes);
setKeyIndex((prev) => prev + 1);
setCheckboxes(initialCheckboxes);
setSliders(initialSliders);
setSwitchers(initialSwitchers);
};
return (
<div className="absolute z-50 top-0 left-0 w-screen bg-[#0D192266] h-screen backdrop-blur-[6px] grid grid-cols-12 items-center ">
<div
className="h-full col-span-3 bg-[#F3F3F2] flex flex-col items-center justify-between "
key={keyIndex}
>
<div className="h-full col-span-3 bg-[#F3F3F2] flex flex-col items-center justify-between ">
<div className="w-full py-6 px-6 flex flex-col items-center">
<div className="flex justify-between border-b border-[#E2E2DC] w-full pb-4">
<h2 className="text-subheadline-m font-semibold">Filters</h2>
@@ -59,47 +83,38 @@ const MasterplanFilters = () => {
<div className="flex flex-col gap-2">
{checkboxes.map((checkbox) => (
<Checkbox
title={checkbox.title}
checkbox={checkbox}
key={checkbox.id}
disabled={checkbox.disabled}
onClick={handleOnCheckboxClick}
/>
))}
</div>
</div>
<div className="flex flex-col pt-6 w-full gap-8">
<div className="flex flex-col gap-2">
<div className="flex justify-between items-center">
<p className="text-[#0D1922] text-m font-semibold ">Cost</p>
<p className="text-[#73787C] text-m font-semibold">AED</p>
{sliders.map((slider) => (
<div className="flex flex-col gap-2">
<div className="flex justify-between items-center">
<p className="text-[#0D1922] text-m font-semibold ">
{slider.title}
</p>
<p className="text-[#73787C] text-m font-semibold">
{slider.unit}
</p>
</div>
<MultiRangeSlider
onChange={handleOnSliderValueChange}
multirangeSlider={slider}
/>
</div>
<MultiRangeSlider min={1048888} max={2408888} />
</div>
<div className="flex flex-col gap-2">
<div className="flex justify-between items-center">
<p className="text-[#0D1922] text-m font-semibold ">
Total Area
</p>
<p className="text-[#73787C] text-m font-semibold">Sqft</p>
</div>
<MultiRangeSlider min={341} max={891} />
</div>
<div className="flex flex-col gap-2">
<div className="flex justify-between items-center">
<p className="text-[#0D1922] text-m font-semibold ">Floor</p>
<p className="text-[#73787C] text-m font-semibold"></p>
</div>
<MultiRangeSlider min={5} max={81} />
</div>
))}
<div className="flex flex-col gap-2">
<div className="flex justify-between w-full">
<p className="text-s text-[#73787C]">Not the first floor</p>
<Switch />
</div>
<div className="flex justify-between w-full">
<p className="text-s text-[#73787C]">Not the top floor</p>
<Switch />
</div>
{switchers.map((switcher) => (
<div key={switcher.id} className="flex justify-between w-full">
<p className="text-s text-[#73787C]">{switcher.title}</p>
<Switch switcher={switcher} onClick={handleOnSwitcherClick} />
</div>
))}
</div>
</div>
</div>
+49
View File
@@ -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 (
<div className="bg-white flex flex-col p-4 rounded-lg gap-4">
<div className="flex gap-4 justify-between">
<div className="flex gap-1 flex-col">
<p className="text-[#00BED7] text-s leading-5">
Rove Home {roveHome}
</p>
<div className="text-[#73787C] flex gap-2 items-center w-fit">
<p className="text-caption-m font-semibold leading-4">{wing}</p>
<div className="w-1 h-1 bg-[#E2E2DC] rounded-full"></div>
<p className="text-caption-m font-semibold leading-4">
Floor {floorStart}-{floorEnd}
</p>
</div>
</div>
<div className="bg-[#00BED7] text-white text-caption-m font-semibold rounded-full py-[3px] px-2 self-start text-nowrap">
{units} units
</div>
</div>
<div className="w-full bg-slate-500 aspect-square rounded-lg"></div>
<div className="flex flex-col">
<p className="text[#0D1922] text-s">
{apartmentType}, {square} Sqft
</p>
<p className="text-[#00BED7] text-m font-bold">AED {cost}</p>
</div>
</div>
);
};
export default LayoutCard;
+192
View File
@@ -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 (
<section className="w-full p-6 flex flex-col">
<div className="flex justify-between w-full items-center border-b pb-4">
<div className="flex gap-4 font-semibold text-subheadline-s leading-7">
<h2 className="text-[#0D1922]">Layout options</h2>
<p className="text-[#73787C]">145</p>
</div>
<SortButton sortList={sortList} onClick={handleOnSortClick} />
</div>
<div className="grid 2xl:grid-cols-4 xl:grid-cols-3 sm:grid-cols-2 grid-cols-1 gap-4 pt-6">
{layoutsCards.map((layoutsCard) => (
<LayoutCard layoutCard={layoutsCard} />
))}
</div>
</section>
);
};
export default LayoutOptions;
@@ -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<ICheckbox[]>(
initialRoveHomeCheckboxes
);
const [sliders, setSliders] = useState<IMultirangeSlider[]>(initialSliders);
const [switchers, setSwitchers] = useState<ISwitcher[]>(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 (
<div>
<div className="h-full w-[360px] bg-[#F3F3F2] flex flex-col items-center justify-between border-r">
<div className="w-full py-6 px-6 flex flex-col items-center">
<div className="flex justify-between border-b border-[#E2E2DC] w-full pb-4">
<h2 className="text-subheadline-m font-semibold">Filters</h2>
<Button
icon={<ResetIcon />}
buttonType="fab"
onClick={handleOnResetClick}
/>
</div>
<div className="flex flex-col pt-6 w-full">
<p className="text-[#0D1922] text-m font-semibold pb-4">
Rove Home
</p>
<div className="flex flex-col gap-2">
{roveHomeCheckboxes.map((checkbox) => (
<Checkbox
checkbox={checkbox}
key={checkbox.id}
onClick={handleOnCheckboxRoveHomeClick}
/>
))}
</div>
</div>
<div className="flex flex-col pt-6 w-full">
<p className="text-[#0D1922] text-m font-semibold pb-4">
Apartment type
</p>
<div className="flex flex-col gap-2">
{apartmentTypeCheckboxes.map((checkbox) => (
<Checkbox
checkbox={checkbox}
key={checkbox.id}
onClick={handleOnCheckboxApartmentClick}
/>
))}
</div>
</div>
<div className="flex flex-col pt-6 w-full gap-8">
{sliders.map((slider) => (
<div className="flex flex-col gap-2">
<div className="flex justify-between items-center">
<p className="text-[#0D1922] text-m font-semibold ">
{slider.title}
</p>
<p className="text-[#73787C] text-m font-semibold">
{slider.unit}
</p>
</div>
<MultiRangeSlider
onChange={handleOnSliderValueChange}
multirangeSlider={slider}
/>
</div>
))}
<div className="flex flex-col gap-2">
{switchers.map((switcher) => (
<div key={switcher.id} className="flex justify-between w-full">
<p className="text-s text-[#73787C]">{switcher.title}</p>
<Switch switcher={switcher} onClick={handleOnSwitcherClick} />
</div>
))}
</div>
</div>
</div>
</div>
</div>
);
};
export default SidebarFilters;
+57
View File
@@ -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 (
<div className="relative">
<button
className="text-[#00BED7] text-m leading-5 flex gap-2"
onClick={handleOnClick}
>
Sort by ascending price{" "}
<div
className={`transition-all duration-300 ease-in-out ${
isSelected ? "rotate-180" : "rotate-0"
}`}
>
<ChevronDownIcon />
</div>
</button>
<div
className={`absolute flex flex-col bg-white p-2 text-[#0D1922] rounded-lg w-full shadow-lg transition-opacity duration-300 ease-in-out ${
isSelected ? "opacity-100" : "opacity-0"
}`}
>
{sortList.map((sort) => (
<button
onClick={() => onClick(sort.id)}
key={sort.id}
className="hover:bg-[#F3F3F2] py-2 pl-3 rounded-lg transition-all duration-300 ease-in-out text-left flex items-center gap-2"
>
{sort.isSelected && (
<div className="text-[#00BED7]">
<CheckIcon />
</div>
)}
{sort.title}
</button>
))}
</div>
</div>
);
};
export default SortButton;
+46
View File
@@ -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 };
+57
View File
@@ -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,
};
+5
View File
@@ -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: <Company />,
},
{
path: "/search",
element: <Search />,
},
],
},
]);
+1 -1
View File
@@ -4,7 +4,7 @@ import SequenceWing from "../components/complexWingPage/SequenceWing";
const ComplexWing = () => {
return (
<div className="overflow-hidden h-screen w-screen">
<div className="overflow-hidden h-screen w-screen ">
<ComplexTopPanel />
<SequenceWing />
<ComplexButtomPanel />
+17
View File
@@ -0,0 +1,17 @@
import Footer from "../components/Footer";
import LayoutOptions from "../components/searchPage/LayoutOptions";
import SidebarFilters from "../components/searchPage/SidebarFilters";
const Search = () => {
return (
<div className="overflow-scroll h-screen w-screen pt-14">
<div className="flex">
<SidebarFilters />
<LayoutOptions />
</div>
<Footer />
</div>
);
};
export default Search;
+8
View File
@@ -0,0 +1,8 @@
interface ICheckbox {
title: string;
id: string;
disabled?: boolean;
selected: boolean;
}
export type { ICheckbox };
+17
View File
@@ -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 };
+11
View File
@@ -0,0 +1,11 @@
interface IMultirangeSlider {
minValue: number;
maxValue: number;
startValue: number;
endValue: number;
title: string;
unit?: string;
id: string;
}
export type { IMultirangeSlider };
+7
View File
@@ -0,0 +1,7 @@
interface ISort {
id: string;
title: string;
isSelected: boolean;
}
export type { ISort };
+7
View File
@@ -0,0 +1,7 @@
interface ISwitcher {
id: string;
title: string;
isSwitched: boolean;
}
export type { ISwitcher };