diff --git a/public/images/searchApartment/StudioFlex.png b/public/images/searchApartment/StudioFlex.png new file mode 100644 index 0000000..510859d Binary files /dev/null and b/public/images/searchApartment/StudioFlex.png differ diff --git a/src/components/Checkbox.tsx b/src/components/Checkbox.tsx index 59ee96e..8d42bb9 100644 --- a/src/components/Checkbox.tsx +++ b/src/components/Checkbox.tsx @@ -11,7 +11,7 @@ const Checkbox = ({ onClick, checkbox }: CheckboxProps) => { return (
onClick(checkbox.id)} - className={`flex justify-between bg-white p-3 rounded-2xl transition-[background] duration-300 ease-in-out select-none ${ + className={`flex justify-between bg-white p-3 rounded-lg transition-[background] duration-300 ease-in-out select-none ${ checkbox.disabled ? "pointer-events-none touch-none" : "hover:bg-[#F3F3F2] cursor-pointer" diff --git a/src/components/MasterInput.tsx b/src/components/MasterInput.tsx new file mode 100644 index 0000000..a9f4ea5 --- /dev/null +++ b/src/components/MasterInput.tsx @@ -0,0 +1,25 @@ +interface MasterInputProps { + placeholder: string; + isRequired: boolean; + title: string; +} + +const MasterInput = ({ placeholder, isRequired, title }: MasterInputProps) => { + return ( +
+
+

{title}

+ {isRequired &&

*

} +
+
+ +
+
+ ); +}; + +export default MasterInput; diff --git a/src/components/MasterSelector.tsx b/src/components/MasterSelector.tsx index 9415c95..c0a0853 100644 --- a/src/components/MasterSelector.tsx +++ b/src/components/MasterSelector.tsx @@ -13,11 +13,9 @@ interface MasterSelectorProps { options?: IOptions[]; } -// const formatPhone = - const MasterSelector = ({ title }: MasterSelectorProps) => { return ( -
+

{title}

diff --git a/src/components/MultiRangeSlider.tsx b/src/components/MultiRangeSlider.tsx index 315bdc7..7fd565b 100644 --- a/src/components/MultiRangeSlider.tsx +++ b/src/components/MultiRangeSlider.tsx @@ -70,7 +70,7 @@ const MultiRangeSlider = ({ return (
-
+
{/* {
*/}
{ +const ApartmentDescription = ({ + isVisible, + is3DTourAvailable, +}: ApartmentDescriptionProps) => { return (

1 bedroom, 609 Sqft

-
+

East Wing

Floor 11

E-213

-

AED 1,668,888

+
+

+ AED 1,668,888 +

+
+ +

+ 3D-tour +

+
+
diff --git a/src/components/complexWingPage/FloorSidebar/FloorSidebar.tsx b/src/components/complexWingPage/FloorSidebar/FloorSidebar.tsx index 48cc682..87b566a 100644 --- a/src/components/complexWingPage/FloorSidebar/FloorSidebar.tsx +++ b/src/components/complexWingPage/FloorSidebar/FloorSidebar.tsx @@ -14,6 +14,7 @@ interface IFloorSidebarProps { const FloorSidebar = ({ currentFloor, onMouseEnter }: IFloorSidebarProps) => { const [mousePos, setMousePos] = useState([0, 0]); const [isDescVisible, setIsDescVisible] = useState(false); + const [is3DTourAvailable] = useState(true); const { setIsSidebar } = useWingSidebar(); const navigate = useNavigate(); @@ -50,7 +51,10 @@ const FloorSidebar = ({ currentFloor, onMouseEnter }: IFloorSidebarProps) => { className="absolute z-[99999] w-fit h-fit top-0 left-0" style={{ top: `${mousePos[1]}px`, left: `${mousePos[0]}px` }} > - +
{
234 units
-
+

Studio Flex

@@ -90,7 +94,7 @@ const FloorSidebar = ({ currentFloor, onMouseEnter }: IFloorSidebarProps) => {
-
+
{ return (
diff --git a/src/components/complexWingPage/SkygardenSidebar/SkygardenSidebar.tsx b/src/components/complexWingPage/SkygardenSidebar/SkygardenSidebar.tsx index 333d1cd..5883a71 100644 --- a/src/components/complexWingPage/SkygardenSidebar/SkygardenSidebar.tsx +++ b/src/components/complexWingPage/SkygardenSidebar/SkygardenSidebar.tsx @@ -42,7 +42,7 @@ const SkygardenSidebar = ({ onMouseEnter }: ISkygardenSidebarProps) => {
-
+
diff --git a/src/components/favoritesPage/FavoriteApartmentCard.tsx b/src/components/favoritesPage/FavoriteApartmentCard.tsx index 275b42b..4d9ff37 100644 --- a/src/components/favoritesPage/FavoriteApartmentCard.tsx +++ b/src/components/favoritesPage/FavoriteApartmentCard.tsx @@ -2,8 +2,10 @@ import useModal from "../../store/useModal"; import { ILayoutCard } from "../../types/layoutCard"; import Button from "../Button"; import BookingIcon from "../icons/BookingIcon"; -import CrossIcon from "../icons/CrossIcon"; import HeartIcon from "../icons/Heart"; +import { SendEnquiryModal } from "../modals/SendEnquryModal"; +import { MobileModalWrapper } from "../modals/mobile/MobileModalWrapper"; +import SendEnquiryMobileModal from "../modals/mobile/SendEnquiryMobileModal"; interface FavoriteAppartmentCardProps { card: ILayoutCard; @@ -18,8 +20,17 @@ const FavoriteAppartmentCard = ({ card }: FavoriteAppartmentCardProps) => { const handleOnSendEquiryClick = () => { setModal(); }; + + const handleOnMobileSendEquiryClick = () => { + setModal( + + + + ); + }; + return ( -
+

@@ -56,67 +67,20 @@ const FavoriteAppartmentCard = ({ card }: FavoriteAppartmentCardProps) => {

); }; -const SendEnquiryModal = () => { - const { setModal } = useModal(); - - const handleOnModalClick = () => { - setModal(null); - }; - return ( -
-
-
-
-

- Apartment purchase enquiry -

-
-
-
-

- 1 bedroom, 609 Sqft{" "} -

-

- AED 1,668,888 -

-
-
-

1 bedroom, 609 Sqft

-
-
-

- East Wing -

-
-

- Floor 11 -

-
-

- № 213 -

-
-
-
-
-
-
-
- ); -}; - export default FavoriteAppartmentCard; diff --git a/src/components/favoritesPage/FavoriteCardList.tsx b/src/components/favoritesPage/FavoriteCardList.tsx index 74839e9..acd7b2a 100644 --- a/src/components/favoritesPage/FavoriteCardList.tsx +++ b/src/components/favoritesPage/FavoriteCardList.tsx @@ -7,7 +7,7 @@ interface FavoriteCardListProps { const FavoriteCardList = ({ cards }: FavoriteCardListProps) => { return ( -
+
{cards.map((card) => ( ))} diff --git a/src/components/favoritesPage/FavoriteSlider.tsx b/src/components/favoritesPage/FavoriteSlider.tsx index 153737b..b7985c0 100644 --- a/src/components/favoritesPage/FavoriteSlider.tsx +++ b/src/components/favoritesPage/FavoriteSlider.tsx @@ -4,18 +4,45 @@ import FavoriteSliderCard from "./FavoriteSliderCard"; import Button from "../Button"; import RightArrowIcon from "../icons/RightArrowIcon"; import LeftArrowIcon from "../icons/LeftArrowIcon"; +import { useSwipeable } from "react-swipeable"; interface FavoritesSliderProps { cards: ILayoutCard[]; } -const cols = 4; - const FavoritesSlider = ({ cards }: FavoritesSliderProps) => { const [offset, setOffset] = useState(0); const cardRef = useRef(null); const [cardWidth, setCardWidth] = useState(0); const [buttonTopPos, setButtonTopPos] = useState(0); + const [cols, setCols] = useState(2); + + const handlers = useSwipeable({ + trackMouse: true, + onSwipedRight: () => handleOnLeftBtnClick(), + onSwipedLeft: () => handleOnRightBtnClick(), + }); + + const handleOnLeftBtnClick = () => { + if (0 > offset) { + setOffset((prev) => prev + 1); + } + }; + + const handleOnRightBtnClick = () => { + if (offset > -cards.length + cols + 1) { + setOffset((prev) => prev - 1); + } + }; + + useEffect(() => { + const screenWidth = window.innerWidth; + if (screenWidth >= 1024) { + setCols(4); + } else { + setCols(2); + } + }, [window.innerWidth]); useEffect(() => { const cardElement = cardRef.current; @@ -27,22 +54,10 @@ const FavoritesSlider = ({ cards }: FavoritesSliderProps) => { setCardWidth(width); setButtonTopPos(_buttonTopPos); } - }, []); - - const handleOnLeftBtnClick = () => { - if (0 > offset) { - setOffset((prev) => prev + 1); - } - }; - - const handleOnRightBtnClick = () => { - if (offset > -cards.length + cols) { - setOffset((prev) => prev - 1); - } - }; + }, [cardRef.current]); return ( -
+
{ onClick={handleOnRightBtnClick} />
-
+
{ (_, index) => { return (
{cards diff --git a/src/components/favoritesPage/FavoriteSliderCard.tsx b/src/components/favoritesPage/FavoriteSliderCard.tsx index 4cd3564..60288a0 100644 --- a/src/components/favoritesPage/FavoriteSliderCard.tsx +++ b/src/components/favoritesPage/FavoriteSliderCard.tsx @@ -10,17 +10,21 @@ interface FavoriteSliderCardProps { const FavoriteSliderCard = ({ card, elementRef }: FavoriteSliderCardProps) => { return ( -
+
-
+

{card.apartmentType}, {card.square} Sqft

- +

Price

diff --git a/src/components/header/Auth/AuthDesktop.tsx b/src/components/header/Auth/AuthDesktop.tsx index dc67375..c9ade81 100644 --- a/src/components/header/Auth/AuthDesktop.tsx +++ b/src/components/header/Auth/AuthDesktop.tsx @@ -1,5 +1,6 @@ import useModal from "../../../store/useModal"; import Button from "../../Button"; +import AuthIcon from "../../icons/AuthIcon"; import LoginModal from "../../modals/LoginModal"; interface AuthProps { @@ -30,7 +31,12 @@ const AuthDesktop = ({ isAuth, userName }: AuthProps) => {
) : ( -
); diff --git a/src/components/header/Auth/AuthMobile.tsx b/src/components/header/Auth/AuthMobile.tsx index b60d4a5..8fb00ea 100644 --- a/src/components/header/Auth/AuthMobile.tsx +++ b/src/components/header/Auth/AuthMobile.tsx @@ -1,4 +1,5 @@ import Button from "../../Button"; +import AuthIcon from "../../icons/AuthIcon"; interface AuthProps { isAuth: boolean; @@ -17,7 +18,12 @@ const AuthMobile = ({ isAuth, userName }: AuthProps) => {
) : (
-
)} diff --git a/src/components/header/Header/DesktopHeader.tsx b/src/components/header/Header/DesktopHeader.tsx index ec0f21c..2f861a7 100644 --- a/src/components/header/Header/DesktopHeader.tsx +++ b/src/components/header/Header/DesktopHeader.tsx @@ -10,7 +10,7 @@ const DesktopHeader = () => (
- + ); diff --git a/src/components/icons/AuthIcon.tsx b/src/components/icons/AuthIcon.tsx new file mode 100644 index 0000000..32c095a --- /dev/null +++ b/src/components/icons/AuthIcon.tsx @@ -0,0 +1,20 @@ +const AuthIcon = () => { + return ( + + + + ); +}; + +export default AuthIcon; diff --git a/src/components/icons/VirtualTourIcon.tsx b/src/components/icons/VirtualTourIcon.tsx new file mode 100644 index 0000000..8d0097a --- /dev/null +++ b/src/components/icons/VirtualTourIcon.tsx @@ -0,0 +1,24 @@ +const VirtualTourIcon = () => { + return ( + + + + + ); +}; + +export default VirtualTourIcon; diff --git a/src/components/modals/MasterplanFilters.tsx b/src/components/modals/MasterplanFilters.tsx index cbe5d78..5045562 100644 --- a/src/components/modals/MasterplanFilters.tsx +++ b/src/components/modals/MasterplanFilters.tsx @@ -10,28 +10,45 @@ import { ICheckbox } from "../../types/checkbox"; import { IMultirangeSlider } from "../../types/multirangeSlider"; import { ISwitcher } from "../../types/switcher"; import { - initialCheckboxes, + initialAparmentTypeCheckboxes, initialSliders, initialSwitchers, + initialViewCheckboxes, } from "../../consts/initialMasterplanFilters"; const MasterplanFilters = () => { const { setModal } = useModal(); - const [checkboxes, setCheckboxes] = useState(initialCheckboxes); + const [apartmentTypeCheckbox, setAparmentTypeCheckboxes] = useState< + ICheckbox[] + >(initialAparmentTypeCheckboxes); + const [viewCheckboxes, setViewCheckboxes] = useState( + initialViewCheckboxes + ); const [sliders, setSliders] = useState(initialSliders); const [switchers, setSwitchers] = useState(initialSwitchers); const handleOnCloseClick = () => setModal(null); - const handleOnCheckboxClick = (checkboxId: string) => { - const updatedCheckboxes = checkboxes.map((cbox) => { + const handleOnApartmentTypeCheckboxClick = (checkboxId: string) => { + const updatedCheckboxes = apartmentTypeCheckbox.map((cbox) => { if (checkboxId !== cbox.id) return cbox; const isSelected = !cbox.selected; return { ...cbox, selected: isSelected }; }); - setCheckboxes(updatedCheckboxes); + setAparmentTypeCheckboxes(updatedCheckboxes); + }; + + const handleOnViewCheckboxClick = (checkboxId: string) => { + const updatedCheckboxes = viewCheckboxes.map((cbox) => { + if (checkboxId !== cbox.id) return cbox; + const isSelected = !cbox.selected; + + return { ...cbox, selected: isSelected }; + }); + + setViewCheckboxes(updatedCheckboxes); }; const handleOnSliderValueChange = ( @@ -63,33 +80,33 @@ const MasterplanFilters = () => { }; const handleOnResetClick = () => { - setCheckboxes(initialCheckboxes); + setAparmentTypeCheckboxes(initialAparmentTypeCheckboxes); + setViewCheckboxes(initialViewCheckboxes); setSliders(initialSliders); setSwitchers(initialSwitchers); }; return (
-
+

Filters

-

- Apartment type -

+

Apartment type

- {checkboxes.map((checkbox) => ( + {apartmentTypeCheckbox.map((checkbox) => ( ))}
@@ -98,12 +115,8 @@ const MasterplanFilters = () => { {sliders.map((slider) => (
-

- {slider.title} -

-

- {slider.unit} -

+

{slider.title}

+

{slider.unit}

{ ))}
+
+

View

+
+ {viewCheckboxes.map((checkbox) => ( + + ))} +
+
diff --git a/src/components/modals/SendEnquryModal.tsx b/src/components/modals/SendEnquryModal.tsx new file mode 100644 index 0000000..902db28 --- /dev/null +++ b/src/components/modals/SendEnquryModal.tsx @@ -0,0 +1,95 @@ +import useModal from "../../store/useModal"; +import Button from "../Button"; +import CrossIcon from "../icons/CrossIcon"; +import MasterInput from "../MasterInput"; +import MasterSelector from "../MasterSelector"; + +const SendEnquiryModal = () => { + const { setModal } = useModal(); + + const handleOnCloseClick = () => { + setModal(null); + }; + + return ( +
+
+
+
+

+ Apartment purchase enquiry +

+
+
+
+
+

+ 1 bedroom, 609 Sqft{" "} +

+

+ AED 1,668,888 +

+
+
+

1 bedroom, 609 Sqft

+
+
+

+ East Wing +

+
+

+ Floor 11 +

+
+

+ № 213 +

+
+
+
+
+
+

+ Specify the client data to send the request +

+
+ + + +
+
+
+
+
+

+ By clicking on the “Send” button, you accept the privacy policy and + consent to the processing of personal data. +

+
+
+
+ ); +}; + +export { SendEnquiryModal }; diff --git a/src/components/modals/mobile/MasterplanFiltersModal.tsx b/src/components/modals/mobile/MasterplanFiltersModal.tsx index 756bfb6..182bee5 100644 --- a/src/components/modals/mobile/MasterplanFiltersModal.tsx +++ b/src/components/modals/mobile/MasterplanFiltersModal.tsx @@ -9,16 +9,22 @@ import Switch from "../../Switch"; import ResetIcon from "../../icons/ResetIcon"; import { useSwipeable } from "react-swipeable"; import { - initialCheckboxes, + initialAparmentTypeCheckboxes, initialSliders, initialSwitchers, + initialViewCheckboxes, } from "../../../consts/initialMasterplanFilters"; +import { ICheckbox } from "../../../types/checkbox"; const MasterplanFiltersModal = () => { const { setModal } = useModal(); const { setIsAnimate } = useContext(MobileModalWrapperContext); - const [apartmentTypeCheckboxes, setApartmentTypeCheckboxes] = - useState(initialCheckboxes); + const [apartmentTypeCheckboxes, setApartmentTypeCheckboxes] = useState< + ICheckbox[] + >(initialAparmentTypeCheckboxes); + const [viewCheckboxes, setViewCheckboxes] = useState( + initialViewCheckboxes + ); const [switchers, setSwitchers] = useState(initialSwitchers); const [multirangeSliders, setMultirangeSliders] = useState(initialSliders); const handlers = useSwipeable({ @@ -70,6 +76,17 @@ const MasterplanFiltersModal = () => { setMultirangeSliders(updatedSliders); }; + const handleOnViewCheckboxClick = (checkboxId: string) => { + const updatedCheckboxes = viewCheckboxes.map((cbox) => { + if (checkboxId !== cbox.id) return cbox; + const isSelected = !cbox.selected; + + return { ...cbox, selected: isSelected }; + }); + + setViewCheckboxes(updatedCheckboxes); + }; + const handleOnShowApartmentClick = () => { if (setIsAnimate) { setIsAnimate(false); @@ -81,14 +98,15 @@ const MasterplanFiltersModal = () => { }; const handleOnResetClick = () => { + setViewCheckboxes(initialViewCheckboxes); setSwitchers(initialSwitchers); setMultirangeSliders(initialSliders); - setApartmentTypeCheckboxes(initialCheckboxes); + setApartmentTypeCheckboxes(initialAparmentTypeCheckboxes); }; return (
@@ -104,9 +122,7 @@ const MasterplanFiltersModal = () => { />
-

- Apartment type -

+

Apartment type

{apartmentTypeCheckboxes.map((checkbox) => ( { {multirangeSliders.map((slider) => (
-

- {slider.title} -

-

- {slider.unit} -

+

{slider.title}

+

{slider.unit}

{ ))}
+
+

Apartment type

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

195 apartments found

+
+
+
+ +
+
+

+ Studio Flex, 607,08 Sqft +

+

Rove Home Marasi Drive

+
+

East Wing

+
+

Floor 11

+
+

E-503

+
+
+
+

Total Area

+

607,08 Sqft

+
+
+

Suite Area

+

485,67 Sqft

+
+
+

Balcony Area

+

121,42 Sqft

+
+
+

Status

+

Available

+
+
+

Parking Space

+

1

+
+
+

+ AED 1,668,888 +

+
+
+
+
+

+ Specify the client data to send the request +

+
+ +
+
+ +
+
+ +
+
+
+
+
+

+ By clicking on the “Send” button, you accept the privacy policy and + consent to the processing of personal data. +

+
+
+ ); +}; + +export default SendEnquiryMobileModal; diff --git a/src/components/searchApartment/ApartmentLayout.tsx b/src/components/searchApartment/ApartmentLayout.tsx index c87627f..4ff8377 100644 --- a/src/components/searchApartment/ApartmentLayout.tsx +++ b/src/components/searchApartment/ApartmentLayout.tsx @@ -13,7 +13,7 @@ const ApartmentLayout = () => { setCurrentLabel(label); }; return ( -
+
{ + const navigate = useNavigate(); + + const handleOn3DTourClick = () => { + navigate(`../virtual-tour/apartments-studio-1`); + }; return (
-
+

View from window

@@ -14,7 +20,7 @@ const ApartmentSidebar = () => { />
-
+

Parameters

@@ -41,12 +47,13 @@ const ApartmentSidebar = () => {
-
+

AED 1,668,888