Merge branch 'main' of http://192.168.1.163:3000/inmake/irth-new-client-120
|
After Width: | Height: | Size: 6.1 MiB |
|
After Width: | Height: | Size: 5.5 MiB |
|
After Width: | Height: | Size: 4.8 MiB |
|
After Width: | Height: | Size: 7.2 MiB |
|
After Width: | Height: | Size: 5.9 MiB |
|
After Width: | Height: | Size: 5.9 MiB |
|
After Width: | Height: | Size: 7.2 MiB |
|
After Width: | Height: | Size: 5.4 MiB |
|
After Width: | Height: | Size: 5.6 MiB |
|
After Width: | Height: | Size: 4.4 MiB |
|
After Width: | Height: | Size: 5.9 MiB |
|
After Width: | Height: | Size: 4.5 MiB |
|
After Width: | Height: | Size: 6.7 MiB |
|
After Width: | Height: | Size: 6.5 MiB |
|
After Width: | Height: | Size: 6.8 MiB |
|
After Width: | Height: | Size: 6.4 MiB |
|
Before Width: | Height: | Size: 836 KiB After Width: | Height: | Size: 836 KiB |
|
Before Width: | Height: | Size: 116 KiB |
|
After Width: | Height: | Size: 836 KiB |
|
Before Width: | Height: | Size: 797 KiB After Width: | Height: | Size: 797 KiB |
|
Before Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 797 KiB |
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 849 KiB After Width: | Height: | Size: 849 KiB |
|
Before Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 850 KiB |
|
Before Width: | Height: | Size: 820 KiB After Width: | Height: | Size: 820 KiB |
|
Before Width: | Height: | Size: 111 KiB |
|
After Width: | Height: | Size: 818 KiB |
|
Before Width: | Height: | Size: 105 KiB |
|
After Width: | Height: | Size: 680 KiB |
|
Before Width: | Height: | Size: 98 KiB |
|
After Width: | Height: | Size: 681 KiB |
|
Before Width: | Height: | Size: 90 KiB |
|
Before Width: | Height: | Size: 850 KiB After Width: | Height: | Size: 850 KiB |
|
Before Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 852 KiB |
|
Before Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 656 KiB |
|
Before Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 659 KiB |
|
Before Width: | Height: | Size: 88 KiB |
|
Before Width: | Height: | Size: 856 KiB After Width: | Height: | Size: 856 KiB |
|
Before Width: | Height: | Size: 115 KiB |
|
After Width: | Height: | Size: 855 KiB |
|
Before Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 692 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 700 KiB |
|
Before Width: | Height: | Size: 80 KiB |
|
Before Width: | Height: | Size: 896 KiB After Width: | Height: | Size: 896 KiB |
|
Before Width: | Height: | Size: 125 KiB |
|
After Width: | Height: | Size: 898 KiB |
|
Before Width: | Height: | Size: 1.0 MiB After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 138 KiB |
|
After Width: | Height: | Size: 1.0 MiB |
|
Before Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 807 KiB |
|
Before Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 808 KiB |
|
Before Width: | Height: | Size: 106 KiB |
|
Before Width: | Height: | Size: 648 KiB After Width: | Height: | Size: 648 KiB |
|
Before Width: | Height: | Size: 86 KiB |
|
After Width: | Height: | Size: 650 KiB |
|
Before Width: | Height: | Size: 600 KiB After Width: | Height: | Size: 600 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 688 KiB |
|
Before Width: | Height: | Size: 504 KiB After Width: | Height: | Size: 504 KiB |
|
Before Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 505 KiB |
|
Before Width: | Height: | Size: 504 KiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 141 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 1.1 MiB After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 122 KiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
Before Width: | Height: | Size: 885 KiB After Width: | Height: | Size: 885 KiB |
|
Before Width: | Height: | Size: 119 KiB |
|
After Width: | Height: | Size: 886 KiB |
|
Before Width: | Height: | Size: 951 KiB After Width: | Height: | Size: 951 KiB |
|
Before Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 952 KiB |
|
Before Width: | Height: | Size: 828 KiB After Width: | Height: | Size: 828 KiB |
|
Before Width: | Height: | Size: 114 KiB |
|
After Width: | Height: | Size: 828 KiB |
|
Before Width: | Height: | Size: 134 KiB |
|
Before Width: | Height: | Size: 609 KiB After Width: | Height: | Size: 609 KiB |
|
Before Width: | Height: | Size: 81 KiB |
|
After Width: | Height: | Size: 610 KiB |
|
Before Width: | Height: | Size: 633 KiB After Width: | Height: | Size: 633 KiB |
|
Before Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 634 KiB |
@@ -11,7 +11,8 @@ import { Link } from "react-router";
|
||||
import complexNameToSlug from "../utils/complexNameToSlug";
|
||||
import { projects } from "../data/projects";
|
||||
import { useEffect, useState } from "react";
|
||||
import getUnitTypeSlug from "../utils/getUnitTypeSlug";
|
||||
import { getUnitTypeVariantMarasiDrive } from "../utils/getUnitTypeVariantMarasiDrive";
|
||||
import { getUnitTypeVariantDubaiMarina } from "../utils/getUnitTypeVariantDubaiMarina";
|
||||
|
||||
function UnitCard({ unit }: { unit: Unit }) {
|
||||
const { favoriteUnits, setFavoriteUnits } = useFavoritesUnitsStore();
|
||||
@@ -75,10 +76,11 @@ function UnitCard({ unit }: { unit: Unit }) {
|
||||
</div>
|
||||
<div className="2xl:rounded-[0.556vw] rounded-xl 2xl:p-[0.556vw] p-2 overflow-hidden mx-auto">
|
||||
<img
|
||||
src={`/images/unit-types/${complexSlug}/${getUnitTypeSlug(
|
||||
complexSlug,
|
||||
unit.unitType
|
||||
)}.jpg`}
|
||||
src={`/images/unit-types/${complexSlug}/${
|
||||
complexSlug === "marasi-drive"
|
||||
? getUnitTypeVariantMarasiDrive(unit.unitNo)
|
||||
: getUnitTypeVariantDubaiMarina(unit.unitNo)
|
||||
}.jpg`}
|
||||
alt=""
|
||||
className="object-cover pointer-events-none"
|
||||
/>
|
||||
|
||||
@@ -0,0 +1,315 @@
|
||||
import { useEffect, useState } from "react";
|
||||
import { projects } from "../data/projects";
|
||||
import UnitTypeImageWithMarkers from "./UnitTypeImageWithMarkers";
|
||||
import Button from "./ui/Button";
|
||||
import { AnimatePresence, motion } from "framer-motion";
|
||||
import ChevronLeftIcon from "./icons/ChevronLeftIcon";
|
||||
import ChevronRightIcon from "./icons/ChevronRightIcon";
|
||||
import { useSwipeable } from "react-swipeable";
|
||||
import clsx from "clsx";
|
||||
|
||||
interface UnitSliderProps {
|
||||
unitTypeVariant: string;
|
||||
complexName: string;
|
||||
}
|
||||
// костыль: в Мараси 2 bedroom b ЕДИНСТВЕННАЯ НЕ ЗЕРКАЛЬНАЯ ХАТА среди всех
|
||||
function UnitSlider({ unitTypeVariant, complexName }: UnitSliderProps) {
|
||||
const [hasSide, setHasSide] = useState(false);
|
||||
|
||||
const [selectedSide, setSelectedSide] = useState<"left" | "right">();
|
||||
|
||||
const [isLoft, setIsLoft] = useState(false);
|
||||
|
||||
const [currentSlide, setCurrentSlide] = useState(0);
|
||||
|
||||
useEffect(
|
||||
() =>
|
||||
setSelectedSide(
|
||||
hasSide || unitTypeVariant === "2-bedroom-b" ? undefined : "left"
|
||||
),
|
||||
[hasSide, unitTypeVariant]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
setIsLoft(unitTypeVariant.includes("loft"));
|
||||
setHasSide(
|
||||
unitTypeVariant.endsWith("-left") || unitTypeVariant.endsWith("-right")
|
||||
);
|
||||
}, [unitTypeVariant]);
|
||||
|
||||
const handlers = useSwipeable({
|
||||
onSwipedLeft: () =>
|
||||
setCurrentSlide(Math.min(currentSlide + 1, isLoft ? 2 : 1)),
|
||||
onSwipedRight: () => setCurrentSlide(Math.max(currentSlide - 1, 0)),
|
||||
preventScrollOnSwipe: true,
|
||||
touchEventOptions: {
|
||||
passive: false,
|
||||
},
|
||||
trackMouse: true,
|
||||
});
|
||||
|
||||
return (
|
||||
<div
|
||||
className="relative w-full h-full overflow-hidden bg-[#F3F3F2] 2xl:rounded-[1.111vw] rounded-xl group"
|
||||
{...handlers}
|
||||
>
|
||||
<motion.div
|
||||
animate={{
|
||||
x: `calc(-${currentSlide} * 100%)`,
|
||||
}}
|
||||
transition={{
|
||||
duration: 0.5,
|
||||
ease: "easeInOut",
|
||||
}}
|
||||
className="flex h-full w-full relative top-0"
|
||||
>
|
||||
{isLoft ? (
|
||||
<>
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={`${selectedSide}-lower`}
|
||||
initial={{
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
opacity: 1,
|
||||
}}
|
||||
exit={{
|
||||
opacity: 0,
|
||||
}}
|
||||
className="shrink-0 w-full 2xl:p-[2.222vw] p-6"
|
||||
>
|
||||
<UnitTypeImageWithMarkers
|
||||
complexName={complexName}
|
||||
unitTypeVariant={
|
||||
hasSide
|
||||
? unitTypeVariant
|
||||
: `${unitTypeVariant}-lower-${selectedSide}`
|
||||
}
|
||||
floor={"lower"}
|
||||
legend={
|
||||
projects
|
||||
.find((project) => project.slug === complexName)
|
||||
?.types.find(
|
||||
(type) =>
|
||||
type.slug ===
|
||||
(hasSide
|
||||
? unitTypeVariant
|
||||
.split("-")
|
||||
.slice(0, isLoft ? -2 : -1)
|
||||
.join("-")
|
||||
: unitTypeVariant)
|
||||
)?.legend || []
|
||||
}
|
||||
/>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={`${selectedSide}-upper`}
|
||||
initial={{
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
opacity: 1,
|
||||
}}
|
||||
exit={{
|
||||
opacity: 0,
|
||||
}}
|
||||
className="shrink-0 w-full 2xl:p-[2.222vw] p-6"
|
||||
>
|
||||
<UnitTypeImageWithMarkers
|
||||
complexName={complexName}
|
||||
unitTypeVariant={
|
||||
hasSide
|
||||
? unitTypeVariant.replace("lower", "upper")
|
||||
: `${unitTypeVariant}-upper-${selectedSide}`
|
||||
}
|
||||
floor={"upper"}
|
||||
legend={
|
||||
projects
|
||||
.find((project) => project.slug === complexName)
|
||||
?.types.find(
|
||||
(type) =>
|
||||
type.slug ===
|
||||
(hasSide
|
||||
? unitTypeVariant
|
||||
.split("-")
|
||||
.slice(0, isLoft ? -2 : -1)
|
||||
.join("-")
|
||||
: unitTypeVariant)
|
||||
)?.legend || []
|
||||
}
|
||||
/>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
</>
|
||||
) : (
|
||||
<AnimatePresence mode="wait">
|
||||
<motion.div
|
||||
key={`${selectedSide}`}
|
||||
initial={{
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
opacity: 1,
|
||||
}}
|
||||
exit={{
|
||||
opacity: 0,
|
||||
}}
|
||||
className="shrink-0 w-full 2xl:p-[2.222vw] p-6"
|
||||
>
|
||||
<UnitTypeImageWithMarkers
|
||||
complexName={complexName}
|
||||
unitTypeVariant={
|
||||
hasSide || unitTypeVariant === "2-bedroom-b"
|
||||
? unitTypeVariant
|
||||
: `${unitTypeVariant}-${selectedSide}`
|
||||
}
|
||||
legend={
|
||||
projects
|
||||
.find((project) => project.slug === complexName)
|
||||
?.types.find(
|
||||
(type) =>
|
||||
type.slug ===
|
||||
(hasSide
|
||||
? unitTypeVariant.split("-").slice(0, -1).join("-")
|
||||
: unitTypeVariant)
|
||||
)?.legend || []
|
||||
}
|
||||
/>
|
||||
</motion.div>
|
||||
</AnimatePresence>
|
||||
)}
|
||||
<div className="w-full shrink-0">
|
||||
<img
|
||||
src={`/images/interiors/${complexName}/${
|
||||
complexName === "marasi-drive"
|
||||
? unitTypeVariant.split("-").slice(0, 2).join("-")
|
||||
: hasSide && unitTypeVariant !== "2-bedroom-b"
|
||||
? unitTypeVariant
|
||||
.split("-")
|
||||
.slice(0, isLoft ? -2 : -1)
|
||||
.join("-")
|
||||
: unitTypeVariant
|
||||
}.png`}
|
||||
alt=""
|
||||
className="object-cover h-full pointer-events-none 2xl:rounded-[1.111vw] rounded-2xl"
|
||||
/>
|
||||
</div>
|
||||
</motion.div>
|
||||
<AnimatePresence mode="wait">
|
||||
{!hasSide &&
|
||||
unitTypeVariant !== "2-bedroom-b" &&
|
||||
currentSlide !== (isLoft ? 2 : 1) && (
|
||||
<motion.div
|
||||
initial={{
|
||||
opacity: 0,
|
||||
}}
|
||||
animate={{
|
||||
opacity: 1,
|
||||
}}
|
||||
exit={{
|
||||
opacity: 0,
|
||||
}}
|
||||
className="flex 2xl:gap-[0.556vw] gap-2 items-center absolute 2xl:top-[2.222vw] top-6 left-1/2 -translate-x-1/2 max-md:hidden"
|
||||
>
|
||||
<p className="text-btn-m">Left</p>
|
||||
<div
|
||||
className="2xl:w-[2.778vw] w-10 2xl:p-[0.139vw] p-0.5 rounded-full cursor-pointer transition-colors bg-[#00BED7]"
|
||||
onClick={() =>
|
||||
setSelectedSide(selectedSide === "left" ? "right" : "left")
|
||||
}
|
||||
>
|
||||
<motion.div
|
||||
className="2xl:size-[1.389vw] size-5 rounded-full bg-white"
|
||||
initial={{
|
||||
x: selectedSide === "right" ? "80%" : 0,
|
||||
}}
|
||||
animate={{
|
||||
x: selectedSide === "right" ? "80%" : 0,
|
||||
}}
|
||||
transition={{ bounce: 0, duration: 0.3 }}
|
||||
/>
|
||||
</div>
|
||||
<p className="text-btn-m">Right</p>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
<div className="absolute flex 2xl:gap-[0.278vw] gap-1 items-center 2xl:bottom-[1.667vw] md:max-2xl:bottom-6 bottom-4 left-1/2 -translate-x-1/2">
|
||||
{isLoft ? (
|
||||
<>
|
||||
<Button
|
||||
variant={currentSlide === 0 ? "cta" : "secondary"}
|
||||
onClick={() => setCurrentSlide(0)}
|
||||
className="max-md:hidden"
|
||||
>
|
||||
Lower
|
||||
</Button>
|
||||
<Button
|
||||
variant={currentSlide === 1 ? "cta" : "secondary"}
|
||||
onClick={() => setCurrentSlide(1)}
|
||||
className="max-md:hidden"
|
||||
>
|
||||
Upper
|
||||
</Button>
|
||||
</>
|
||||
) : (
|
||||
<Button
|
||||
variant={currentSlide === 0 ? "cta" : "secondary"}
|
||||
onClick={() => setCurrentSlide(0)}
|
||||
className="max-md:hidden"
|
||||
>
|
||||
Layout
|
||||
</Button>
|
||||
)}
|
||||
<Button
|
||||
variant={currentSlide === (isLoft ? 2 : 1) ? "cta" : "secondary"}
|
||||
onClick={() => setCurrentSlide(isLoft ? 2 : 1)}
|
||||
className="max-md:hidden"
|
||||
>
|
||||
Interior
|
||||
</Button>
|
||||
{Array.from({ length: isLoft ? 3 : 2 }).map((_, index) => (
|
||||
<div
|
||||
key={index}
|
||||
className={clsx(
|
||||
"md:hidden size-2 rounded-full transition-colors",
|
||||
currentSlide === index ? "bg-[#00BED7]" : "bg-[#E2E2DC]"
|
||||
)}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="absolute top-1/2 -translate-y-1/2 2xl:left-[2.778vw] group-hover:opacity-100 opacity-0 transition-opacity duration-300 max-2xl:hidden"
|
||||
onlyIcon
|
||||
onClick={() =>
|
||||
setCurrentSlide(currentSlide === 0 ? 0 : currentSlide - 1)
|
||||
}
|
||||
disabled={currentSlide === 0}
|
||||
>
|
||||
<div className="2xl:size-[1.389vw] size-5">
|
||||
<ChevronLeftIcon />
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
variant="secondary"
|
||||
className="absolute top-1/2 -translate-y-1/2 2xl:right-[2.778vw] group-hover:opacity-100 opacity-0 transition-opacity duration-300 max-2xl:hidden"
|
||||
onlyIcon
|
||||
onClick={() =>
|
||||
setCurrentSlide(
|
||||
currentSlide === (isLoft ? 2 : 1) ? currentSlide : currentSlide + 1
|
||||
)
|
||||
}
|
||||
disabled={currentSlide === (isLoft ? 2 : 1)}
|
||||
>
|
||||
<div className="2xl:size-[1.389vw] size-5">
|
||||
<ChevronRightIcon />
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default UnitSlider;
|
||||
@@ -23,7 +23,10 @@ function UnitTypeCard({ project, type }: { project: Project; type: UnitType }) {
|
||||
</div>
|
||||
<div className="2xl:p-[1.111vw] 2xl:rounded-[0.556vw]">
|
||||
<img
|
||||
src={`/images/unit-types/${project.slug}/${type.slug}.jpg`}
|
||||
src={`/images/unit-types/${project.slug}/${type.slug}${
|
||||
type.slug.includes("loft") ? "-lower" : ""
|
||||
}${type.slug !== "2-bedroom-b" ? "-left" : ""}.jpg`}
|
||||
// костыль для единственной незеркальной хаты
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -2,33 +2,43 @@ import { useRef, useState } from "react";
|
||||
|
||||
function UnitTypeImageWithMarkers({
|
||||
complexName,
|
||||
unitType,
|
||||
legend,
|
||||
floor,
|
||||
}: {
|
||||
unitTypeVariant,
|
||||
}: // unitNumber,
|
||||
{
|
||||
complexName: string;
|
||||
unitType: string;
|
||||
legend: {
|
||||
name: string;
|
||||
x: number;
|
||||
y: number;
|
||||
x: [number, number];
|
||||
y: [number, number];
|
||||
floor?: "lower" | "upper";
|
||||
}[];
|
||||
floor?: "lower" | "upper";
|
||||
unitTypeVariant: string;
|
||||
// unitNumber: string;
|
||||
}) {
|
||||
console.log(complexName, unitType, floor);
|
||||
|
||||
const refRect = useRef<SVGRectElement>(null);
|
||||
const [hoveredIndex, setHoveredIndex] = useState<number | null>(null);
|
||||
|
||||
// Фильтруем legend по floor
|
||||
const filteredLegend = legend.filter(item => {
|
||||
const filteredLegend = legend.filter((item) => {
|
||||
// Если у элемента нет поля floor, показываем всегда
|
||||
if (!item.floor) return true;
|
||||
// Если у элемента есть поле floor, показываем только если оно совпадает с переданным floor
|
||||
return item.floor === floor;
|
||||
});
|
||||
|
||||
// const [unitTypeVariant, setUnitTypeVariant] = useState<string>();
|
||||
|
||||
// useEffect(() => {
|
||||
// setUnitTypeVariant(
|
||||
// complexName === "dubai-marina"
|
||||
// ? getUnitTypeVariantDubaiMarina(unitNumber, floor)
|
||||
// : getUnitTypeVariantMarasiDrive(unitNumber)
|
||||
// );
|
||||
// }, [complexName, unitNumber, floor]);
|
||||
|
||||
return (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
@@ -57,8 +67,7 @@ function UnitTypeImageWithMarkers({
|
||||
width={1312}
|
||||
height={1312}
|
||||
transform="scale(.5)"
|
||||
// xlinkHref={`/images/unit-types/${complexName}/${unitType}.png`}
|
||||
xlinkHref={`/images/unit-types/${complexName}/${unitType}${floor ? `-${floor}` : ""}.jpg`}
|
||||
xlinkHref={`/images/unit-types/${complexName}/${unitTypeVariant}.jpg`}
|
||||
style={{
|
||||
isolation: "isolate",
|
||||
}}
|
||||
@@ -68,12 +77,12 @@ function UnitTypeImageWithMarkers({
|
||||
<rect
|
||||
key={`marker-${index}`}
|
||||
ref={refRect}
|
||||
x={item.x}
|
||||
y={item.y}
|
||||
x={item.x[unitTypeVariant?.endsWith("left") ? 0 : 1]}
|
||||
y={item.y[unitTypeVariant?.endsWith("left") ? 0 : 1]}
|
||||
width={16}
|
||||
height={16}
|
||||
rx={8}
|
||||
className="stroke-white fill-[#00BED7] hover:fill-white transition-colors cursor-pointer"
|
||||
className="stroke-white fill-[#00BED7] hover:fill-white transition-colors cursor-pointer max-md:hidden"
|
||||
onMouseEnter={() => setHoveredIndex(index)}
|
||||
onMouseLeave={() => setHoveredIndex(null)}
|
||||
/>
|
||||
@@ -82,13 +91,17 @@ function UnitTypeImageWithMarkers({
|
||||
{filteredLegend.map((item, index) => (
|
||||
<g
|
||||
key={`tooltip-${index}`}
|
||||
className={`transition-opacity pointer-events-none ${
|
||||
className={`transition-opacity pointer-events-none max-md:hidden ${
|
||||
hoveredIndex === index ? "opacity-100" : "opacity-0"
|
||||
}`}
|
||||
>
|
||||
<rect
|
||||
x={item.x + 8 - (item.name.length * 8 + 32) / 2}
|
||||
y={item.y - 41}
|
||||
x={
|
||||
item.x[unitTypeVariant?.endsWith("left") ? 0 : 1] +
|
||||
8 -
|
||||
(item.name.length * 8 + 32) / 2
|
||||
}
|
||||
y={item.y[unitTypeVariant?.endsWith("left") ? 0 : 1] - 41}
|
||||
width={item.name.length * 8 + 32}
|
||||
height={30}
|
||||
rx={8}
|
||||
@@ -96,8 +109,8 @@ function UnitTypeImageWithMarkers({
|
||||
className="fill-white"
|
||||
/>
|
||||
<text
|
||||
x={item.x + 8}
|
||||
y={item.y - 26}
|
||||
x={item.x[unitTypeVariant?.endsWith("left") ? 0 : 1] + 8}
|
||||
y={item.y[unitTypeVariant?.endsWith("left") ? 0 : 1] - 26}
|
||||
textAnchor="middle"
|
||||
dominantBaseline="central"
|
||||
className="text-sm"
|
||||
|
||||