update
@@ -1,5 +1,5 @@
|
||||
# VITE_API_URL=http://localhost:4002
|
||||
VITE_API_URL=http://192.168.1.35:4002
|
||||
# VITE_API_URL=http://192.168.1.224:4002
|
||||
# VITE_API_URL=http://192.168.1.35:4002
|
||||
# VITE_API_URL=http://194.26.138.94:4002
|
||||
# VITE_API_URL=https://irthtest.online/api
|
||||
VITE_API_URL=https://irthtest.online/api
|
||||
# VITE_API_URL=https://irth.graff.estate/api
|
||||
@@ -11,6 +11,7 @@ lerna-debug.log*
|
||||
node_modules
|
||||
dist
|
||||
dist-ssr
|
||||
dist.zip
|
||||
*.local
|
||||
|
||||
public/virtual-tours
|
||||
|
||||
|
After Width: | Height: | Size: 225 KiB |
|
After Width: | Height: | Size: 250 KiB |
|
After Width: | Height: | Size: 334 KiB |
|
After Width: | Height: | Size: 385 KiB |
|
After Width: | Height: | Size: 287 KiB |
|
After Width: | Height: | Size: 284 KiB |
|
After Width: | Height: | Size: 334 KiB |
|
After Width: | Height: | Size: 385 KiB |
|
After Width: | Height: | Size: 287 KiB |
|
After Width: | Height: | Size: 284 KiB |
@@ -32,7 +32,7 @@ const constrainPosition = (
|
||||
position: Position,
|
||||
containerSize: Size,
|
||||
imageSize: Size,
|
||||
zoom: number,
|
||||
zoom: number
|
||||
): Position => {
|
||||
const scaledWidth = imageSize.width * zoom;
|
||||
const scaledHeight = imageSize.height * zoom;
|
||||
@@ -58,7 +58,7 @@ const constrainPosition = (
|
||||
};
|
||||
|
||||
const getEventPosition = (
|
||||
e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent,
|
||||
e: MouseEvent | TouchEvent | React.MouseEvent | React.TouchEvent
|
||||
): Position => {
|
||||
if ("touches" in e)
|
||||
return {
|
||||
@@ -83,7 +83,7 @@ const calculateMinZoom = (containerSize: Size, imageSize: Size): number => {
|
||||
const calculateCenterPosition = (
|
||||
containerSize: Size,
|
||||
imageSize: Size,
|
||||
zoom: number,
|
||||
zoom: number
|
||||
): Position => {
|
||||
const scaledWidth = imageSize.width * zoom;
|
||||
const scaledHeight = imageSize.height * zoom;
|
||||
@@ -161,7 +161,7 @@ function FloorSelect({
|
||||
newPosition,
|
||||
{ width: containerRect.width, height: containerRect.height },
|
||||
originalSize,
|
||||
newZoom,
|
||||
newZoom
|
||||
);
|
||||
|
||||
setImagePosition(constrainedPosition);
|
||||
@@ -194,7 +194,7 @@ function FloorSelect({
|
||||
// Check if we've moved beyond the threshold
|
||||
const distanceMoved = Math.hypot(
|
||||
x - dragStartPosition.current.x,
|
||||
y - dragStartPosition.current.y,
|
||||
y - dragStartPosition.current.y
|
||||
);
|
||||
|
||||
if (distanceMoved > dragThreshold) {
|
||||
@@ -251,7 +251,7 @@ function FloorSelect({
|
||||
const touch2 = e.touches[1];
|
||||
const distance = Math.hypot(
|
||||
touch1.clientX - touch2.clientX,
|
||||
touch1.clientY - touch2.clientY,
|
||||
touch1.clientY - touch2.clientY
|
||||
);
|
||||
initialTouchDistance.current = distance;
|
||||
previousTouchDistance.current = distance;
|
||||
@@ -285,7 +285,7 @@ function FloorSelect({
|
||||
const touch2 = e.touches[1];
|
||||
const distance = Math.hypot(
|
||||
touch1.clientX - touch2.clientX,
|
||||
touch1.clientY - touch2.clientY,
|
||||
touch1.clientY - touch2.clientY
|
||||
);
|
||||
|
||||
if (initialTouchDistance.current === null) {
|
||||
@@ -311,7 +311,7 @@ function FloorSelect({
|
||||
|
||||
const newZoom = Math.min(
|
||||
maxZoomRef.current,
|
||||
Math.max(minZoomRef.current, zoom * zoomFactor),
|
||||
Math.max(minZoomRef.current, zoom * zoomFactor)
|
||||
);
|
||||
|
||||
// Prevent zoom if at limits or change is too small
|
||||
@@ -353,7 +353,7 @@ function FloorSelect({
|
||||
// Check if we've moved beyond the threshold
|
||||
const distanceMoved = Math.hypot(
|
||||
x - dragStartPosition.current.x,
|
||||
y - dragStartPosition.current.y,
|
||||
y - dragStartPosition.current.y
|
||||
);
|
||||
|
||||
if (distanceMoved > dragThreshold) {
|
||||
@@ -426,7 +426,7 @@ function FloorSelect({
|
||||
|
||||
const newZoom = Math.min(
|
||||
maxZoomRef.current,
|
||||
Math.max(minZoomRef.current, zoom * zoomFactor),
|
||||
Math.max(minZoomRef.current, zoom * zoomFactor)
|
||||
);
|
||||
|
||||
// Prevent zoom if at limits or change is too small
|
||||
@@ -459,7 +459,7 @@ function FloorSelect({
|
||||
const centerPosition = calculateCenterPosition(
|
||||
{ width, height },
|
||||
originalSize,
|
||||
newMinZoom, // Сбрасываем к минимальному зуму (изображение на всю высоту)
|
||||
newMinZoom // Сбрасываем к минимальному зуму (изображение на всю высоту)
|
||||
);
|
||||
|
||||
setZoom(newMinZoom);
|
||||
@@ -493,7 +493,7 @@ function FloorSelect({
|
||||
const centerPosition = calculateCenterPosition(
|
||||
{ width, height },
|
||||
originalSize,
|
||||
newMinZoom, // Используем вычисленный минимальный зум
|
||||
newMinZoom // Используем вычисленный минимальный зум
|
||||
);
|
||||
setZoom(newMinZoom);
|
||||
setImagePosition(centerPosition);
|
||||
@@ -583,11 +583,7 @@ function FloorSelect({
|
||||
const { data } = useQuery({
|
||||
queryKey: ["floors-data", complexName],
|
||||
queryFn: () =>
|
||||
api
|
||||
.get(
|
||||
`units/get-floors-data/${complexName}`,
|
||||
)
|
||||
.json<FloorsData[]>(),
|
||||
api.get(`units/get-floors-data/${complexName}`).json<FloorsData[]>(),
|
||||
});
|
||||
|
||||
function handleFloorClick(floor: string) {
|
||||
@@ -606,7 +602,7 @@ function FloorSelect({
|
||||
data.some(
|
||||
(floorData) =>
|
||||
floorData.floor === +floor!.split(" ").at(-1)! ||
|
||||
floorData.floor === +floor!.split(" ").at(-1)!.split("-")[0],
|
||||
floorData.floor === +floor!.split(" ").at(-1)!.split("-")[0]
|
||||
) ||
|
||||
SPECIAL_FLOORS.includes(floor)
|
||||
)
|
||||
@@ -618,11 +614,11 @@ function FloorSelect({
|
||||
data.find(
|
||||
(floorData) =>
|
||||
floorData.floor === +floor!.split(" ").at(-1)! ||
|
||||
floorData.floor === +floor!.split(" ").at(-1)!.split("-")[0],
|
||||
floorData.floor === +floor!.split(" ").at(-1)!.split("-")[0]
|
||||
)!
|
||||
}
|
||||
onSelect={handleFloorClick}
|
||||
/>,
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -647,7 +643,7 @@ function FloorSelect({
|
||||
<div
|
||||
className={clsx(
|
||||
"overflow-hidden h-full w-full relative transition-transform duration-300",
|
||||
selectedFloor && "2xl:-translate-x-1/4",
|
||||
selectedFloor && "2xl:-translate-x-1/4"
|
||||
)}
|
||||
ref={rootRef}
|
||||
>
|
||||
@@ -661,7 +657,7 @@ function FloorSelect({
|
||||
"touch-none absolute inset-0 select-none will-change-[opacity,scale,transform] transition-opacity duration-300",
|
||||
isImageLoaded && originalSize.width !== 0
|
||||
? "opacity-100"
|
||||
: "opacity-0",
|
||||
: "opacity-0"
|
||||
)}
|
||||
style={{
|
||||
cursor: isMobile ? (isDragging ? "grabbing" : "grab") : "default",
|
||||
@@ -702,60 +698,64 @@ function FloorSelect({
|
||||
/>
|
||||
<g ref={ref}>
|
||||
{Object.entries(enumerationMasks[complexName]).map(
|
||||
([floorTitle, { x, y, width, height, d }]) =>
|
||||
Array.isArray(d) && Array.isArray(x) ? (
|
||||
<Fragment key={floorTitle}>
|
||||
<rect
|
||||
x={x[0]}
|
||||
y={y}
|
||||
width={width}
|
||||
height={height}
|
||||
rx={complexName === "marasi-drive" ? 14.2 : 10}
|
||||
fillOpacity={0.4}
|
||||
className={clsx(
|
||||
"transition-[fill] pointer-events-none",
|
||||
((hoveredFloor &&
|
||||
floorTitle ===
|
||||
(complexName === "dubai-marina"
|
||||
? hoveredFloor
|
||||
: SPECIAL_FLOORS.includes(hoveredFloor)
|
||||
? hoveredFloor
|
||||
: hoveredFloor.split(" ").at(-1)!)) ||
|
||||
selectedFloor?.split(" ").at(-1) === floorTitle) &&
|
||||
"fill-[#00BED7]",
|
||||
)}
|
||||
/>
|
||||
<path d={d[0]} className="pointer-events-none fill-white" />
|
||||
<rect
|
||||
x={x[1]}
|
||||
y={y}
|
||||
width={width}
|
||||
height={height}
|
||||
rx={complexName === "marasi-drive" ? 14.2 : 10}
|
||||
fillOpacity={0.4}
|
||||
className={clsx(
|
||||
"transition-[fill] pointer-events-none",
|
||||
((hoveredFloor &&
|
||||
floorTitle ===
|
||||
(complexName === "dubai-marina"
|
||||
? hoveredFloor
|
||||
: SPECIAL_FLOORS.includes(hoveredFloor)
|
||||
? hoveredFloor
|
||||
: hoveredFloor.split(" ").at(-1)!)) ||
|
||||
selectedFloor?.split(" ").at(-1) === floorTitle) &&
|
||||
"fill-[#00BED7]",
|
||||
)}
|
||||
/>
|
||||
<path d={d[1]} className="pointer-events-none fill-white" />
|
||||
</Fragment>
|
||||
([floorTitle, mask]) =>
|
||||
Array.isArray(mask) ? (
|
||||
mask.map(({ x, y, width, height, d }) => (
|
||||
<Fragment
|
||||
key={`${floorTitle}-${x}-${y}-${width}-${height}-${d}`}
|
||||
>
|
||||
<rect
|
||||
x={x}
|
||||
y={y}
|
||||
width={width}
|
||||
height={height}
|
||||
rx={height / 2}
|
||||
fillOpacity={0.4}
|
||||
className={clsx(
|
||||
"transition-[fill] pointer-events-none",
|
||||
((hoveredFloor &&
|
||||
floorTitle ===
|
||||
(complexName === "dubai-marina"
|
||||
? hoveredFloor
|
||||
: SPECIAL_FLOORS.includes(hoveredFloor)
|
||||
? hoveredFloor
|
||||
: hoveredFloor.split(" ").at(-1)!)) ||
|
||||
selectedFloor?.split(" ").at(-1) === floorTitle) &&
|
||||
"fill-[#00BED7]"
|
||||
)}
|
||||
/>
|
||||
<path d={d} className="fill-white pointer-events-none" />
|
||||
</Fragment>
|
||||
))
|
||||
) : (
|
||||
// <rect
|
||||
// x={x[1]}
|
||||
// y={y[1]}
|
||||
// width={width[1]}
|
||||
// height={height[1]}
|
||||
// rx={complexName === "marasi-drive" ? 14.2 : 10}
|
||||
// fillOpacity={0.4}
|
||||
// className={clsx(
|
||||
// "transition-[fill] pointer-events-none",
|
||||
// ((hoveredFloor &&
|
||||
// floorTitle ===
|
||||
// (complexName === "dubai-marina"
|
||||
// ? hoveredFloor
|
||||
// : SPECIAL_FLOORS.includes(hoveredFloor)
|
||||
// ? hoveredFloor
|
||||
// : hoveredFloor.split(" ").at(-1)!)) ||
|
||||
// selectedFloor?.split(" ").at(-1) === floorTitle) &&
|
||||
// "fill-[#00BED7]"
|
||||
// )}
|
||||
// />
|
||||
// <path d={d[1]} className="fill-white pointer-events-none" />
|
||||
<Fragment key={floorTitle}>
|
||||
<rect
|
||||
x={Array.isArray(x) ? x[0] : x}
|
||||
y={y}
|
||||
width={width}
|
||||
height={height}
|
||||
rx={complexName === "marasi-drive" ? 14.2 : 10}
|
||||
x={mask.x}
|
||||
y={mask.y}
|
||||
width={mask.width}
|
||||
height={mask.height}
|
||||
rx={mask.height / 2}
|
||||
fillOpacity={0.4}
|
||||
className={clsx(
|
||||
"transition-[fill] pointer-events-none",
|
||||
@@ -767,18 +767,18 @@ function FloorSelect({
|
||||
? hoveredFloor
|
||||
: hoveredFloor.split(" ").at(-1)!)) ||
|
||||
selectedFloor?.split(" ").at(-1) === floorTitle) &&
|
||||
"fill-[#00BED7]",
|
||||
"fill-[#00BED7]"
|
||||
)}
|
||||
/>
|
||||
<path
|
||||
d={d as string}
|
||||
className="pointer-events-none fill-white"
|
||||
d={mask.d}
|
||||
className="fill-white pointer-events-none"
|
||||
/>
|
||||
</Fragment>
|
||||
),
|
||||
)
|
||||
)}
|
||||
{Object.entries(
|
||||
floorsMasks[complexName as keyof typeof floorsMasks],
|
||||
floorsMasks[complexName as keyof typeof floorsMasks]
|
||||
).map(([floorTitle, d]) => (
|
||||
<path
|
||||
onMouseMove={!isMobile ? handleFloorMouseMove : undefined}
|
||||
@@ -802,7 +802,7 @@ function FloorSelect({
|
||||
SPECIAL_FLOORS.includes(floorTitle) ||
|
||||
complexName === "marasi-drive"
|
||||
? floorTitle
|
||||
: floorTitle.split(" ").at(-1)!,
|
||||
: floorTitle.split(" ").at(-1)!
|
||||
);
|
||||
|
||||
openPopup(
|
||||
@@ -810,7 +810,7 @@ function FloorSelect({
|
||||
!SPECIAL_FLOORS.includes(floorTitle) &&
|
||||
complexName === "marasi-drive"
|
||||
? (floorTitle.split(" ")[0] as "West" | "East")
|
||||
: undefined,
|
||||
: undefined
|
||||
);
|
||||
}
|
||||
}}
|
||||
@@ -819,7 +819,7 @@ function FloorSelect({
|
||||
SPECIAL_FLOORS.includes(floorTitle) ||
|
||||
complexName === "marasi-drive"
|
||||
? floorTitle
|
||||
: floorTitle.split(" ").at(-1)!,
|
||||
: floorTitle.split(" ").at(-1)!
|
||||
);
|
||||
if (!isMobile)
|
||||
openPopup(
|
||||
@@ -827,7 +827,7 @@ function FloorSelect({
|
||||
!SPECIAL_FLOORS.includes(floorTitle) &&
|
||||
complexName === "marasi-drive"
|
||||
? (floorTitle.split(" ")[0] as "West" | "East")
|
||||
: undefined,
|
||||
: undefined
|
||||
);
|
||||
}}
|
||||
onMouseLeave={() => {
|
||||
@@ -851,7 +851,7 @@ function FloorSelect({
|
||||
? floorTitle
|
||||
: floorTitle.split(" ").at(-1)!)
|
||||
? "opacity-60"
|
||||
: "opacity-20",
|
||||
: "opacity-20"
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -25,9 +25,7 @@ function UnitPage() {
|
||||
queryKey: ["unit", params.complexName, params.unitNumber],
|
||||
queryFn: () =>
|
||||
api
|
||||
.get(
|
||||
`units/${params.unitNumber}?project=${params.complexName}`
|
||||
)
|
||||
.get(`units/${params.unitNumber}?project=${params.complexName}`)
|
||||
.json<Unit>(),
|
||||
});
|
||||
|
||||
@@ -270,6 +268,29 @@ function UnitPage() {
|
||||
{/* <Button disabled variant="cta" size="large">
|
||||
Book
|
||||
</Button> */}
|
||||
|
||||
{/* videos for hq units */}
|
||||
{unit.projectSlug === "hq" &&
|
||||
[
|
||||
"loft-edge",
|
||||
"penthouse-loft",
|
||||
"presidential-loft",
|
||||
"studio",
|
||||
].includes(unit.unitTypeVariantSlug) && (
|
||||
<Button
|
||||
variant="cta"
|
||||
size="large"
|
||||
onClick={() =>
|
||||
setModal(
|
||||
<VideoModal
|
||||
src={`/videos/unit-types/hq/${unit.unitTypeVariantSlug}.mp4`}
|
||||
/>
|
||||
)
|
||||
}
|
||||
>
|
||||
Video tour
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||