This exceptional location mirrors our commitment to being at the
forefront of innovation and design, reflecting the very essence of
our brand. Just as The Opus stands as a testament to architectural
diff --git a/client/src/components/companyPage/OurValues/Slider.tsx b/client/src/components/companyPage/OurValues/Slider.tsx
index 9956eaf..f92e979 100644
--- a/client/src/components/companyPage/OurValues/Slider.tsx
+++ b/client/src/components/companyPage/OurValues/Slider.tsx
@@ -5,21 +5,20 @@ import { useLayoutEffect, useRef, useState } from "react";
import Button from "../../Button";
import LeftArrowSliderIcon from "../../icons/LeftArrowSliderIcon";
import RightArrowSliderIcon from "../../icons/RightArrowSliderIcon";
-// import { isMobile } from "react-device-detect";
-const isMobile = true;
+// const isMobile = true;
const images: Image[] = [
- { id: "1", src: "./images/company/slider/1.png" },
- { id: "2", src: "./images/company/slider/2.png" },
- { id: "3", src: "./images/company/slider/3.png" },
+ { id: "img-1", src: "./images/company/slider/1.png" },
+ { id: "img-2", src: "./images/company/slider/2.png" },
+ { id: "img-3", src: "./images/company/slider/3.png" },
];
-const getGapOffset = (screenWidth: number) => {
- if (screenWidth > 1600) return 16;
- if (screenWidth > 1280) return 24;
- if (screenWidth > 640) return 16;
- return 16;
-};
+// const getGapOffset = (screenWidth: number) => {
+// if (screenWidth > 1600) return 16;
+// if (screenWidth > 1280) return 24;
+// if (screenWidth > 640) return 16;
+// return 16;
+// };
const Slider = () => {
const [selectedImageIndex, setSelectedImageIndex] = useState(-1);
@@ -34,15 +33,11 @@ const Slider = () => {
}, [imageRef.current, window.innerWidth]);
useLayoutEffect(() => {
- const screenWidth = window.innerWidth;
- const gapOffset = getGapOffset(screenWidth);
+ const gapOffset = 45;
- const _rightImageOffset =
- screenWidth > 1280
- ? `${"calc(clamp(315px, 6.9317rem + 17.0319vw, 420px)"} + ${
- selectedImageIndex * (imageWidth + gapOffset)
- }px)`
- : `${(selectedImageIndex + 1) * (imageWidth + gapOffset)}px`;
+ const _rightImageOffset = `${
+ (selectedImageIndex + 1) * (imageWidth + gapOffset)
+ }px`;
setRightImageOffset(_rightImageOffset);
}, [imageWidth, selectedImageIndex, window.innerWidth]);
@@ -54,7 +49,7 @@ const Slider = () => {
});
function next() {
- const lastIndex = isMobile ? images.length - 2 : images.length - 3;
+ const lastIndex = images.length - 2;
if (selectedImageIndex === lastIndex) return;
setSelectedImageIndex((prev) => prev + 1);
@@ -69,10 +64,10 @@ const Slider = () => {
{
src={image.src}
alt=""
key={image.id}
- className="rounded-2xl sm:aspect-[6/5] object-cover 2xl:w-[calc(100vw*1/2)] xl:w-[calc(100vw*5/12)] pointer-events-none select-none w-[calc(100%-16px)]"
+ className="rounded-2xl object-cover pointer-events-none select-none w-[1493.44px]"
/>
))}
-
}
- className="absolute text-[#73787C] top-[calc(50%-22px)] xl:left-slider-btn-offset left-6 hidden sm:block"
- />
-
}
- className="absolute text-[#73787C] top-[calc(50%-22px)] right-6 hidden sm:block"
- />
-
-
- {images.map((image, index) => (
-
- ))}
+
+ }
+ className="text-[#73787C]"
+ />
+
+
+ }
+ className="text-[#73787C]"
+ />
+
);
diff --git a/client/src/components/complexPage/ComplexTopPanel.tsx b/client/src/components/complexPage/ComplexTopPanel.tsx
index a29496f..6745623 100644
--- a/client/src/components/complexPage/ComplexTopPanel.tsx
+++ b/client/src/components/complexPage/ComplexTopPanel.tsx
@@ -5,7 +5,6 @@ import FilterIcon from "../icons/FilterIcon";
import HintIcon from "../icons/HintIcon";
import LeftArrowSliderIcon from "../icons/LeftArrowSliderIcon";
import ResizeIcon from "../icons/ResizeIcon";
-import HelpModal from "../modals/HelpModal";
// import MasterplanFilters from "../modals/MasterplanFilters";
import InfoIcon from "../icons/InfoIcon";
import useFullScreen from "../../store/useFullScreen";
@@ -13,6 +12,7 @@ import ActiveResizeIcon from "../icons/ActiveResizeIcon";
import useWingSidebar from "../../store/useWingSidebar";
import { MobileModalWrapper } from "../modals/mobile/MobileModalWrapper";
import MasterplanFiltersModal from "../modals/mobile/MasterplanFiltersModal";
+import MobileHelpModal from "../modals/mobile/MobileHelpModal";
const ComplexTopPanel = () => {
const { setModal, modal } = useModal();
@@ -21,7 +21,12 @@ const ComplexTopPanel = () => {
const navigate = useNavigate();
const handleOnHelpClick = () => {
- setModal(
);
+ // setModal(
);
+ setModal(
+
+
+
+ );
};
// const handleOnFiltersClick = () => {
diff --git a/client/src/components/icons/DisclaimerIcon.tsx b/client/src/components/icons/DisclaimerIcon.tsx
index 889b84e..8015f05 100644
--- a/client/src/components/icons/DisclaimerIcon.tsx
+++ b/client/src/components/icons/DisclaimerIcon.tsx
@@ -14,7 +14,7 @@ const DisclaimerIcon = () => {
{
d="M10 14.1665V9.1665"
stroke="currentColor"
stroke-width="1.5"
- stroke-linecap="round"
+ strokeLinecap="round"
/>
{
);
diff --git a/client/src/components/icons/RightArrowSliderIcon.tsx b/client/src/components/icons/RightArrowSliderIcon.tsx
index 2ef2f60..40a3796 100644
--- a/client/src/components/icons/RightArrowSliderIcon.tsx
+++ b/client/src/components/icons/RightArrowSliderIcon.tsx
@@ -10,9 +10,9 @@ const RightArrowSliderIcon = () => {
);
diff --git a/client/src/components/masterplanPage/TopPanel.tsx b/client/src/components/masterplanPage/TopPanel.tsx
index 72d5484..f172a58 100644
--- a/client/src/components/masterplanPage/TopPanel.tsx
+++ b/client/src/components/masterplanPage/TopPanel.tsx
@@ -3,15 +3,21 @@ import useModal from "../../store/useModal";
import Button from "../Button";
import HintIcon from "../icons/HintIcon";
import ResizeIcon from "../icons/ResizeIcon";
-import HelpModal from "../modals/HelpModal";
import ActiveResizeIcon from "../icons/ActiveResizeIcon";
+import MobileHelpModal from "../modals/mobile/MobileHelpModal";
+import { MobileModalWrapper } from "../modals/mobile/MobileModalWrapper";
const TopPanel = () => {
const { setModal } = useModal();
const { onFullscreen, isFullscreen, setIsFullscreen } = useFullScreen();
const handleOnHelpClick = () => {
- setModal( );
+ // setModal( );
+ setModal(
+
+
+
+ );
};
const handleOnFullScreenClick = () => {
diff --git a/client/src/components/modals/VirtualTourVideoModal.tsx b/client/src/components/modals/VirtualTourVideoModal.tsx
index f1cc726..18ade2e 100644
--- a/client/src/components/modals/VirtualTourVideoModal.tsx
+++ b/client/src/components/modals/VirtualTourVideoModal.tsx
@@ -15,10 +15,10 @@ const VirtualTourVideoModal = ({ videoHref }: VirtualTourVideoModalProps) => {
return (
-
+
diff --git a/client/src/components/modals/mobile/MobileHelpModal.tsx b/client/src/components/modals/mobile/MobileHelpModal.tsx
new file mode 100644
index 0000000..7ba9166
--- /dev/null
+++ b/client/src/components/modals/mobile/MobileHelpModal.tsx
@@ -0,0 +1,205 @@
+import { useSwipeable } from "react-swipeable";
+import Button from "../../Button";
+import CrossIcon from "../../icons/CrossIcon";
+import { ISlider } from "../../../types/slide";
+import { useState, useRef, useLayoutEffect, useContext } from "react";
+import LeftArrowSliderIcon from "../../icons/LeftArrowSliderIcon";
+import RightArrowSliderIcon from "../../icons/RightArrowSliderIcon";
+import { MobileModalWrapperContext } from "./MobileModalWrapper";
+import useModal from "../../../store/useModal";
+
+const tipsSlides: ISlider[] = [
+ {
+ id: "tps-sld-1",
+ src: "/images/masterplan/help/1.png",
+ title: "1. Workspace",
+ desc: "For more comfortable work with the general plan, size it to the full screen.",
+ },
+ {
+ id: "tps-sld-2",
+ src: "/images/masterplan/help/1.png",
+ title: "2. Filter on the master plan",
+ desc: "Filter the apartments in the project by required parameters.",
+ },
+ {
+ id: "tps-sld-3",
+ src: "/images/masterplan/help/1.png",
+ title: "3. Take a closer look at the project",
+ desc: "Learn more about the project, surrounding infrastructure and apartment features.",
+ },
+ {
+ id: "tps-sld-4",
+ src: "/images/masterplan/help/1.png",
+ title: "4. Look for apartments",
+ desc: "Use the search to select an apartment that suits you, add it to your favorites and compare.",
+ },
+];
+
+const MobileHelpModal = () => {
+ const [imageWidth] = useState(0);
+ const imageRef = useRef(null);
+ const [selectedImageIndex, setSelectedImageIndex] = useState(-1);
+ const [rightImageOffset, setRightImageOffset] = useState("");
+ const { setIsAnimate } = useContext(MobileModalWrapperContext);
+ const { setModal } = useModal();
+
+ const handlers = useSwipeable({
+ onSwipedDown: () => handleOnCloseClick(),
+ onSwipedLeft: next,
+ onSwipedRight: prev,
+ });
+ const handleOnCloseClick = () => {
+ if (setIsAnimate) {
+ setIsAnimate(false);
+ const timeout = setTimeout(() => {
+ setModal(null);
+ clearTimeout(timeout);
+ }, 300);
+ }
+ };
+
+ function next() {
+ const lastIndex = tipsSlides.length - 2;
+
+ if (selectedImageIndex === lastIndex) return;
+ setSelectedImageIndex((prev) => prev + 1);
+ }
+
+ function prev() {
+ if (selectedImageIndex === -1) return;
+ setSelectedImageIndex((prev) => prev - 1);
+ }
+
+ useLayoutEffect(() => {
+ const gapOffset = 45;
+
+ const _rightImageOffset = `${
+ (selectedImageIndex + 1) * (imageWidth + gapOffset)
+ }px`;
+
+ setRightImageOffset(_rightImageOffset);
+ }, [
+ imageWidth,
+ selectedImageIndex,
+ window.innerWidth,
+ imageRef.current?.width,
+ ]);
+
+ return (
+
+
+
+ Tips for working
+
+ }
+ className="text-[#0D1922B2]"
+ onClick={handleOnCloseClick}
+ />
+
+
+
+ {tipsSlides.map((image) => (
+
+
+
+ {image.title}
+
+
+ {image.desc}
+
+
+ ))}
+
+
+
+
}
+ buttonType="fab"
+ className="text-black"
+ />
+
+
}
+ buttonType="fab"
+ className="text-black"
+ />
+
+
+ );
+
+ // return
+ //
+ //
+ //
+ //
+ // Tips for working
+ //
+ // }
+ // buttonType="fab"
+ // onClick={handleOnCloseClick}
+ // isCircleRounded
+ // />
+ //
+ //
+ //
+ //
1. Workspace
+ //
+ // For more comfortable work with the general plan, size it to the
+ // full screen.
+ //
+ //
+ //
+ //
+ //
}
+ // buttonType="fab"
+ // className="text-black"
+ // />
+ //
+ //
+ //
+ //
+ //
+ //
+ //
+ //
}
+ // buttonType="fab"
+ // className="text-black"
+ // />
+ //
+ //
+ //
;
+};
+
+export default MobileHelpModal;
diff --git a/client/src/components/virtualTour/ButtomPanelCompassVirualTour.tsx b/client/src/components/virtualTour/ButtomPanelCompassVirualTour.tsx
index 0d980da..b2d5ed5 100644
--- a/client/src/components/virtualTour/ButtomPanelCompassVirualTour.tsx
+++ b/client/src/components/virtualTour/ButtomPanelCompassVirualTour.tsx
@@ -32,7 +32,7 @@ const ButtomPanelCompassVirtualTour = () => {
style={{ transform: `rotate(${currentCompassRotate - 180}deg)` }}
src="/images/masterplan/compass.png"
alt="compass"
- className=""
+ className="zoom-280"
/>
diff --git a/client/src/components/virtualTour/LabelMarker.tsx b/client/src/components/virtualTour/LabelMarker.tsx
index b3b460e..d7f5694 100644
--- a/client/src/components/virtualTour/LabelMarker.tsx
+++ b/client/src/components/virtualTour/LabelMarker.tsx
@@ -12,7 +12,7 @@ const LabelMarker = ({ sphereLink, apartment }: LaberlMarkerProps) => {
return (
<>
{
-
+
{sphereLink.type === "default" && (
)}
diff --git a/client/src/components/virtualTour/VirtualTourSidebar.tsx b/client/src/components/virtualTour/VirtualTourSidebar.tsx
index 42df908..e124138 100644
--- a/client/src/components/virtualTour/VirtualTourSidebar.tsx
+++ b/client/src/components/virtualTour/VirtualTourSidebar.tsx
@@ -103,9 +103,9 @@ const VirtualTourSidebar = ({
return (
-
+
-
+
}
buttonType="secondary"
@@ -113,7 +113,7 @@ const VirtualTourSidebar = ({
onClick={handleOnBackClick}
/>
{/*
*/}
-
+
{apartment
? `${apartment?.Unit_Type}, ${Math.round(
apartment?.Total_Area_Sqft
@@ -152,16 +152,12 @@ const VirtualTourSidebar = ({
isActive ? "my-4" : ""
} relative flex justify-center`}
>
-
+
@@ -234,7 +230,7 @@ const VirtualTourSidebar = ({
className="transition-all duration-300 bg-[#FFFFFFCC] px-4 py-3 w-fit h-12 rounded-ee-lg rounded-es-lg select-none cursor-pointer pointer-events-auto items-start border border-t-[#0D1922B2] active:border-[#00BED7] hover:bg-[#FFFFFF] text-[#0D1922B2] hover:text-[#0D1922]"
>
-
+
{
return (
<>
{isFullscreen ? (
diff --git a/client/src/components/virtualTour/VirtualTourWrapper.tsx b/client/src/components/virtualTour/VirtualTourWrapper.tsx
index 2fca124..27f1234 100644
--- a/client/src/components/virtualTour/VirtualTourWrapper.tsx
+++ b/client/src/components/virtualTour/VirtualTourWrapper.tsx
@@ -1,5 +1,5 @@
import { OrbitControls, Html } from "@react-three/drei";
-import { Suspense, useEffect, useRef } from "react";
+import { Fragment, Suspense, useEffect, useRef } from "react";
import { OrbitControls as OrbitControlsImpl } from "three-stdlib";
import useCompass from "../../store/useCompass";
import SphereTour from "./SphereTour";
@@ -42,16 +42,20 @@ const VirtualTourWrapper = ({ appartment }: VirtualTourWrapperProps) => {
selectedSphere && sphere.id === selectedSphere.id;
return (
- <>
+
{isLabelContains &&
sphere.links.map((sphereLink) => (
-
+
))}
- >
+
);
})}
{
return (
-
-
+
+
IRTH is a privately held real estate investment platform part of a large
local family conglomerate from Dubai
-
+
IRTHS’s real estate portfolio is spread across numerous projects, below
is a snapshot of some of our current and previous investments
diff --git a/client/src/types/slide.ts b/client/src/types/slide.ts
new file mode 100644
index 0000000..0bd1dd7
--- /dev/null
+++ b/client/src/types/slide.ts
@@ -0,0 +1,8 @@
+interface ISlider {
+ src: string;
+ id: string;
+ desc: string;
+ title: string;
+}
+
+export type { ISlider };
diff --git a/client/tailwind.config.js b/client/tailwind.config.js
index 8096a12..69182a0 100644
--- a/client/tailwind.config.js
+++ b/client/tailwind.config.js
@@ -12,6 +12,7 @@ export default {
2: "4.8px",
},
padding: {
+ 5: "56.25px",
8: "90px",
6: "67.5px",
1: "11.25px",
@@ -20,9 +21,12 @@ export default {
2: "22.5px",
16: "180px",
14: "157.5px",
+ 7: "56px",
},
margin: {
+ 5: "56.25px",
14: "157.5px",
+ 7: "56px",
8: "90px",
6: "67.5px",
1: "11.25px",
@@ -45,6 +49,7 @@ export default {
16: "180px",
},
height: {
+ 12: "135px",
6: "57.6px",
3: "33.75px",
16: "180px",