гзв fix bugs on ios

This commit is contained in:
2026-01-20 17:44:37 +05:00
parent 1722e9ab5e
commit 401f628d3e
20 changed files with 195 additions and 83 deletions
+1
View File
@@ -11,6 +11,7 @@ node_modules
dist dist
dist-ssr dist-ssr
*.local *.local
public/virtual-tours
# Editor directories and files # Editor directories and files
.vscode/* .vscode/*
+4 -1
View File
@@ -24,6 +24,7 @@
"@types/react-dom": "^19.2.2", "@types/react-dom": "^19.2.2",
"@vitejs/plugin-react": "^5.1.0", "@vitejs/plugin-react": "^5.1.0",
"autoprefixer": "^10.4.21", "autoprefixer": "^10.4.21",
"baseline-browser-mapping": "^2.9.14",
"eslint": "^9.39.1", "eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.24", "eslint-plugin-react-refresh": "^0.4.24",
@@ -236,7 +237,7 @@
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="], "balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
"baseline-browser-mapping": ["baseline-browser-mapping@2.8.25", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA=="], "baseline-browser-mapping": ["baseline-browser-mapping@2.9.14", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg=="],
"binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="], "binary-extensions": ["binary-extensions@2.3.0", "", {}, "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw=="],
@@ -644,6 +645,8 @@
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="], "anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
"browserslist/baseline-browser-mapping": ["baseline-browser-mapping@2.8.25", "", { "bin": { "baseline-browser-mapping": "dist/cli.js" } }, "sha512-2NovHVesVF5TXefsGX1yzx1xgr7+m9JQenvz6FQY3qd+YXkKkYiv+vTCc7OriP9mcDZpTC5mAOYN4ocd29+erA=="],
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="], "fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
+1
View File
@@ -29,6 +29,7 @@
"@types/react-dom": "^19.2.2", "@types/react-dom": "^19.2.2",
"@vitejs/plugin-react": "^5.1.0", "@vitejs/plugin-react": "^5.1.0",
"autoprefixer": "^10.4.21", "autoprefixer": "^10.4.21",
"baseline-browser-mapping": "^2.9.14",
"eslint": "^9.39.1", "eslint": "^9.39.1",
"eslint-plugin-react-hooks": "^5.2.0", "eslint-plugin-react-hooks": "^5.2.0",
"eslint-plugin-react-refresh": "^0.4.24", "eslint-plugin-react-refresh": "^0.4.24",
+2 -7
View File
@@ -19,9 +19,7 @@ function UnitFilters({ className }: { className?: string }) {
// Инициализация фильтров из URL при монтировании // Инициализация фильтров из URL при монтировании
useEffect(() => { useEffect(() => {
const units = searchParams.get("units"); const units = searchParams.get("units");
if (units) { if (units) setFiltersFromURLParams(units.split(","));
setFiltersFromURLParams(units.split(","));
}
}, [searchParams, setFiltersFromURLParams]); }, [searchParams, setFiltersFromURLParams]);
const filterCount = Object.entries(UNIT_TYPE_MAPPING).filter(([key]) => const filterCount = Object.entries(UNIT_TYPE_MAPPING).filter(([key]) =>
@@ -52,9 +50,7 @@ function UnitFilters({ className }: { className?: string }) {
) )
); );
setSearchParams({ units: unitsArray.join(",") }); setSearchParams({ units: unitsArray.join(",") });
} else { } else resetURLParams();
setSearchParams({});
}
} }
function resetURLParams() { function resetURLParams() {
@@ -79,7 +75,6 @@ function UnitFilters({ className }: { className?: string }) {
<AnimatePresence> <AnimatePresence>
{!showFiltersPopup && ( {!showFiltersPopup && (
<motion.div <motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
exit={{ opacity: 0 }} exit={{ opacity: 0 }}
className={clsx( className={clsx(
+12
View File
@@ -0,0 +1,12 @@
function VirtualDTourIcon() {
return (
<svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M18 3.475a2.65 2.65 0 0 1 2.65 2.65v13.84a.65.65 0 0 1-1.3 0V6.125A1.35 1.35 0 0 0 18 4.775h-1.585v4.407c0 .91-.74 1.65-1.65 1.65H14a.65.65 0 1 1 0-1.3h.765a.35.35 0 0 0 .35-.35V4.775H6a1.35 1.35 0 0 0-1.35 1.35v5.736h3.056a.35.35 0 0 0 .35-.35V9.482a.65.65 0 0 1 1.3 0v2.029a1.65 1.65 0 0 1-1.65 1.65H4.65v4.804c0 .745.604 1.35 1.35 1.35h8.294a.35.35 0 0 0 .35-.35v-3.009h-1.977a.65.65 0 1 1 0-1.3h2.127c.635 0 1.15.515 1.15 1.15v3.159a1.65 1.65 0 0 1-1.65 1.65H6a2.65 2.65 0 0 1-2.65-2.65V6.125A2.65 2.65 0 0 1 6 3.475z"
fill="currentColor"
/>
</svg>
);
}
export default VirtualDTourIcon;
+10 -29
View File
@@ -4,45 +4,26 @@ import { useEffect } from "react";
function DefaultLayout() { function DefaultLayout() {
useEffect(() => { useEffect(() => {
const setVh = () => { function setVh() {
// Получаем реальную высоту viewport
const vh = window.innerHeight * 0.01; const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--vh", `${vh}px`); document.documentElement.style.setProperty("--vh", `${vh}px`);
}; }
// const setVw = () => { setVh();
// const vw = window.innerWidth * 0.01;
// document.documentElement.style.setProperty("--vw", `${vw}px`);
// };
// Устанавливаем при монтировании window.addEventListener("DOMContentLoaded", setVh);
setVh(); window.addEventListener("resize", setVh)
// setVw(); window.addEventListener("orientationchange", setVh);
// Обновляем при изменении размера окна и ориентации
window.addEventListener("resize", () => {
setVh();
// setVw();
});
window.addEventListener("orientationchange", () => {
setVh();
// setVw();
});
return () => { return () => {
window.removeEventListener("resize", () => { window.removeEventListener("resize", setVh);
setVh(); window.removeEventListener("orientationchange", setVh);
// setVw(); window.removeEventListener("DOMContentLoaded", setVh);
});
window.removeEventListener("orientationchange", () => {
setVh();
// setVw();
});
}; };
}, []); }, []);
return ( return (
<div className="min-h-screen bg-[#F7F6F3]"> <div className="min-h-[calc(var(--vh)*100)] bg-[#F7F6F3]">
<NavMenu /> <NavMenu />
<main> <main>
<Outlet /> <Outlet />
+13
View File
@@ -0,0 +1,13 @@
import { Outlet } from "react-router";
function EmptyLayout() {
return (
<div className="min-h-[calc(var(--vh)*100)]">
<main className="h-[calc(var(--vh)*100)] overflow-hidden">
<Outlet />
</main>
</div>
);
}
export default EmptyLayout;
+23 -2
View File
@@ -3,6 +3,27 @@ import NavMenu from "./NavMenu";
import { useEffect } from "react"; import { useEffect } from "react";
function LayoutWithoutFooter() { function LayoutWithoutFooter() {
useEffect(() => {
function setVh() {
const vh = window.innerHeight * 0.01;
document.documentElement.style.setProperty("--vh", `${vh}px`);
document.body.style.setProperty("overflow", "hidden");
}
setVh();
window.addEventListener("resize", setVh);
window.addEventListener("orientationchange", setVh);
window.addEventListener("DOMContentLoaded", setVh);
return () => {
window.removeEventListener("resize", setVh);
window.removeEventListener("orientationchange", setVh);
window.removeEventListener("DOMContentLoaded", setVh);
document.body.style.removeProperty("overflow");
};
}, []);
const location = useLocation(); const location = useLocation();
useEffect(() => { useEffect(() => {
@@ -10,9 +31,9 @@ function LayoutWithoutFooter() {
}, [location.pathname]); }, [location.pathname]);
return ( return (
<div className="min-h-screen bg-[#F7F6F3] overflow-hidden"> <div className="min-h-[calc(var(--vh)*100)] bg-[#F7F6F3] overflow-hidden">
<NavMenu /> <NavMenu />
<main className="h-screen overflow-hidden"> <main className="h-[calc(var(--vh)*100)] overflow-hidden">
<Outlet /> <Outlet />
</main> </main>
</div> </div>
+1 -1
View File
@@ -33,7 +33,7 @@ export default function AboutPage() {
function AboutHero() { function AboutHero() {
return ( return (
<div className="bg-[url('/img/about/about_main.jpg')] bg-no-repeat [box-shadow:0_-100px_400px_rgba(0,0,0,0.9)_inset] flex flex-col justify-between items-center 2xl:pt-[1.667vw] md:pt-[2.083vw] pt-[4.444vw] 2xl:pb-[4.444vw] md:pb-[9.375vw] pb-[16.667vw] 2xl:rounded-b-[2.222vw] md:rounded-b-[4.167vw] rounded-b-[8.889vw] w-full 2xl:h-[95.5vh] md:h-[96.4vh] h-[94vh] bg-cover bg-center "> <div className="bg-[url('/img/about/about_main.jpg')] bg-no-repeat [box-shadow:0_-100px_400px_rgba(0,0,0,0.9)_inset] flex flex-col justify-between items-center 2xl:pt-[1.667vw] md:pt-[2.083vw] pt-[4.444vw] 2xl:pb-[4.444vw] md:pb-[9.375vw] pb-[16.667vw] 2xl:rounded-b-[2.222vw] md:rounded-b-[4.167vw] rounded-b-[8.889vw] w-full 2xl:h-[calc(var(--vh)*95.5)] md:h-[calc(var(--vh)*96.4)] h-[calc(var(--vh)*94)] bg-cover bg-center">
<img <img
src="/img/about/baraha_logo.svg" src="/img/about/baraha_logo.svg"
className="2xl:w-[13.681vw] md:w-[29.948vw] w-[45.556vw]" className="2xl:w-[13.681vw] md:w-[29.948vw] w-[45.556vw]"
+14 -3
View File
@@ -16,6 +16,7 @@ import { useUnitFiltersStore } from "../../stores/useUnitFiltersStore";
import { UNIT_TYPE_MAPPING, type UnitTypeKey } from "../../consts/blocksStats"; import { UNIT_TYPE_MAPPING, type UnitTypeKey } from "../../consts/blocksStats";
import { unitTypeByLabel } from "../../utils/unitTypeToLabel"; import { unitTypeByLabel } from "../../utils/unitTypeToLabel";
import UnitFilters from "../UnitFilters"; import UnitFilters from "../UnitFilters";
import VirtualDTourIcon from "../icons/VirtualDTourIcon";
function BlockPage() { function BlockPage() {
const { blockNumber } = useParams(); const { blockNumber } = useParams();
@@ -71,7 +72,7 @@ function BlockPage() {
} }
return ( return (
<div className="touch-none select-none bg-[url('/img/about/about_main.jpg')] bg-cover bg-center bg-no-repeat h-screen flex flex-col 2xl:gap-[8.25vh] items-center 2xl:py-[1.111vw] md:py-4 py-3 relative"> <div className="touch-none select-none bg-[url('/img/about/about_main.jpg')] bg-cover bg-center bg-no-repeat h-[calc(var(--vh)*100)] flex flex-col 2xl:gap-[calc(var(--vh)*8.25)] items-center 2xl:py-[1.111vw] md:py-4 py-3 relative">
<div className="absolute inset-0 bg-[#00000033] 2xl:backdrop-blur-[0.833vw] backdrop-blur-md [-webkit-backdrop-filter:blur(4px)]" /> <div className="absolute inset-0 bg-[#00000033] 2xl:backdrop-blur-[0.833vw] backdrop-blur-md [-webkit-backdrop-filter:blur(4px)]" />
<div className="flex items-start self-stretch relative 2xl:px-[1.111vw] md:px-4 px-3"> <div className="flex items-start self-stretch relative 2xl:px-[1.111vw] md:px-4 px-3">
<div className="flex-1 flex"> <div className="flex-1 flex">
@@ -86,7 +87,7 @@ function BlockPage() {
</Button> </Button>
</Link> </Link>
</div> </div>
<div className="flex flex-col items-center 2xl:gap-[4vh] relative"> <div className="flex flex-col items-center 2xl:gap-[calc(var(--vh)*4)] relative">
<h1 className="2xl:text-[2.222vw] text-[32px] [font-family:New_York_Medium] text-white flex-1 text-center"> <h1 className="2xl:text-[2.222vw] text-[32px] [font-family:New_York_Medium] text-white flex-1 text-center">
Block {blockNumber} Block {blockNumber}
</h1> </h1>
@@ -133,7 +134,7 @@ function BlockPage() {
</div> </div>
</div> </div>
<div className="max-2xl:overflow-x-scroll [scrollbar-width:none] max-2xl:max-w-full 2xl:mx-auto flex-1 relative"> <div className="max-2xl:overflow-x-scroll [scrollbar-width:none] max-2xl:max-w-full 2xl:mx-auto flex-1 relative">
<div className="2xl:w-[125vh] w-[min(175vw,1000px)] flex max-2xl:h-full relative"> <div className="2xl:w-[calc(var(--vh)*125)] w-[min(175vw,1000px)] flex max-2xl:h-full relative">
<svg <svg
viewBox="0 0 1000 476" viewBox="0 0 1000 476"
className="m-auto absolute max-md:inset-0" className="m-auto absolute max-md:inset-0"
@@ -211,6 +212,16 @@ function BlockPage() {
</div> </div>
</div> </div>
<UnitFilters className="2xl:!top-[4.444vw] md:!top-16 !top-[60px]" /> <UnitFilters className="2xl:!top-[4.444vw] md:!top-16 !top-[60px]" />
<Link
to={`/virtual-tour/${blockNumber}`}
className="absolute 2xl:left-[1.111vw] md:left-4 left-3 2xl:top-[7.778vw] md:top-[112px] top-[108px]"
>
<Button variant="cta">
<div className="2xl:size-[1.111vw] size-4">
<VirtualDTourIcon />
</div>
</Button>
</Link>
<Compass <Compass
degrees={0} degrees={0}
className="absolute 2xl:bottom-[1.111vw] bottom-4 2xl:left-[1.111vw] left-4" className="absolute 2xl:bottom-[1.111vw] bottom-4 2xl:left-[1.111vw] left-4"
+1 -1
View File
@@ -3,7 +3,7 @@ import Socials from "../Socials";
function ContactsPage() { function ContactsPage() {
return ( return (
<div className="2xl:p-[2.778vw_2.778vw_12vh] md:p-[24px_24px_96px] p-[16px_16px_88px] 2xl:space-y-[2.222vw] space-y-8"> <div className="2xl:p-[2.778vw_2.778vw_calc(var(--vh)*12)] md:p-[24px_24px_96px] p-[16px_16px_88px] 2xl:space-y-[2.222vw] space-y-8">
<Feedback /> <Feedback />
<hr className="w-full border-[#ECE8DF] 2xl:border-[0.069vw] border-[1px] col-span-full" /> <hr className="w-full border-[#ECE8DF] 2xl:border-[0.069vw] border-[1px] col-span-full" />
<Socials /> <Socials />
+9 -15
View File
@@ -43,16 +43,12 @@ function constrainPosition(
const scaledWidth = imageSize.width * zoom; const scaledWidth = imageSize.width * zoom;
const scaledHeight = imageSize.height * zoom; const scaledHeight = imageSize.height * zoom;
console.log(imageSize);
// Строгие границы: изображение не должно выходить за пределы контейнера // Строгие границы: изображение не должно выходить за пределы контейнера
// Максимальная позиция: 0 (верхний левый угол контейнера) // Максимальная позиция: 0 (верхний левый угол контейнера)
// Минимальная позиция: когда правый/нижний край изображения совпадает с правым/нижним краем контейнера // Минимальная позиция: когда правый/нижний край изображения совпадает с правым/нижним краем контейнера
const minX = containerSize.width - scaledWidth; const minX = containerSize.width - scaledWidth;
const minY = containerSize.height - scaledHeight; const minY = containerSize.height - scaledHeight;
console.log({ minX, minY, position, scaledWidth, scaledHeight, zoom });
return { return {
x: Math.min(0, Math.max(minX, position.x)), x: Math.min(0, Math.max(minX, position.x)),
y: Math.min(0, Math.max(minY, position.y)), y: Math.min(0, Math.max(minY, position.y)),
@@ -105,8 +101,6 @@ function calculateCenterPosition(
}; };
} }
// const FRAME_COUNT = 360;
// const FRAME_STEP = 90;
const FRAME_COUNT = 120; const FRAME_COUNT = 120;
const FRAME_STEP = 30; const FRAME_STEP = 30;
@@ -774,10 +768,6 @@ function MasterplanPage() {
const currentFrame = Math.floor(currentIndex / FRAME_STEP); const currentFrame = Math.floor(currentIndex / FRAME_STEP);
useEffect(() => {
console.log("zoom", zoom);
}, [zoom]);
return ( return (
<div className="overflow-hidden size-full select-none" ref={rootRef}> <div className="overflow-hidden size-full select-none" ref={rootRef}>
<AnimatePresence> <AnimatePresence>
@@ -900,7 +890,7 @@ function MasterplanPage() {
key={`${currentFrame}-${index}`} key={`${currentFrame}-${index}`}
style={{ style={{
display: !blockHasSelectedUnits(index) ? "none" : "block", display: !blockHasSelectedUnits(index) ? "none" : "block",
transform: `scale(${1 / zoom})`, scale: 1 / zoom,
transformOrigin: `${ transformOrigin: `${
x - Math.max(0.00694 * innerWidth, 10) / 2 x - Math.max(0.00694 * innerWidth, 10) / 2
}px ${y - Math.max(0.00694 * innerWidth, 10) / 2}px`, }px ${y - Math.max(0.00694 * innerWidth, 10) / 2}px`,
@@ -913,7 +903,10 @@ function MasterplanPage() {
fill="white" fill="white"
stroke="rgba(50, 77, 67, 0.15)" stroke="rgba(50, 77, 67, 0.15)"
strokeWidth={2} strokeWidth={2}
className="cursor-pointer" className={clsx(
"cursor-pointer",
!blockHasSelectedUnits(index) && "hidden"
)}
/> />
</motion.g> </motion.g>
))} ))}
@@ -942,7 +935,7 @@ function MasterplanPage() {
))} ))}
{/* Facilities */} {/* Facilities */}
<AnimatePresence mode="wait"> <AnimatePresence>
{isShowVideo && {isShowVideo &&
hoveredMaskIndex === null && hoveredMaskIndex === null &&
facilitiesPoints[currentFrame].map( facilitiesPoints[currentFrame].map(
@@ -951,9 +944,10 @@ function MasterplanPage() {
initial={{ opacity: 0 }} initial={{ opacity: 0 }}
animate={{ opacity: 1 }} animate={{ opacity: 1 }}
exit={{ opacity: 0 }} exit={{ opacity: 0 }}
key={`facility-${currentFrame}-${index}-${isShowVideo}-${hoveredMaskIndex}`} key={`facility-${currentFrame}-${index}`}
style={{ style={{
transform: `scale(${1 / zoom})`, scale: 1 / zoom,
// transform: `scale(${1 / zoom})`,
transformOrigin: `${ transformOrigin: `${
x - Math.max(0.02222 * innerWidth, 32) / 2 x - Math.max(0.02222 * innerWidth, 32) / 2
}px ${y - Math.max(0.02222 * innerWidth, 32) / 2}px`, }px ${y - Math.max(0.02222 * innerWidth, 32) / 2}px`,
+1 -1
View File
@@ -1014,7 +1014,7 @@ function SurroundingsPage({ maxZoom = 3 }: MapProps) {
style={imageStyle} style={imageStyle}
viewBox="0 0 4096 2176" viewBox="0 0 4096 2176"
> >
<AnimatePresence mode="wait"> <AnimatePresence>
{selectedPoint && {selectedPoint &&
(Array.isArray(selectedPoint.path) ? ( (Array.isArray(selectedPoint.path) ? (
// Для составных путей: сначала пунктир (index 1), потом сплошная (index 0) // Для составных путей: сначала пунктир (index 1), потом сплошная (index 0)
+49
View File
@@ -0,0 +1,49 @@
import { Link, useParams } from "react-router";
import Button from "../ui/Button";
import ChevronLeftIcon from "../icons/ChevronLeftIcon";
function VirtualTourPage() {
const { blockNumber } = useParams();
return (
<div className="relative size-full">
<iframe
className="absolute inset-0 size-full"
src={`/virtual-tours/B${blockNumber}/index.html`}
/>
<Link
to={"/blocks/" + blockNumber}
className="absolute 2xl:top-[1.111vw] top-4 2xl:left-[1.111vw] left-4"
>
<Button variant="primary">
<div className="2xl:size-[1.111vw] size-4">
<ChevronLeftIcon />
</div>
<span className="max-md:hidden">Baraha Town</span>
</Button>
</Link>
<div className="absolute left-1/2 -translate-x-1/2 2xl:top-[1.111vw] md:top-4 top-3 flex 2xl:gap-[0.556vw] gap-2"></div>
<div
onClick={() => {
window.location.href = "/";
}}
className="cursor-pointer"
>
<img
src="/img/about/baraha_logo.svg"
className="absolute 2xl:top-[1.111vw] top-4 2xl:right-[1.111vw] right-4 2xl:w-[13.681vw] md:w-[165px] select-none max-md:hidden"
draggable={false}
alt="baraha-logo"
/>
<img
src="/img/about/baraha_logo_mini.svg"
className="absolute size-10 md:hidden select-none top-4 right-4"
draggable={false}
alt="baraha-logo-mobile"
/>
</div>
</div>
);
}
export default VirtualTourPage;
+1 -1
View File
@@ -27,7 +27,7 @@ function BlockPopup({
}; };
return ( return (
<div className="flex flex-col 2xl:gap-y-[1.667vw] gap-y-6 2xl:p-[1.111vw] p-4 2xl:rounded-[1.111vw] md:max-2xl:rounded-xl rounded-t-2xl bg-white 2xl:w-[18.472vw] md:max-2xl:w-[266px] w-screen"> <div className="select-none flex flex-col 2xl:gap-y-[1.667vw] gap-y-6 2xl:p-[1.111vw] p-4 2xl:rounded-[1.111vw] md:max-2xl:rounded-xl rounded-t-2xl bg-white 2xl:w-[18.472vw] md:max-2xl:w-[266px] w-[calc(var(--vh)*100)]">
{isMobile && ( {isMobile && (
<Button <Button
variant="secondary" variant="secondary"
+1 -1
View File
@@ -26,7 +26,7 @@ function FacilityPopup({
return ( return (
<div <div
className={clsx( className={clsx(
"select-none flex flex-col 2xl:gap-y-[1.111vw] gap-y-4 2xl:w-[20.556vw] md:max-2xl:w-[296px] w-screen bg-white 2xl:p-[0.833vw] p-3 2xl:rounded-[0.833vw] md:rounded-xl rounded-t-xl", "select-none flex flex-col 2xl:gap-y-[1.111vw] gap-y-4 2xl:w-[20.556vw] md:max-2xl:w-[296px] w-[calc(var(--vh)*100)] bg-white 2xl:p-[0.833vw] p-3 2xl:rounded-[0.833vw] md:rounded-xl rounded-t-xl",
className className
)} )}
> >
+1 -1
View File
@@ -43,7 +43,7 @@ function FiltersPopup({ onUpdateURL, onResetURL }: FiltersPopupProps) {
transform: `translateX(calc(${-parentBoundingClientRect! transform: `translateX(calc(${-parentBoundingClientRect!
.width}px - max(0.521vw, 10px)))`, .width}px - max(0.521vw, 10px)))`,
}} }}
className="max-md:!translate-x-0 select-none 2xl:p-[1.111vw] p-4 flex flex-col 2xl:gap-[1.111vw] gap-4 bg-white 2xl:rounded-[1.111vw] md:rounded-2xl max-md:rounded-t-2xl z-10 2xl:max-w-[17.778vw] md:max-w-[256px] max-md:w-screen" className="max-md:!translate-x-0 select-none 2xl:p-[1.111vw] p-4 flex flex-col 2xl:gap-[1.111vw] gap-4 bg-white 2xl:rounded-[1.111vw] md:rounded-2xl max-md:rounded-t-2xl z-10 2xl:max-w-[17.778vw] md:max-w-[256px] max-md:w-[calc(var(--vh)*100)]"
> >
<Button <Button
variant="secondary" variant="secondary"
+1 -16
View File
@@ -1,6 +1,3 @@
// import VirtualTourIcon from "../icons/VirtualTourIcon";
// import Button from "../ui/Button";
import clsx from "clsx"; import clsx from "clsx";
import { usePopupStore } from "../../stores/usePopupStore"; import { usePopupStore } from "../../stores/usePopupStore";
import Button from "../ui/Button"; import Button from "../ui/Button";
@@ -18,7 +15,7 @@ function UnitPopup({ unitType, square, block, floor }: UnitPopupProps) {
const { side, setPopup, setHasBackdrop } = usePopupStore(); const { side, setPopup, setHasBackdrop } = usePopupStore();
return ( return (
<div className="bg-[#F7F6F3] 2xl:p-[0.833vw] p-3 2xl:rounded-[1.111vw] md:rounded-2xl rounded-t-2xl 2xl:w-[13.958vw] md:min-w-[176px] md:max-w-[200px] w-screen"> <div className="select-none bg-[#F7F6F3] 2xl:p-[0.833vw] p-3 2xl:rounded-[1.111vw] md:rounded-2xl rounded-t-2xl 2xl:w-[13.958vw] md:min-w-[176px] md:max-w-[200px] w-[calc(var(--vh)*100)]">
{isMobile && ( {isMobile && (
<Button <Button
variant="secondary" variant="secondary"
@@ -43,18 +40,6 @@ function UnitPopup({ unitType, square, block, floor }: UnitPopupProps) {
<p className="caption-s text-[#A7A08E]">{floor}</p> <p className="caption-s text-[#A7A08E]">{floor}</p>
</div> </div>
</div> </div>
{/* <hr className="border-[#ECE8DF] 2xl:border-[0.069vw] border-[1px]" />
<div className="flex 2xl:gap-[0.278vw] 2xl:flex-col">
<Button variant="cta" size={innerWidth >= 768 ? "small" : "large"}>
Book
</Button>
<Button variant="primary" size={innerWidth >= 768 ? "small" : "large"}>
<div className="2xl:size-[1.111vw] size-4">
<VirtualTourIcon />
</div>
Virtual tour
</Button>
</div> */}
<div <div
className={clsx( className={clsx(
"max-md:hidden absolute 2xl:[border-width:0.556vw_0px_0.486vw_0.556vw] [border-width:8px_0px_7px_8px] [border-color:_transparent_transparent_transparent_#fff]", "max-md:hidden absolute 2xl:[border-width:0.556vw_0px_0.486vw_0.556vw] [border-width:8px_0px_7px_8px] [border-color:_transparent_transparent_transparent_#fff]",
+12 -1
View File
@@ -1,5 +1,5 @@
import { createRoot } from "react-dom/client";
import "./index.css"; import "./index.css";
import { createRoot } from "react-dom/client";
import { createBrowserRouter, RouterProvider, Navigate } from "react-router"; import { createBrowserRouter, RouterProvider, Navigate } from "react-router";
import DefaultLayout from "./components/layouts/DefaultLayout.tsx"; import DefaultLayout from "./components/layouts/DefaultLayout.tsx";
import AboutPage from "./components/pages/AboutPage.tsx"; import AboutPage from "./components/pages/AboutPage.tsx";
@@ -10,6 +10,8 @@ import LayoutWithoutFooter from "./components/layouts/LayoutWithoutFooter.tsx";
import MasterplanPage from "./components/pages/MasterplanPage.tsx"; import MasterplanPage from "./components/pages/MasterplanPage.tsx";
import BlockPage from "./components/pages/BlockPage.tsx"; import BlockPage from "./components/pages/BlockPage.tsx";
import ModalContainer from "./components/ModalContainer.tsx"; import ModalContainer from "./components/ModalContainer.tsx";
import EmptyLayout from "./components/layouts/EmptyLayout.tsx";
import VirtualTourPage from "./components/pages/VirtualTourPage.tsx";
const router = createBrowserRouter([ const router = createBrowserRouter([
{ {
@@ -53,6 +55,15 @@ const router = createBrowserRouter([
}, },
], ],
}, },
{
path: "/virtual-tour",
element: <Navigate to="/" replace />,
},
{
path: "/virtual-tour/:blockNumber",
element: <EmptyLayout />,
children: [{ index: true, element: <VirtualTourPage /> }],
},
]); ]);
createRoot(document.getElementById("root")!).render( createRoot(document.getElementById("root")!).render(
+39 -4
View File
@@ -3,10 +3,45 @@ export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"],
theme: { theme: {
extend: { extend: {
screens: { // height: ({ theme }) => ({
"2xl": "1440px", // ...theme("height"),
// screen: `calc(var(--vh, ${innerHeight * 0.01}px) * 100)`,
// dvh: `calc(var(--vh, ${innerHeight * 0.01}px) * 100)`,
// }),
// minHeight: ({ theme }) => ({
// ...theme("minHeight"),
// screen: `calc(var(--vh, ${innerHeight * 0.01}px) * 100)`,
// dvh: `calc(var(--vh, ${innerHeight * 0.01}px) * 100)`,
// }),
// maxHeight: ({ theme }) => ({
// ...theme("maxHeight"),
// screen: `calc(var(--vh, ${innerHeight * 0.01}px) * 100)`,
// dvh: `calc(var(--vh, ${innerHeight * 0.01}px) * 100)`,
// }),
}, },
}, },
}, plugins: [
plugins: [], // plugin(function ({ addBase }) {
// addBase({
// ":root": {
// "--vh": `${innerHeight * 0.01}px`,
// },
// });
// }),
// // Дополнительные утилиты для разных единиц vh
// plugin(function ({ addUtilities, theme }) {
// const newUtilities = {
// ".h-dynamic-screen": {
// height: `calc(var(--vh, ${innerHeight * 0.01}px) * 100)`,
// },
// ".min-h-dynamic-screen": {
// "min-height": `calc(var(--vh, ${innerHeight * 0.01}px) * 100)`,
// },
// ".max-h-dynamic-screen": {
// "max-height": `calc(var(--vh, ${innerHeight * 0.01}px) * 100)`,
// },
// };
// addUtilities(newUtilities);
// }),
],
}; };