This commit is contained in:
2024-09-16 20:19:22 +05:00
parent 1901aad2b7
commit ea19d1e43a
16 changed files with 335 additions and 704 deletions
+2 -2
View File
@@ -3,15 +3,15 @@ import { ISwitchLabel } from "../types/switchLabel";
interface ISwitchToggleProps {
labels: ISwitchLabel[];
currentLabel: ISwitchLabel;
onClick: (label: ISwitchLabel) => void;
isDisabled?: boolean;
onClick: (label: ISwitchLabel) => void;
}
function SwitchToggle({
labels,
currentLabel,
onClick,
isDisabled = false,
onClick,
}: ISwitchToggleProps) {
return (
<div className="flex bg-[#F3F3F2] rounded-lg">
+5 -16
View File
@@ -1,5 +1,6 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useEffect, useRef, useState } from "react";
import { isMobile } from "react-device-detect";
interface Props {
floor: string;
@@ -8,23 +9,11 @@ interface Props {
function FloorItem({ floor, onSelected }: Props) {
const [selected, setSelected] = useState(false);
// const [ref, entry] = useIntersectionObserver({
// threshold: 0,
// root: document.querySelector("#test"),
// rootMargin: "0px",
// });
// console.log(document.querySelector("#test"));
// useEffect(() => {
// if (!entry?.isIntersecting) return;
// onSelected();
// }, [entry?.isIntersecting]);
const ref = useRef<HTMLParagraphElement>(null);
useEffect(() => {
if (!isMobile) return;
const test = document.querySelector("#test")!.getBoundingClientRect();
setInterval(() => {
@@ -37,13 +26,13 @@ function FloorItem({ floor, onSelected }: Props) {
} else {
setSelected(false);
}
}, 0);
}, 50);
}, []);
return (
<p
ref={ref}
className={`snap-center w-4 h-4 flex items-center justify-center text-xs font-semibold transition-[color,transform] ${
className={`snap-center min-w-[68px] w-[68px] h-4 flex items-center justify-center text-xs font-semibold transition-[color,transform] whitespace-nowrap ${
selected ? "text-[#00BED7] scale-125" : ""
}`}
>
@@ -2437,7 +2437,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}16`}
{`E-${floor}16`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
@@ -2464,7 +2464,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}15`}
{`E-${floor}15`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
@@ -2491,7 +2491,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}14`}
{`E-${floor}14`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
@@ -2518,7 +2518,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}13`}
{`E-${floor}13`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
@@ -2545,7 +2545,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}12`}
{`E-${floor}12`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
@@ -2572,7 +2572,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}11`}
{`E-${floor}11`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
@@ -2599,7 +2599,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}10`}
{`E-${floor}10`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
@@ -2626,7 +2626,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}09`}
{`E-${floor}09`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
@@ -2653,7 +2653,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}08`}
{`E-${floor}08`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
@@ -2680,7 +2680,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}07`}
{`E-${floor}07`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
@@ -2708,7 +2708,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}06`}
{`E-${floor}06`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
@@ -2735,7 +2735,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}05`}
{`E-${floor}05`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
@@ -2762,7 +2762,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}04`}
{`E-${floor}04`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
@@ -2789,7 +2789,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}03`}
{`E-${floor}03`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
@@ -2816,7 +2816,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}02`}
{`E-${floor}02`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
@@ -2843,7 +2843,7 @@ function EastWingFloorPlan({
}}
>
<tspan x={0} y={0}>
{`E-${floor.padStart(2, "0")}01`}
{`E-${floor}01`}
</tspan>
<tspan x={0} y={10.8}>
{"2BR"}
@@ -11,19 +11,49 @@ import { isMobile } from "react-device-detect";
import WestWingFloorPlanLower from "./WestWingFloorPlanLower";
import WestWingFloorPlanUpper from "./WestWingFloorPlanUpper";
import EastWingFloorPlan from "./EastWingFloorPlan";
import PlayIcon from "../../icons/PlayIcon";
import SwitchToggle from "../../SwitchToggle";
import AmphitheatreIcon from "../../icons/activities/AmphitheatreIcon";
import BoulderingWallIcon from "../../icons/activities/BoulderingWallIcon";
import ChangingRoomsIcon from "../../icons/activities/ChangingRoomsIcon";
import ChessTablesIcon from "../../icons/activities/ChessTablesIcon";
import ClimbingRoomIcon from "../../icons/activities/ClimbingRoomIcon";
import CommunalDiningTablesIcon from "../../icons/activities/CommunalDiningTablesIcon";
import IndoorLapPoolIcon from "../../icons/activities/IndoorLapPoolIcon";
import LushLandscapeIcon from "../../icons/activities/LushLandscapeIcon";
import MultiPurposeCourtIcon from "../../icons/activities/MultiPurposeCourtIcon";
import OutdoorCinemaIcon from "../../icons/activities/OutdoorCinemaIcon";
import OutdoorCoworkingSpaceIcon from "../../icons/activities/OutdoorCoworkingSpaceIcon";
import PadelPongIcon from "../../icons/activities/PadelPongIcon";
import PingPongInATableIcon from "../../icons/activities/PingPongInATableIcon";
import RunningWheelIcon from "../../icons/activities/RunningWheelIcon";
import SunLoungingDeckIcon from "../../icons/activities/SunLoungingDeckIcon";
import SuspendedLoungingNetsIcon from "../../icons/activities/SuspendedLoungingNetsIcon";
import WellnessFeaturesIcon from "../../icons/activities/WellnessFeaturesIcon";
import ActivityCard from "../SkygardenSidebar/ActivityCard";
import SkyGardenSlider from "../SkygardenSidebar/SkyGardenSlider";
import VirtualTourVideoModal from "../../modals/VirtualTourVideoModal";
interface Props {
floor: number;
floor: string;
wing: string;
onClose: () => void;
}
const skyGardenImages = {
indoor: "/images/skyGarden/sky-garden-indoor.jpg",
outdoor: "/images/skyGarden/sky-garden-outdoor.jpg",
};
function FloorPlanSidebar({ floor, wing, onClose }: Props) {
const { setModal } = useModal();
const [hoveredUnit, setHoveredUnit] = useState<IUnit | undefined>();
const [showPopup, setShowPopup] = useState(false);
const [mousePos, setMousePos] = useState<[number, number]>([0, 0]);
const [type, setType] = useState<string | null>(null);
const [selectedSkyGardenImage, setSelectedSkyGardenImage] = useState<
"indoor" | "outdoor"
>("indoor");
function handleMouseEnter(e: React.MouseEvent<SVGPathElement>) {
const unitNumber = e.currentTarget.dataset.number;
@@ -46,14 +76,12 @@ function FloorPlanSidebar({ floor, wing, onClose }: Props) {
const x = e.clientX - e.currentTarget.getBoundingClientRect().left;
const y = e.clientY - e.currentTarget.getBoundingClientRect().top;
console.log(x, y);
setMousePos([x, y]);
}
function handleClick() {
console.log("hoveredUnit", hoveredUnit);
console.log("type", type);
// console.log("hoveredUnit", hoveredUnit);
// console.log("type", type);
if (!hoveredUnit || !type) return;
@@ -79,7 +107,7 @@ function FloorPlanSidebar({ floor, wing, onClose }: Props) {
}, [hoveredUnit]);
return (
<div className="flex flex-col flex-1 gap-4 p-4 select-none sm:p-6 mt-14">
<div className="flex flex-col flex-1 gap-4 p-4 overflow-y-auto select-none sm:p-6 mt-14">
<div className="flex items-start justify-between">
<div>
<p
@@ -87,9 +115,11 @@ function FloorPlanSidebar({ floor, wing, onClose }: Props) {
floor ? "opacity-100" : "opacity-0"
}`}
>
{floor} floor
{floor === "Sky Garden" ? "Sky Garden" : `${floor} floor`}
</p>
<p className="text-sm">
{floor === "Sky Garden" ? `22-23 floor` : `${wing} Wing`}
</p>
<p className="text-sm">{wing} Wing</p>
</div>
<Button3
icon={<CloseIcon className="w-5 h-5" />}
@@ -97,68 +127,205 @@ function FloorPlanSidebar({ floor, wing, onClose }: Props) {
onClick={onClose}
/>
</div>
<div className="flex flex-col flex-1 space-y-2 max-sm:w-screen max-sm:-m-4">
<div className="flex items-center justify-end p-4 bg-white xl:justify-between rounded-2xl max-xl:hidden">
<div className="flex gap-6 max-xl:hidden">
<div className="flex items-center gap-2">
<div className="w-5 h-5 text-white rounded-full bg-[#A19E9E] text-xs flex items-center justify-center"></div>
<p className="text-xs font-semibold">Studio Flex</p>
</div>
<div className="flex items-center gap-2">
<div className="w-5 h-5 text-white rounded-full bg-[#8299AD] text-xs flex items-center justify-center"></div>
<p className="text-xs font-semibold">Studio²</p>
</div>
<div className="flex items-center gap-2">
<div className="w-5 h-5 text-white rounded-full bg-[#BFC9D1] text-xs flex items-center justify-center"></div>
<p className="text-xs font-semibold">1 Bedroom²</p>
</div>
<div className="flex items-center gap-2">
<div className="w-5 h-5 text-white rounded-full bg-[#878FA3] text-xs flex items-center justify-center"></div>
<p className="text-xs font-semibold">2 Bedroom²</p>
{floor === "Sky Garden" ? (
<div className="space-y-6">
<div className="pb-6 border-b border-[#E2E2DC]">
<div className="relative flex flex-col p-6 bg-white rounded-2xl">
<Button3
variant="secondary"
icon={<PlayIcon />}
className="absolute self-end max-sm:hidden"
onClick={() =>
setModal(
<VirtualTourVideoModal videoHref="/videos/SkyGarden.mp4" />
)
}
>
Play video
</Button3>
<Button3
variant="secondary"
icon={<PlayIcon />}
onlyIcon
size="small"
className="absolute self-end sm:hidden"
onClick={() =>
setModal(
<VirtualTourVideoModal videoHref="/videos/SkyGarden.mp4" />
)
}
/>
<div className="flex flex-col gap-10">
<div className="px-4">
<img
src={skyGardenImages[selectedSkyGardenImage]}
alt=""
className="pointer-events-none"
/>
</div>
<div className="self-center">
<SwitchToggle
labels={[
{ id: "indoor", label: "Indoor" },
{ id: "outdoor", label: "Outdoor" },
]}
currentLabel={
selectedSkyGardenImage === "indoor"
? { id: "indoor", label: "Indoor" }
: { id: "outdoor", label: "Outdoor" }
}
onClick={(label) =>
setSelectedSkyGardenImage(
label.id as "indoor" | "outdoor"
)
}
/>
</div>
</div>
</div>
</div>
{/* <div className="text-xs text-white rounded-full bg-[#00BED7] px-2 py-[3px] ">
<div className="pb-6 space-y-6 border-b border-[#E2E2DC]">
<p className="sm:text-xl text-[#0D1922] font-semibold">
Indoor Amenities
</p>
<div className="grid grid-cols-3 gap-4 sm:grid-cols-4">
<ActivityCard
title={"Indoor Lap Pool"}
icon={<IndoorLapPoolIcon />}
/>
<ActivityCard
title={"Wellness Features"}
icon={<WellnessFeaturesIcon />}
/>
<ActivityCard
title={"Changing Rooms"}
icon={<ChangingRoomsIcon />}
/>
</div>
</div>
<div className="pb-6 space-y-6 border-b border-[#E2E2DC]">
<p className="sm:text-xl text-[#0D1922] font-semibold">
Outdoor Amenities
</p>
<div className="grid grid-cols-3 sm:grid-cols-4 gap-x-4 gap-y-6">
<ActivityCard title={"Padel Pong"} icon={<PadelPongIcon />} />
<ActivityCard
title={"Sun Lounging Deck"}
icon={<SunLoungingDeckIcon />}
/>
<ActivityCard
title={"Outdoor Cinema"}
icon={<OutdoorCinemaIcon />}
/>
<ActivityCard
title={"Bouldering Wall"}
icon={<BoulderingWallIcon />}
/>
<ActivityCard
title={"Ping Pong in a Tube"}
icon={<PingPongInATableIcon />}
/>
<ActivityCard
title={"Amphitheatre"}
icon={<AmphitheatreIcon />}
/>
<ActivityCard
title={"Communal Dining Tables"}
icon={<CommunalDiningTablesIcon />}
/>
<ActivityCard
title={"Suspended Lounging Nets "}
icon={<SuspendedLoungingNetsIcon />}
/>
<ActivityCard
title={"Lush Landscape"}
icon={<LushLandscapeIcon />}
/>
<ActivityCard
title={"Running Wheel"}
icon={<RunningWheelIcon />}
/>
<ActivityCard title={"Chess Tables"} icon={<ChessTablesIcon />} />
<ActivityCard
title={"Climbing Wall"}
icon={<ClimbingRoomIcon />}
/>
<ActivityCard
title={"Outdoor Coworking Space"}
icon={<OutdoorCoworkingSpaceIcon />}
/>
<ActivityCard
title={"Multi-purpose Court"}
icon={<MultiPurposeCourtIcon />}
/>
</div>
</div>
<SkyGardenSlider />
</div>
) : (
<div className="flex flex-col flex-1 space-y-2 max-sm:w-screen max-sm:-m-4">
<div className="flex items-center justify-end p-4 bg-white xl:justify-between rounded-2xl max-xl:hidden">
<div className="flex gap-6 max-xl:hidden">
<div className="flex items-center gap-2">
<div className="w-5 h-5 text-white rounded-full bg-[#A19E9E] text-xs flex items-center justify-center"></div>
<p className="text-xs font-semibold">Studio Flex</p>
</div>
<div className="flex items-center gap-2">
<div className="w-5 h-5 text-white rounded-full bg-[#8299AD] text-xs flex items-center justify-center"></div>
<p className="text-xs font-semibold">Studio²</p>
</div>
<div className="flex items-center gap-2">
<div className="w-5 h-5 text-white rounded-full bg-[#BFC9D1] text-xs flex items-center justify-center"></div>
<p className="text-xs font-semibold">1 Bedroom²</p>
</div>
<div className="flex items-center gap-2">
<div className="w-5 h-5 text-white rounded-full bg-[#878FA3] text-xs flex items-center justify-center"></div>
<p className="text-xs font-semibold">2 Bedroom²</p>
</div>
</div>
{/* <div className="text-xs text-white rounded-full bg-[#00BED7] px-2 py-[3px] ">
0 units
</div> */}
</div>
<div className="relative flex flex-1 sm:bg-white rounded-2xl">
<svg className="flex-1 p-2 sm:p-10" onMouseMove={handleMouseMove}>
{wing === "West" ? (
floor <= 21 ? (
<WestWingFloorPlanLower
floor={floor.toString().padStart(2, "0")}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
/>
</div>
<div className="relative flex flex-1 sm:bg-white rounded-2xl">
<svg className="flex-1 p-2 sm:p-10" onMouseMove={handleMouseMove}>
{wing === "West" ? (
+floor <= 21 ? (
<WestWingFloorPlanLower
floor={floor}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
/>
) : (
<WestWingFloorPlanUpper
floor={floor}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
/>
)
) : (
<WestWingFloorPlanUpper
floor={floor.toString().padStart(2, "0")}
<EastWingFloorPlan
floor={floor}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
/>
)
) : (
<EastWingFloorPlan
floor={floor.toString()}
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
onClick={handleClick}
)}
</svg>
{!isMobile && (
<UnitPopup
unit={hoveredUnit}
type={type}
show={showPopup}
mousePos={mousePos}
/>
)}
</svg>
{!isMobile && (
<UnitPopup
unit={hoveredUnit}
type={type}
show={showPopup}
mousePos={mousePos}
/>
)}
</div>
</div>
</div>
)}
</div>
);
}
@@ -5,8 +5,8 @@ interface ActivityCardProps {
const ActivityCard = ({ icon, title }: ActivityCardProps) => {
return (
// <div className="bg-white rounded-2xl flex flex-col gap-9 p-3">
// <div className="flex gap-2 items-center">
// <div className="flex flex-col p-3 bg-white rounded-2xl gap-9">
// <div className="flex items-center gap-2">
// <div className="w-3 h-3 bg-[#E2E2DC] rounded-full"></div>
// <p className="text-m text-[#0D1922]">{title}</p>
// </div>
@@ -18,7 +18,7 @@ const ActivityCard = ({ icon, title }: ActivityCardProps) => {
<div className="w-10 h-10 rounded-full text-[#00BED7] overflow-hidden border border-[#00BED7]">
{icon}
</div>
<p className="text-sm font-semibold">{title}</p>
<p className="lg:text-sm sm:text-xs text-[10px] font-semibold">{title}</p>
</div>
);
};
@@ -39,23 +39,37 @@ function SkyGardenSlider() {
}, [currentSlideIndex]);
return (
<div ref={ref} className="relative py-8 overflow-x-clip">
<div ref={ref} className="relative pb-4 overflow-x-clip">
{ref.current?.clientWidth && (
<div
className="flex gap-4 px-6 transition-transform duration-300"
style={{
transform: `translateX(calc(-${
ref.current.clientWidth * currentSlideIndex
}px + ${currentSlideIndex * 32}px))`,
}}
>
{images.map((image, index) => (
<img key={index} src={image} alt="" className="rounded-2xl" />
))}
</div>
<>
<div
className="flex gap-4 px-6 transition-transform duration-300 max-sm:hidden"
style={{
transform: `translateX(calc(-${
ref.current.clientWidth * currentSlideIndex
}px + ${currentSlideIndex * 32}px))`,
}}
>
{images.map((image, index) => (
<img key={index} src={image} alt="" className="rounded-2xl" />
))}
</div>
<div
className="flex gap-2 transition-transform duration-300 sm:hidden"
style={{
transform: `translateX(calc(-${
ref.current.clientWidth * currentSlideIndex
}px + ${currentSlideIndex * -8}px))`,
}}
>
{images.map((image, index) => (
<img key={index} src={image} alt="" className="rounded-2xl" />
))}
</div>
</>
)}
<div className="absolute top-0 w-full h-full flex items-center justify-between px-4">
<div className="absolute top-0 flex items-center justify-between w-full h-full px-4">
<button
className={`p-2.5 bg-[#FFFFFFCC] hover:bg-white hover:text-[#0D1922] rounded-full transition-all ${
isShowPrevButton ? "opacity-100" : "opacity-0 pointer-events-none"
+26
View File
@@ -0,0 +1,26 @@
interface Props {
className?: string;
}
function PlayIcon({ className = "" }: Props) {
return (
<svg
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
>
<path
d="M19.185 11.7856C19.3468 11.8827 19.3468 12.1173 19.185 12.2144L7.12863 19.4482C6.96199 19.5482 6.75 19.4281 6.75 19.2338L6.75 4.76619C6.75 4.57187 6.96199 4.45184 7.12862 4.55182L19.185 11.7856Z"
stroke="currentColor"
strokeWidth={1.5}
strokeLinecap="round"
strokeLinejoin="round"
/>
</svg>
);
}
export default PlayIcon;
@@ -22,8 +22,8 @@ const Map = () => {
return (
<div className="relative">
<TransformWrapper
initialScale={isMobile ? 2 : 1}
minScale={isMobile ? 2 : 1}
initialScale={isMobile ? 1 : 1}
minScale={isMobile ? 1 : 1}
maxScale={2}
alignmentAnimation={{ sizeX: 50, sizeY: 50 }}
wheel={{ step: 10000, smoothStep: 0.0005 }}
@@ -32,6 +32,7 @@ const Map = () => {
animationType: "easeOutQuart",
animationTime: 500,
}}
centerOnInit
>
<WeatherWidget />
{!isMobile && <ZoomControlls />}