unit popup for east marasi drive

This commit is contained in:
2025-06-03 14:59:17 +05:00
parent 68d2b910c8
commit f0584ab656
17 changed files with 522 additions and 460 deletions
+153 -388
View File
@@ -1,16 +1,17 @@
// import { selectedFloorPlanMasksMarasiDrive } from "../data/selectedFloor-plan-masks/marasi-drive";
import { formattedUnitTypes } from "../data/formattedUnitTypes";
import { usePopupStore } from "../stores/usePopupStore";
import { Unit } from "../types/IUnit";
import UnitPopup from "./UnitPopup";
interface FloorPlanMarasiDriveEastProps {
selectedFloor: string | null;
unitsOnFloor: Unit[];
}
function FloorPlanMarasiDriveEast({
selectedFloor,
unitsOnFloor,
}: FloorPlanMarasiDriveEastProps & React.SVGProps<SVGSVGElement>) {
function handleClick(unitNumber: string) {
window.open(`/complex/marasi-drive/${unitNumber}`, "_blank");
}
return (
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -1149,411 +1150,175 @@ function FloorPlanMarasiDriveEast({
}}
/>
</g>
<g>
<g data-name={16}>
<text
transform="translate(411.74 50.63)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}16`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}16`)}
data-number={16}
data-type="1br-type-c"
d="M474.57,66.81c.12.12,2.82-2.72,4.16-4.16l-47.12-47.12-3.51,3.51-15.49-15.49-36.67,36.67,15.49,15.49-2.36,2.36,34.26,34.26-1.1,1.1,10.16,10.16,21.28-21.28,5.6,5.6,1.66-1.66,7.72-7.72c.08.08,5.91-5.85,8.82-8.82l-2.9-2.9Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
{unitsOnFloor && unitsOnFloor.length && (
<g>
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(411.74 50.63)"
unit={unitsOnFloor[15]}
d="M474.57 66.81c.12.12 2.82-2.72 4.16-4.16l-47.12-47.12-3.51 3.51-15.49-15.49-36.67 36.67 15.49 15.49-2.36 2.36 34.26 34.26-1.1 1.1 10.16 10.16 21.28-21.28 5.6 5.6 1.66-1.66 7.72-7.72c.08.08 5.91-5.85 8.82-8.82z"
/>
</g>
<g data-name={15}>
<text
transform="translate(365.57 97)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}15`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}15`)}
data-number={15}
data-type="1br-type-c"
d="M415.38,131.84l-1.85,1.85-7.69,7.69-8.75,8.75-2.92-2.92-4.06,4.06-47.12-47.12,3.55-3.56-15.49-15.49,36.48-36.49,15.49,15.49,2.58-2.58,34.26,34.26,1.1-1.1,10.16,10.16-21.36,21.36,5.61,5.61Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(365.57 97)"
unit={unitsOnFloor[14]}
d="m415.38 131.84-1.85 1.85-7.69 7.69-8.75 8.75-2.92-2.92-4.06 4.06-47.12-47.12 3.55-3.56-15.49-15.49 36.48-36.49 15.49 15.49 2.58-2.58 34.26 34.26 1.1-1.1 10.16 10.16-21.36 21.36 5.61 5.61Z"
/>
</g>
<g data-name={14}>
<text
transform="translate(262.01 199.05)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}14`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}14`)}
data-number={14}
data-type="studio-2"
d="M321.78,225.44l-1.45,1.45-7.76,7.76-9,9-4.56-4.56-4.63,4.64-45.43-45.43-15.52-15.52,22.49-22.49,15.52,15.52,3.45-3.45,47.08,47.08-3.1,3.1,2.91,2.91Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(262.01 199.05)"
unit={unitsOnFloor[13]}
d="m321.78 225.44-1.45 1.45-7.76 7.76-9 9-4.56-4.56-4.63 4.64-45.43-45.43-15.52-15.52 22.49-22.49 15.52 15.52 3.45-3.45 47.08 47.08-3.1 3.1 2.91 2.91Z"
/>
</g>
<g data-name={13}>
<text
transform="translate(235.49 225.61)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}13`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}13`)}
data-number={13}
data-type="studio-2"
d="M292.55,254.67l-8.94,8.94-7.77,7.77-1.38,1.38-2.91-2.91-3.07,3.07-47.08-47.08,3.45-3.45-15.52-15.52,22.67-22.67,15.52,15.52,45.43,45.43-4.95,4.96,4.56,4.56Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(235.49 225.61)"
unit={unitsOnFloor[12]}
d="m292.55 254.67-8.94 8.94-7.77 7.77-1.38 1.38-2.91-2.91-3.07 3.07-47.08-47.08 3.45-3.45-15.52-15.52L232 184.2l15.52 15.52 45.43 45.43-4.95 4.96 4.56 4.56Z"
/>
</g>
<g data-name={12}>
<text
transform="translate(206.63 254.63)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}12`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}12`)}
data-number={12}
data-type="studio-2"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(206.63 254.63)"
unit={unitsOnFloor[11]}
d="M266.85,280.36l-1.47,1.47-7.54,7.54-9.17,9.17-4.62-4.62-5.9,5.9-11.15-11.15.88-.88-34.22-34.22-.88.88-15.52-15.52,23.6-23.6,15.52,15.52,3.55-3.55,47.08,47.08-3.06,3.06,2.91,2.91Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
/>
</g>
<g data-name={11}>
<text
transform="translate(179.52 282.3)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}11`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}11`)}
data-number={11}
data-type="studio-2"
d="M235.49,311.73l-9.17,9.17-7.67,7.67-1.35,1.35-2.91-2.91-3.09,3.09-47.09-47.09,3.37-3.37-15.52-15.52,23.73-23.73,15.55,15.5-1.05,1.05,34.22,34.22,1.05-1.05,11.15,11.15-5.84,5.84,4.62,4.62Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(179.52 282.3)"
unit={unitsOnFloor[10]}
d="m235.49 311.73-9.17 9.17-7.67 7.67-1.35 1.35-2.91-2.91-3.09 3.09-47.09-47.09 3.37-3.37-15.52-15.52 23.73-23.73 15.55 15.5-1.05 1.05 34.22 34.22 1.05-1.05 11.15 11.15-5.84 5.84 4.62 4.62Z"
/>
</g>
<g data-name={10}>
<text
transform="translate(143.08 319.56)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}10`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}10`)}
data-number={10}
data-type="1br-type-c"
d="M208.62,338.6l-8.72,8.72-7.68,7.68-1.9,1.9-5.63-5.63-21.2,21.2-15.4-15.4,1.2-1.2-28.96-28.96,2.34-2.34-15.11-15.11,36.08-36.9,15.52,15.52,3.65-3.65,47.09,47.09-4.18,4.18,2.91,2.91Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(143.08 319.56)"
unit={unitsOnFloor[9]}
d="m208.62 338.6-8.72 8.72-7.68 7.68-1.9 1.9-5.63-5.63-21.2 21.2-15.4-15.4 1.2-1.2-28.96-28.96 2.34-2.34-15.11-15.11 36.08-36.9 15.52 15.52 3.65-3.65 47.09 47.09-4.18 4.18 2.91 2.91Z"
/>
</g>
<g data-name={9}>
<text
transform="translate(42.47 413.14)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}09`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}09`)}
data-number={9}
data-type="1br-type-b"
d="M116.69,430.53l-7.3,7.3-7.69,7.69-18.05,18.05-2.57-2.57-6.8,6.8-11.42-11.42-1.95,1.95-3.17-3.17-4.37,4.37L0,416.28l51.9-51.9,19.55,19.55,3.23-3.23,43.01,43.01-3.92,3.91,2.91,2.91Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(42.47 413.14)"
unit={unitsOnFloor[8]}
d="m116.69 430.53-7.3 7.3-7.69 7.69-18.05 18.05-2.57-2.57-6.8 6.8-11.42-11.42-1.95 1.95-3.17-3.17-4.37 4.37L0 416.28l51.9-51.9 19.55 19.55 3.23-3.23 43.01 43.01-3.92 3.91 2.91 2.91Z"
/>
</g>
<g data-name={8}>
<text
transform="translate(129.9 499.95)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}08`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}08`)}
data-number={8}
data-type="1br-type-b"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(129.9 499.95)"
unit={unitsOnFloor[7]}
d="M131.89,445.71l-7.35,7.35-7.66,7.66-18.05,18.05,2.49,2.49-6.78,6.78,11.47,11.47-1.52,1.52,3.36,3.36-4.88,4.88,43.05,53.14,51.96-51.96-19.57-19.57-.27-.27,3.31-3.31-29.8-29.8,1.16-1.16-12.96-12.96-5.14,5.14-2.82-2.82Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
/>
</g>
<g data-name={7}>
<text
transform="translate(177.05 447.24)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}07`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}07`)}
data-number={7}
data-type="1br-type-c"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(177.05 447.24)"
unit={unitsOnFloor[6]}
d="M161.65,415.95l-1.68,1.68-7.63,7.63-8.78,8.78,2.82,2.82-5.12,5.12,12.96,12.96.91-.91,34.31,34.31,3.43-3.43,15.33,15.33,36.7-36.7-15.33-15.32,2.41-2.41-34.31-34.31,1.13-1.13-10.21-10.21-21.37,21.37-5.56-5.56Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
/>
</g>
<g data-name={6}>
<text
data-name="E-0006 ST"
transform="translate(223.49 400.85)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}06`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}06`)}
data-number={6}
data-type="1br-type-c"
d="M223.81,353.83l-8.71,8.71-7.64,7.64-1.76,1.75,5.56,5.56-21.42,21.42,10.21,10.21,1.24-1.24,34.31,34.31,2.38-2.33,15.3,15.3,36.59-36.59-15.33-15.33,3.53-3.53-47.31-47.31-4.18,4.18-2.78-2.78Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(223.49 400.85)"
unit={unitsOnFloor[5]}
d="m223.81 353.83-8.71 8.71-7.64 7.64-1.76 1.75 5.56 5.56-21.42 21.42 10.21 10.21 1.24-1.24 34.31 34.31 2.38-2.33 15.3 15.3 36.59-36.59-15.33-15.33 3.53-3.53-47.31-47.31-4.18 4.18-2.78-2.78Z"
/>
</g>
<g data-name={5}>
<text
transform="translate(260.74 365.03)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}05`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}05`)}
data-number={5}
data-type="studio-2"
d="M250.61,326.99l-9.11,9.11-7.63,7.62-1.41,1.41,2.78,2.78-3.03,3.02,47.31,47.31,3.32-3.32,15.33,15.33,23.7-23.7-15.33-15.33-1.02,1.02-34.32-34.32,1.1-1.1-11.13-11.13-5.93,5.93-4.64-4.64Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(260.74 365.03)"
unit={unitsOnFloor[4]}
d="m250.61 326.99-9.11 9.11-7.63 7.62-1.41 1.41 2.78 2.78-3.03 3.02 47.31 47.31 3.32-3.32 15.33 15.33 23.7-23.7-15.33-15.33-1.02 1.02-34.32-34.32 1.1-1.1-11.13-11.13-5.93 5.93-4.64-4.64Z"
/>
</g>
<g data-name={4}>
<text
transform="translate(288.32 337.22)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}04`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}04`)}
data-number={4}
data-type="studio-2"
d="M282.06,295.54l-1.44,1.44-7.66,7.66-8.99,8.99,4.64,4.64-6.05,6.05,11.13,11.13.93-.93,34.32,34.32-.94.94,15.33,15.33,23.68-23.68-15.33-15.33,3.54-3.54-47.32-47.32-3.07,3.07-2.77-2.77Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(288.32 337.22)"
unit={unitsOnFloor[3]}
d="m282.06 295.54-1.44 1.44-7.66 7.66-8.99 8.99 4.64 4.64-6.05 6.05 11.13 11.13.93-.93 34.32 34.32-.94.94 15.33 15.33 23.68-23.68-15.33-15.33 3.54-3.54-47.32-47.32-3.07 3.07z"
/>
</g>
<g data-name={3}>
<text
transform="translate(324.71 299.88)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}03`}
</tspan>
<tspan x={0} y={10.8}>
{"1BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}03`)}
data-number={3}
data-type="1br-type-d"
d="M310.29,267.31l-1.78,1.78-7.78,7.78-10.03,10.03,2.77,2.77-4.11,4.12,45.49,45.49,8.38-8.38,17.15,17.15,32.49-32.49-17.15-17.15,7.45-7.45-26.1-26.1-3.68,3.68-10.91-10.91-20.95,20.95-11.26-11.26Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(324.71 299.88)"
unit={unitsOnFloor[2]}
d="m310.29 267.31-1.78 1.78-7.78 7.78-10.03 10.03 2.77 2.77-4.11 4.12 45.49 45.49 8.38-8.38 17.15 17.15 32.49-32.49-17.15-17.15 7.45-7.45-26.1-26.1-3.68 3.68-10.91-10.91-20.95 20.95-11.26-11.26Z"
/>
</g>
<g data-name={2}>
<text
transform="translate(368.68 256.57)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}02`}
</tspan>
<tspan x={0} y={10.8}>
{"ST"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}02`)}
data-number={2}
data-type="studio-2"
<MarasiDriveEastFloorPlanUnit
floor={selectedFloor}
textTransform="translate(368.68 256.57)"
unit={unitsOnFloor[1]}
d="M414.41,263.32l15.35,15.35-22.48,22.48-15.35-15.35-3.7,3.7-34.29-34.29-.86.86-12.93-12.93,4.14-4.14-2.85-2.84,1.41-1.41,7.61-7.61,9.14-9.14,4.65,4.65,4.73-4.73,45.42,45.42Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
/>
<MarasiDriveEastFloorPlanUnit
unit={unitsOnFloor[0]}
floor={selectedFloor}
textTransform="translate(416.83 227.56)"
d="m483.21 195.47 9.32-.1.04 50.46-11.7-.37-.08 18.74-22.25.21c-9.39.09-18.38 3.86-25.02 10.5l-2.35 2.36-58.78-58.78 2.19-2.19-1.99-1.99 16.28-16.28-4.55-4.55 9.75-9.75 4.88 4.89h84.13l.14 6.83Z"
/>
</g>
<g data-name={1}>
<text
transform="translate(416.83 227.56)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`E-${selectedFloor}01`}
</tspan>
<tspan x={0} y={10.8}>
{"2BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`E-${selectedFloor}01`)}
data-number={1}
data-type="2br-type-a"
d="M483.21,195.47l9.32-.1.04,50.46-11.7-.37-.08,18.74-22.25.21c-9.39.09-18.38,3.86-25.02,10.5l-2.35,2.36-58.78-58.78,2.19-2.19-1.99-1.99,16.28-16.28-4.55-4.55,9.75-9.75,4.88,4.89h84.13s.14,6.83.14,6.83Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-all cursor-pointer"
/>
</g>
</g>
)}
</svg>
);
}
export default FloorPlanMarasiDriveEast;
function MarasiDriveEastFloorPlanUnit({
d,
textTransform,
floor,
unit,
}: {
d: string;
textTransform: string;
floor: string | null;
unit: Unit;
}) {
function handleClick(unitNumber: string) {
window.open(`/complex/marasi-drive/${unitNumber}`, "_blank");
}
const { setPopup, setSide } = usePopupStore();
function handleMouseEnter() {
if (floor === null) return;
setSide("top");
setPopup(
<UnitPopup
wing="East"
unitType={unit.unitType}
floor={unit.floor}
unitNumber={unit.unitNo}
squareFt={unit.squareFt}
suitesArea={unit.suitsArea}
balconyArea={unit.balconyArea}
price={unit.salesPrice}
/>
);
}
return (
<g
// data-name={unit.unitNo}
>
<text
transform={textTransform}
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{unit.unitNo}
</tspan>
<tspan x={0} y={10.8}>
{formattedUnitTypes.get(unit.unitType)}
</tspan>
</text>
<path
onClick={() => handleClick(unit.unitNo)}
onMouseEnter={handleMouseEnter}
onMouseLeave={() => setPopup(null)}
// data-number={unit.unitNo}
// data-type={unit.unitType}
d={d}
className="fill-transparent hover:fill-[#00BED7]/20 transition-all cursor-pointer"
/>
</g>
);
}
@@ -1554,29 +1554,31 @@ function FloorPlanMarasiDriveEast({
d="M304.47,286.8l-1.14-1.14-7.04-7.04-8.46-8.46-4.12,4.12-4.36-4.36-42.07,42.07-14.11,14.11,20.7,20.7,14.11-14.11,3.22,3.22,31.77-31.77.92.92,11.88-11.88-3.83-3.83,2.53-2.53Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
/>
<text
transform="translate(203.64 278.77)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`W-${selectedFloor}01`}
</tspan>
<tspan x={0} y={10.8}>
{"2BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`W-${selectedFloor}01`)}
data-number={1}
data-type="2br-type-a"
d="M264.39,246.73l1.02,1.02-4.12,4.12,14.85,14.85-1.91,1.91,1.9,1.9-36.21,36.21-18.05,18.05-1.97-1.97c-6.35-6.35-14.97-9.92-23.95-9.92h-19.67l.03-17.38-10.88-.03v-46.12h8.58v-6.29h77.87l4.43-4.43.95.94,7.13,7.13Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
/>
<g data-name={1}>
<text
transform="translate(203.64 278.77)"
style={{
fill: "#fff",
fontFamily: "Usual",
fontSize: 8,
fontWeight: 500,
}}
>
<tspan x={0} y={0}>
{`W-${selectedFloor}01`}
</tspan>
<tspan x={0} y={10.8}>
{"2BR"}
</tspan>
</text>
<path
onClick={() => handleClick(`W-${selectedFloor}01`)}
data-number={1}
data-type="2br-type-a"
d="M264.39,246.73l1.02,1.02-4.12,4.12,14.85,14.85-1.91,1.91,1.9,1.9-36.21,36.21-18.05,18.05-1.97-1.97c-6.35-6.35-14.97-9.92-23.95-9.92h-19.67l.03-17.38-10.88-.03v-46.12h8.58v-6.29h77.87l4.43-4.43.95.94,7.13,7.13Z"
className="fill-transparent hover:fill-[#00BED7]/20 transition-[fill] cursor-pointer"
/>
</g>
</g>
</svg>
);
+2 -2
View File
@@ -23,9 +23,9 @@ function FloorPopup({ title, position, data, complexName }: FloorMarkerProps) {
transition={{ duration: 0.1 }}
style={{ top: position[1], left: position[0] }}
className={clsx(
"absolute z-1 2xl:rounded-[1.111vw] 2xl:p-[1.111vw] p-4 rounded-2xl flex flex-col 2xl:gap-[1.111vw] bg-white transition-opacity duration-300 -translate-y-1/2 2xl:w-[17.222vw] md:max-2xl:w-70 w-screen",
"absolute z-1 2xl:rounded-[1.111vw] 2xl:p-[1.111vw] p-4 rounded-2xl flex flex-col 2xl:gap-[1.111vw] bg-white -translate-y-1/2 2xl:w-[17.222vw] md:max-2xl:w-70 w-screen",
title.startsWith("West")
? "translate-x-[calc(1.25vw)]"
? "translate-x-[1.25vw]"
: "-translate-x-[calc(100%+1.25vw)]"
)}
>
+47 -11
View File
@@ -9,10 +9,12 @@ import InfoIcon from "./icons/InfoIcon";
import PrivacyPolicyButton from "./PrivacyPolicyButton";
import Button from "./ui/Button";
import { useNavigate } from "react-router";
import FloorPopup from "./FloorPopup";
// import FloorPopup from "./FloorPopup";
import { useQuery } from "@tanstack/react-query";
import { api } from "../api/ky";
import clsx from "clsx";
import { usePopupStore } from "../stores/usePopupStore";
import NewFloorPopup from "./NewFloorPopup";
export interface FloorsData {
floor: number;
@@ -42,16 +44,16 @@ function FloorSelect({
const navigate = useNavigate();
const [isFullScreen, setIsFullScreen] = useState(false);
const [hoveredFloor, setHoveredFloor] = useState<string | null>(null);
const [position, setPosition] = useState<[number, number]>([0, 0]);
// const [hoveredFloor, setHoveredFloor] = useState<string | null>(null);
const { setPopup, setPosition, setSide } = usePopupStore();
const rootRef = useRef<HTMLDivElement>(null);
function handleMouseMove(e: React.MouseEvent<HTMLDivElement>) {
const x = e.clientX - e.currentTarget.getBoundingClientRect().left;
const y = e.clientY - e.currentTarget.getBoundingClientRect().top;
setPosition([x, y]);
const x = e.clientX;
const y = e.clientY;
setPosition({ x, y });
}
function handleFullScreenClick() {
@@ -90,6 +92,28 @@ function FloorSelect({
}
}
function handleFloorMouseEnter(floor: string, wing?: "West" | "East") {
if (!data) return;
if (wing) setSide(wing === "East" ? "left" : "right");
if (
data.some(
(floorData) => floorData.floor === +floor!.split(" ").at(-1)!
) ||
["Rooftop", "Ground Level", "Podium Level", "Sky Garden"].includes(floor)
)
setPopup(
<NewFloorPopup
title={floor}
complexName={complexName}
data={
data.find(
(floorData) => floorData.floor === +floor!.split(" ").at(-1)!
)!
}
/>
);
}
return (
<div
className={clsx(
@@ -115,8 +139,20 @@ function FloorSelect({
).map(([floorTitle, d]) => (
<path
onClick={() => handleFloorClick(floorTitle)}
onMouseEnter={() => setHoveredFloor(floorTitle)}
onMouseLeave={() => setHoveredFloor(null)}
onMouseEnter={() =>
handleFloorMouseEnter(
floorTitle,
![
"Rooftop",
"Ground Level",
"Podium Level",
"Sky Garden",
].includes(floorTitle) && complexName === "marasi-drive"
? (floorTitle.split(" ")[0] as "West" | "East")
: undefined
)
}
onMouseLeave={() => setPopup(null)}
key={floorTitle}
d={d}
className={clsx(
@@ -170,7 +206,7 @@ function FloorSelect({
onClick={handleFullScreenClick}
/>
</div>
{data &&
{/* {data &&
hoveredFloor &&
(data.some(
({ floor }) => floor === +hoveredFloor!.split(" ").at(-1)!
@@ -188,7 +224,7 @@ function FloorSelect({
)!
}
/>
)}
)} */}
</div>
);
}
+97
View File
@@ -0,0 +1,97 @@
import { formattedUnitTypes } from "../data/formattedUnitTypes";
import { FloorsData } from "./FloorSelect";
import HumanIcon from "./icons/HumanIcon";
interface NewFloorPopupProps {
title: string;
complexName: string;
data: FloorsData;
}
function NewFloorPopup({ title, complexName, data }: NewFloorPopupProps) {
return (
<div className="2xl:space-y-[0.556vw] space-y-2">
<div className="flex 2xl:gap-[0.556vw] gap-2">
<p className="font-medium text-h5">
{Number.isNaN(+title.split(" ").at(-1)!)
? title
: `${title.split(" ").at(-1)} floor`}
</p>
{!Number.isNaN(+title.split(" ").at(-1)!) && (
<p className="text-[#0D1922]/40 text-s">{title.split(" ")[0]} Wing</p>
)}
</div>
<div className="flex 2xl:gap-[0.278vw] gap-1">
<p className="2xl:px-[0.556vw] 2xl:py-[0.278vw] px-2 py-0.5 bg-[#F3F3F2] 2xl:rounded-[0.278vw] rounded text-caption-s text-[#0D1922]/70">
{title && Number.isNaN(+title!.split(" ").at(-1)!)
? "16 Amenties"
: `${
complexName === "marasi-drive"
? data[
title.split(" ")[0] === "East"
? "East"
: title.split(" ")[0] === "West"
? "West"
: "others"
].totalUnits
: data.others.totalUnits
} apartments`}
</p>
{!Number.isNaN(+title.split(" ").at(-1)!) && (
<div className="2xl:px-[0.556vw] 2xl:py-[0.278vw] px-2 py-0.5 bg-[#30B216]/8 2xl:rounded-[0.278vw] rounded flex 2xl:gap-[0.278vw] gap-1">
<span className="2xl:w-[0.833vw] 2xl:h-[0.833vw] w-3 h-3 text-[#30B216]">
<HumanIcon />
</span>
<p className="text-caption-s text-[#30B216]">Virtual Tour</p>
</div>
)}
</div>
<hr className="border-[#E2E2DC] 2xl:h-[0.069vw] h-px" />
<div className="2xl:space-y-[0.556vw] space-y-2">
{!Number.isNaN(+title.split(" ").at(-1)!) ? (
<>
{Object.entries(
data[
title.split(" ")[0] === "East"
? "East"
: title.split(" ")[0] === "West"
? "West"
: "others"
].types
).map(([unitType, count]) => (
<div className="flex 2xl:gap-[0.556vw] gap-2" key={unitType}>
<p className="bg-[#00BED7] rounded-full flex justify-center items-center font-mono text-caption-s text-white 2xl:w-[1.111vw] 2xl:h-[1.111vw] w-4 h-4">
{count}
</p>
<p className="text-caption-m text-[#0D1922]/70">
{formattedUnitTypes.get(unitType)}
</p>
</div>
))}
</>
) : (
<>
<div className="flex 2xl:gap-[0.556vw] gap-2">
<p className="bg-[#00BED7] rounded-full flex justify-center items-center font-mono text-caption-s text-white 2xl:w-[1.111vw] 2xl:h-[1.111vw] w-4 h-4">
8
</p>
<p className="text-caption-m text-[#0D1922]/70">
Indoor Amenties
</p>
</div>
<div className="flex 2xl:gap-[0.556vw] gap-2">
<p className="bg-[#00BED7] rounded-full flex justify-center items-center font-mono text-caption-s text-white 2xl:w-[1.111vw] 2xl:h-[1.111vw] w-4 h-4">
8
</p>
<p className="text-caption-m text-[#0D1922]/70">
Outdoor Amenties
</p>
</div>
</>
)}
</div>
</div>
);
}
export default NewFloorPopup;
+48
View File
@@ -0,0 +1,48 @@
import { AnimatePresence, motion } from "motion/react";
import { usePopupStore } from "../stores/usePopupStore";
import clsx from "clsx";
function PopupContainer() {
const { position, popup, side } = usePopupStore();
return (
<AnimatePresence>
{popup && (
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
transition={{ duration: 0.1 }}
style={{ top: position.y, left: position.x }}
className={clsx(
"absolute z-2 2xl:rounded-[1.111vw] 2xl:p-[1.111vw] p-4 rounded-2xl bg-white 2xl:w-[17.222vw] md:max-2xl:w-[248px] w-screen shadow-[0_2px_8px_0_rgba(0,0,0,0.15)]",
side === "left" &&
"-translate-y-1/2 -translate-x-[calc(100%+1.25vw)]",
side === "right" && "-translate-y-1/2 translate-x-[1.25vw]",
side === "top" &&
"-translate-x-1/2 -translate-y-[calc(100%+1.25vw)]",
side === "bottom" &&
"-translate-x-1/2 translate-y-[calc(100%+1.25vw)]"
)}
>
{popup}
<div
className={clsx(
"absolute border-[0.556vw_0px_0.486vw_0.556vw] [border-color:_transparent_transparent_transparent_#fff]",
side === "left" &&
"top-1/2 -translate-y-1/2 left-full -translate-x-px",
side === "right" &&
"top-1/2 -translate-y-1/2 right-full translate-x-px rotate-180",
side === "top" &&
"left-1/2 translate-x-full top-full -translate-y-px rotate-90 origin-top-left",
side === "bottom" &&
"left-1/2 translate-x-full bottom-full translate-y-px -rotate-90 origin-bottom-left"
)}
/>
</motion.div>
)}
</AnimatePresence>
);
}
export default PopupContainer;
+16 -16
View File
@@ -45,12 +45,12 @@ function Slider({
return (
<div
{...handlers}
className='relative w-[63.333vw] h-[27.639vw] rounded-3xl overflow-hidden max-md:w-[91.111vw] max-md:h-[110.556vw] max-2xl:w-[93.75vw] max-2xl:h-[51.823vw]'
className="relative w-[63.333vw] h-[27.639vw] rounded-3xl overflow-hidden max-md:w-[91.111vw] max-md:h-[110.556vw] max-2xl:w-[93.75vw] max-2xl:h-[51.823vw]"
>
<AnimatePresence custom={direction} initial={false}>
<motion.div
key={currentSlide}
className='absolute inset-0 bg-cover bg-no-repeat bg-center before:absolute before:inset-0 before:bg-[#0D1922]/20 before:z-10'
className="absolute inset-0 bg-cover bg-no-repeat bg-center before:absolute before:inset-0 before:bg-[#0D1922]/20 before:z-10"
style={{
backgroundImage: `url(${dubaiMarinaSlider[categoryName][currentSlide].image})`,
}}
@@ -63,12 +63,12 @@ function Slider({
}}
/>
</AnimatePresence>
<div className='relative z-10 w-full h-full flex flex-col justify-between p-6'>
<div className='flex flex-col gap-4'>
<AnimatePresence mode='wait'>
<div className="relative z-10 w-full h-full flex flex-col justify-between p-6">
<div className="flex flex-col gap-4">
<AnimatePresence mode="wait">
<motion.h3
key={`title-${currentSlide}`}
className='text-h3 text-white max-md:text-h5'
className="text-h3 text-white max-md:text-h5"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
@@ -77,10 +77,10 @@ function Slider({
{dubaiMarinaSlider[categoryName][currentSlide].title}
</motion.h3>
</AnimatePresence>
<AnimatePresence mode='wait'>
<AnimatePresence mode="wait">
<motion.p
key={`desc-${currentSlide}`}
className='text-s w-[19.861vw] tracking-[-0.02em] leading-[140%] text-white max-md:w-full max-md:text-caption-m max-2xl:w-[37.24vw]'
className="text-s w-[19.861vw] tracking-[-0.02em] leading-[140%] text-white max-md:w-full max-md:text-caption-m max-2xl:w-[37.24vw]"
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
@@ -90,31 +90,31 @@ function Slider({
</motion.p>
</AnimatePresence>
</div>
<div className='flex items-center gap-[0.556vw] relative max-md:gap-[2.222vw]'>
<div className="flex items-center gap-[0.556vw] relative max-md:gap-[2.222vw]">
<Button
variant='secondary'
variant="secondary"
onlyIcon
onClick={handlePreviousSlide}
disabled={currentSlide === 0}
className='disabled:!text-[#0D1922]/40 disabled:!bg-[#fff]/80 disabled:!cursor-default hover:bg-[#F3F3F2] transition-all duration-200'
className="disabled:!text-[#0D1922]/40 disabled:!bg-[#fff]/80 disabled:!cursor-default hover:bg-[#F3F3F2] transition-all duration-200"
>
<span className='w-5 h-5'>
<span className="w-5 h-5">
<ArrowLeftIcon />
</span>
</Button>
<div className='text-s text-white'>
<div className="text-s text-white">
{currentSlide + 1}/{dubaiMarinaSlider[categoryName].length}
</div>
<Button
variant='secondary'
variant="secondary"
onlyIcon
onClick={handleNextSlide}
disabled={
currentSlide === dubaiMarinaSlider[categoryName].length - 1
}
className='disabled:!text-[#0D1922]/40 disabled:!bg-[#fff]/80 disabled:!cursor-default hover:bg-[#F3F3F2] transition-all duration-200'
className="disabled:!text-[#0D1922]/40 disabled:!bg-[#fff]/80 disabled:!cursor-default hover:bg-[#F3F3F2] transition-all duration-200"
>
<span className='w-5 h-5'>
<span className="w-5 h-5">
<ArrowRightIcon />
</span>
</Button>
+2 -2
View File
@@ -1,5 +1,5 @@
import { useFavoritesUnitsStore } from "../stores/useFavoritesUnitsStore";
import { IUnit } from "../types/IUnit";
import { Unit } from "../types/IUnit";
import FilledHeartIcon from "./icons/FilledHeartIcon";
import HeartIcon from "./icons/HeartIcon";
import Button from "./ui/Button";
@@ -9,7 +9,7 @@ import { formattedUnitTypes } from "../data/formattedUnitTypes";
import { Link } from "react-router";
import complexNameToSlug from "../utils/complexNameToSlug";
function UnitCard({ unit }: { unit: IUnit }) {
function UnitCard({ unit }: { unit: Unit }) {
const { favoriteUnits, setFavoriteUnits } = useFavoritesUnitsStore();
function handleFavorite(e: React.MouseEvent<HTMLButtonElement>) {
+76
View File
@@ -0,0 +1,76 @@
import { formattedUnitTypes } from "../data/formattedUnitTypes";
import HumanIcon from "./icons/HumanIcon";
interface UnitPopupProps {
unitType: string;
wing?: "East" | "West";
floor: string;
unitNumber: string;
squareFt: number;
suitesArea: number;
balconyArea: number;
price: number;
}
function UnitPopup({
unitType,
wing,
floor,
unitNumber,
squareFt,
suitesArea,
balconyArea,
price,
}: UnitPopupProps) {
return (
<div className="2xl:space-y-[1.111vw] space-y-4">
<div className="2xl:space-y-[0.833vw] space-y-3">
<div className="2xl:space-y-[0.556vw] space-y-2">
<p className="text-h5 font-medium">
{formattedUnitTypes.get(unitType)}
</p>
<div className="flex items-center 2xl:gap-[0.556vw] gap-2">
{wing && (
<>
<p className="text-caption-s opacity-70">{wing} Wing</p>
<div className="2xl:size-[0.278vw] size-1 rounded-full bg-[#E2E2DC]" />
</>
)}
<p className="text-caption-s opacity-70">Floor {floor}</p>
<div className="2xl:size-[0.278vw] size-1 rounded-full bg-[#E2E2DC]" />
<p className="text-caption-s opacity-70">{unitNumber}</p>
</div>
<div className="2xl:p-[0.208vw] p-[3px] 2xl:rounded-[0.278vw] rounded bg-[#30B216]/8 flex 2xl:gap-[0.278vw] gap-1 w-fit">
<span className="2xl:size-[0.833vw] size-3 text-[#30B216]">
<HumanIcon />
</span>
<p className="text-caption-s text-[#30B216]">Virtual Tour</p>
</div>
</div>
</div>
<hr className="2xl:h-[0.069vw] h-px border-[#E2E2DC]" />
<div className="flex flex-col 2xl:gap-[0.556vw] gap-2">
<div className="flex 2xl:gap-[0.556vw] gap-2 justify-between">
<p className="text-caption-m opacity-70">Total Area</p>
<p className="text-caption-m">{squareFt.toFixed(2)} Sqft</p>
</div>
<div className="flex 2xl:gap-[0.556vw] gap-2 justify-between">
<p className="text-caption-m opacity-70">Suites Area</p>
<p className="text-caption-m">{suitesArea.toFixed(2)} Sqft</p>
</div>
<div className="flex 2xl:gap-[0.556vw] gap-2 justify-between">
<p className="text-caption-m opacity-70">Balcony Area</p>
<p className="text-caption-m">{balconyArea.toFixed(2)} Sqft</p>
</div>
</div>
<p className="text-h5 font-medium text-[#00BED7]">
{`AED ${Intl.NumberFormat("ar-AE", {
currency: "AED",
minimumFractionDigits: 0,
}).format(price)}`}
</p>
</div>
);
}
export default UnitPopup;
+2 -2
View File
@@ -48,7 +48,7 @@ function Select({
return (
<div ref={ref} className={clsx("relative", className)}>
{label && (
<p className="text-s text-[#0D1922]/70 2xl:mb-[0.556vw] mb-2">
<p className="text-s text-[#0D1922]/70 2xl:mb-[0.556vw] mb-2 text-nowrap">
{label}
</p>
)}
@@ -59,7 +59,7 @@ function Select({
)}
onClick={() => setIsShow(!isShow)}
>
<p className="text-s">{selectedOption}</p>
<p className="text-s text-nowrap">{selectedOption}</p>
<ChevronDownIcon
className={clsx(
"2xl:w-[1.667vw] 2xl:h-[1.667vw] w-6 h-6 flex-shrink-0 group-hover:text-[#00BED7] transition-[color,rotate]",
+2
View File
@@ -17,6 +17,7 @@ import AboutComplexPage from "./pages/AboutComplexPage.tsx";
import UnitTypeItemPage from "./pages/UnitTypeItemPage.tsx";
import TestPage from "./pages/TestPage.tsx";
import UnitPage from "./pages/UnitPage.tsx";
import PopupContainer from "./components/PopupContainer.tsx";
const route = createBrowserRouter([
{
@@ -79,6 +80,7 @@ createRoot(document.getElementById("root")!).render(
<>
<QueryClientProvider client={queryClient}>
<RouterProvider router={route} />
<PopupContainer />
<ModalContainer />
</QueryClientProvider>
</>
+36 -4
View File
@@ -18,6 +18,9 @@ import GroundDubaiMarina from "../components/floor-plans/dubai-marina/GroundDuba
import PodiumDubaiMarina from "../components/floor-plans/dubai-marina/PodiumDubaiMarina";
import FloorPlanMarasiDriveWestLower from "../components/FloorPlanMarasiDriveWestLower";
import FloorPlanMarasiDriveWestUpper from "../components/FloorPlanMarasiDriveWestUpper";
import { Unit } from "../types/IUnit";
import slugToComplexName from "../utils/slugToComplexName";
import { usePopupStore } from "../stores/usePopupStore";
function FloorsPage() {
const { complexName } = useParams();
@@ -36,6 +39,29 @@ function FloorsPage() {
.json<FloorsData[]>(),
});
const { data: unitsOnFloor } = useQuery({
enabled:
!!selectedFloor &&
!["Rooftop", "Ground Level", "Podium Level", "Sky Garden"].includes(
selectedFloor
),
queryKey: ["units-on-floor", complexName, selectedFloor],
queryFn: () =>
api
.get(
`units/on-floor?project=${slugToComplexName(
complexName!
)}&floor=${selectedFloor?.split(" ").at(-1)}${
complexName === "marasi-drive"
? `&wing=${selectedFloor?.split(" ")[0]}`
: ""
}`
)
.json<Unit[]>(),
});
const { setPosition } = usePopupStore();
return (
<div className="relative h-[calc(100vh-4.444vw)] overflow-hidden">
<FloorSelect
@@ -69,7 +95,7 @@ function FloorsPage() {
floorsData?.map((item) => item.floor.toString()) || []
}
defaultOption={selectedFloor?.toString() || ""}
onSelect={(floor) => setSelectedFloor(floor)}
onSelect={setSelectedFloor}
className="2xl:w-[8.333vw]"
/>
<div className="bg-[#E2E2DC] w-px h-[1.667vw]"></div>
@@ -157,7 +183,7 @@ function FloorsPage() {
]) || []
}
defaultOption={selectedFloor?.toString() || ""}
onSelect={(floor) => setSelectedFloor(floor)}
onSelect={setSelectedFloor}
className="2xl:w-[8.333vw]"
/>
<div className="bg-[#E2E2DC] w-px h-[1.667vw]"></div>
@@ -197,9 +223,15 @@ function FloorsPage() {
</div>
</div>
</div>
<div className="p-[4.444vw] bg-[#F3F3F2] rounded-[0.833vw]">
{selectedFloor.split(" ")[0] === "East" && (
<div
className="p-[4.444vw] bg-[#F3F3F2] rounded-[0.833vw]"
onMouseMove={(e) =>
setPosition({ x: e.clientX, y: e.clientY })
}
>
{unitsOnFloor && selectedFloor.split(" ")[0] === "East" && (
<FloorPlanMarasiDriveEast
unitsOnFloor={unitsOnFloor}
selectedFloor={selectedFloor.split(" ").at(-1)!}
/>
)}
+2 -2
View File
@@ -1,7 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps */
import { useInfiniteQuery, useQuery } from "@tanstack/react-query";
import { api } from "../api/ky";
import { IUnit } from "../types/IUnit";
import { Unit } from "../types/IUnit";
import UnitCard from "../components/UnitCard";
import { useEffect, useRef, useState } from "react";
import SearchFilters from "../components/SearchFilters";
@@ -175,7 +175,7 @@ function SearchPage() {
: ""
}${sort ? `&order=${SORT_OPTIONS[sort].split(" ").join()}` : ""}`
)
.json<IUnit[]>(),
.json<Unit[]>(),
getNextPageParam: (lastPage, _, lastPageIndex) =>
lastPage.length < STEP ? undefined : lastPageIndex + STEP,
});
+2 -2
View File
@@ -1,7 +1,7 @@
import { useQuery } from "@tanstack/react-query";
import { useParams } from "react-router";
import { api } from "../api/ky";
import { IUnit } from "../types/IUnit";
import { Unit } from "../types/IUnit";
import ShareIcon from "../components/icons/ShareIcon";
import Button from "../components/ui/Button";
import FilledHeartIcon from "../components/icons/FilledHeartIcon";
@@ -23,7 +23,7 @@ function UnitPage() {
params.complexName!
)}`
)
.json<IUnit>(),
.json<Unit>(),
});
const { favoriteUnits, setFavoriteUnits } = useFavoritesUnitsStore();
+7 -7
View File
@@ -1,18 +1,18 @@
import { create } from 'zustand';
import { IUnit } from '../types/IUnit';
import { persist } from 'zustand/middleware';
import { create } from "zustand";
import { Unit } from "../types/IUnit";
import { persist } from "zustand/middleware";
export interface FavoriteStore {
favoriteUnits: IUnit[];
setFavoriteUnits: (units: IUnit[]) => void;
favoriteUnits: Unit[];
setFavoriteUnits: (units: Unit[]) => void;
}
export const useFavoritesUnitsStore = create<FavoriteStore>()(
persist(
(set) => ({
favoriteUnits: [],
setFavoriteUnits: (units: IUnit[]) => set({ favoriteUnits: units }),
setFavoriteUnits: (units: Unit[]) => set({ favoriteUnits: units }),
}),
{ name: 'favorites' }
{ name: "favorites" }
)
);
+4
View File
@@ -5,6 +5,8 @@ interface PopupStore {
setPopup: (popup: React.ReactNode) => void;
position: { x: number; y: number };
setPosition: (position: { x: number; y: number }) => void;
side: "left" | "right" | "top" | "bottom";
setSide: (side: "left" | "right" | "top" | "bottom") => void;
}
export const usePopupStore = create<PopupStore>((set) => ({
@@ -12,4 +14,6 @@ export const usePopupStore = create<PopupStore>((set) => ({
setPopup: (popup: React.ReactNode) => set({ popup }),
position: { x: 0, y: 0 },
setPosition: (position: { x: number; y: number }) => set({ position }),
side: "left",
setSide: (side: "left" | "right" | "top" | "bottom") => set({ side }),
}));
+1 -1
View File
@@ -1,4 +1,4 @@
export interface IUnit {
export interface Unit {
id: string;
unitNo: string;
project: string;