181 lines
6.9 KiB
TypeScript
181 lines
6.9 KiB
TypeScript
import ShareIcon from "./icons/ShareIcon";
|
|
import Button from "./ui/Button";
|
|
import Project from "../types/Project";
|
|
import UnitType from "../types/UnitType";
|
|
import PlayIcon from "./icons/PlayIcon";
|
|
import VideoModal from "./VideoModal";
|
|
import useModalStore from "../stores/useModalStore";
|
|
import UnitSliderItem from "./UnitSliderItem";
|
|
import NewUnitSlider from "./NewUnitSlider";
|
|
import UnitTypeImageWithMarkers from "./UnitTypeImageWithMarkers";
|
|
import UnitImageWithSides from "./UnitImageWithSides";
|
|
import InteriorSlider from "./InteriorSlider";
|
|
|
|
interface UnitTypeItemProps {
|
|
project: Project;
|
|
type: UnitType;
|
|
}
|
|
|
|
function UnitTypeItem({ project, type }: UnitTypeItemProps) {
|
|
function handleShare() {
|
|
navigator.share({
|
|
title: type.name,
|
|
url: window.location.href,
|
|
});
|
|
}
|
|
|
|
const { setModal } = useModalStore();
|
|
|
|
const hasSides = project.hasSides !== false;
|
|
|
|
return (
|
|
<div className="2xl:p-[2.222vw] md:max-2xl:p-[3.125vw] p-4 bg-white flex 2xl:gap-[2.222vw] md:max-2xl:gap-8 gap-6 max-2xl:flex-col">
|
|
<NewUnitSlider>
|
|
{type.slug.includes("-loft") ? (
|
|
<>
|
|
<UnitSliderItem text="Lower">
|
|
{innerWidth >= 768 && hasSides ? (
|
|
<UnitImageWithSides>
|
|
<UnitTypeImageWithMarkers
|
|
complexName={project.slug}
|
|
legend={type.legend || []}
|
|
floor="lower"
|
|
unitTypeVariant={type.slug + "-lower"}
|
|
/>
|
|
</UnitImageWithSides>
|
|
) : (
|
|
<UnitTypeImageWithMarkers
|
|
complexName={project.slug}
|
|
legend={type.legend || []}
|
|
floor="lower"
|
|
unitTypeVariant={type.slug + "-lower" + (hasSides ? "-left" : "")}
|
|
/>
|
|
)}
|
|
</UnitSliderItem>
|
|
<UnitSliderItem text="Upper">
|
|
{innerWidth >= 768 && hasSides ? (
|
|
<UnitImageWithSides>
|
|
<UnitTypeImageWithMarkers
|
|
complexName={project.slug}
|
|
legend={type.legend || []}
|
|
floor="upper"
|
|
unitTypeVariant={type.slug + "-upper"}
|
|
/>
|
|
</UnitImageWithSides>
|
|
) : (
|
|
<UnitTypeImageWithMarkers
|
|
complexName={project.slug}
|
|
legend={type.legend || []}
|
|
floor="upper"
|
|
unitTypeVariant={type.slug + "-upper" + (hasSides ? "-left" : "")}
|
|
/>
|
|
)}
|
|
</UnitSliderItem>
|
|
</>
|
|
) : (
|
|
<UnitSliderItem text="Layout">
|
|
{innerWidth >= 768 && hasSides && type.slug !== "2-bedroom-b" ? (
|
|
<UnitImageWithSides>
|
|
<UnitTypeImageWithMarkers
|
|
complexName={project.slug}
|
|
legend={type.legend || []}
|
|
unitTypeVariant={type.slug}
|
|
/>
|
|
</UnitImageWithSides>
|
|
) : (
|
|
<UnitTypeImageWithMarkers
|
|
complexName={project.slug}
|
|
legend={type.legend || []}
|
|
unitTypeVariant={type.slug + (hasSides ? "-left" : "")}
|
|
/>
|
|
)}
|
|
</UnitSliderItem>
|
|
)}
|
|
{innerWidth >= 1440 ? (
|
|
<UnitSliderItem text="Interior">
|
|
<InteriorSlider
|
|
unitTypeSlug={type.slug}
|
|
projectSlug={project.slug}
|
|
/>
|
|
</UnitSliderItem>
|
|
) : (
|
|
type.interiors.map((interior, index) => (
|
|
<UnitSliderItem text={`interior ${index + 1}`} key={index}>
|
|
<img src={interior} alt="" className="object-cover size-full" />
|
|
</UnitSliderItem>
|
|
))
|
|
)}
|
|
</NewUnitSlider>
|
|
<div className="flex flex-col justify-between 2xl:w-[21.944vw] flex-shrink-0">
|
|
<div className="2xl:space-y-[1.667vw] space-y-6">
|
|
<div className="flex justify-between items-start">
|
|
<div className="flex flex-col 2xl:gap-y-[0.556vw] gap-y-2">
|
|
<p className="font-medium md:text-h3 text-h4">{type.name}</p>
|
|
<p className="2xl:rounded-[1.667vw] rounded-3xl 2xl:px-[0.833vw] 2xl:py-[0.278vw] px-3 py-1 ring-[0.069vw] ring-[#E2E2DC] opacity-70 text-caption-m w-fit">
|
|
Up to {type.area}
|
|
</p>
|
|
</div>
|
|
<Button onlyIcon variant="secondary" onClick={handleShare}>
|
|
<span className="2xl:size-[1.389vw] size-5 text-[#0D1922]">
|
|
<ShareIcon />
|
|
</span>
|
|
</Button>
|
|
</div>
|
|
<div className="2xl:space-y-[0.556vw] md:max-2xl:space-y-2 space-y-1">
|
|
<p className="text-m text-[#00BED7]">{project.title}</p>
|
|
<div className="flex items-center 2xl:gap-[0.556vw]">
|
|
{type.wing && (
|
|
<>
|
|
<p className="opacity-70 text-s">{type.wing}</p>
|
|
<div className="2xl:w-[0.278vw] 2xl:h-[0.278vw] w-1 h-1 rounded-full bg-[#E2E2DC]" />
|
|
</>
|
|
)}
|
|
<p className="opacity-70 text-s">{type.floors}</p>
|
|
</div>
|
|
</div>
|
|
<hr className="w-full border-[#E2E2DC] 2xl:h-[0.069vw] h-px" />
|
|
{type.video && (
|
|
<button
|
|
onClick={() => setModal(<VideoModal src={type.video!.src} />)}
|
|
className="2xl:p-[1.111vw] p-4 2xl:rounded-[1.111vw] text-left rounded-2xl flex items-center gap-[0.556vw] ring-[0.069vw] ring-[#E2E2DC] cursor-pointer w-full"
|
|
>
|
|
<div className="lg:space-y-[0.278vw] space-y-1 flex-1">
|
|
<p className="font-medium text-h5">{type.video.title}</p>
|
|
<p className="text-s text-[#00BED7]">{type.video.desc}</p>
|
|
</div>
|
|
<div className="2xl:size-[1.389vw] size-5">
|
|
<PlayIcon />
|
|
</div>
|
|
</button>
|
|
)}
|
|
<div className="2xl:space-y-[0.556vw] md:max-2xl:flex md:max-2xl:gap-2 max-md:space-y-2">
|
|
<p className="text-caption-m">{type.desc[0]}</p>
|
|
<p className="text-caption-m">{type.desc[1]}</p>
|
|
</div>
|
|
</div>
|
|
<div className="flex 2xl:flex-col 2xl:gap-[0.556vw] gap-2 2xl:bottom-[2.222vw] bottom-0 bg-white md:max-2xl:-mx-[3.125vw] md:max-2xl:p-[3.125vw] max-md:-mx-4 max-md:p-4 max-2xl:rounded-t-2xl max-2xl:shadow-[0_-4px_20px_0_rgba(0,0,0,0.05)]">
|
|
{type.tourAvailable && (
|
|
<Button
|
|
variant="cta"
|
|
size="large"
|
|
onClick={() =>
|
|
window.open(
|
|
`/virtual-tour/${project.slug}/${type.slug}`,
|
|
"_blank"
|
|
)
|
|
}
|
|
>
|
|
Virtual tour
|
|
</Button>
|
|
)}
|
|
{/* <Button disabled variant="cta" size="large">
|
|
Book
|
|
</Button> */}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default UnitTypeItem;
|