122 lines
5.1 KiB
TypeScript
122 lines
5.1 KiB
TypeScript
"use client";
|
||
|
||
import { useGetProjectsQuery } from "@/queries/getProjects";
|
||
import { Title } from "@/ui/Title";
|
||
import { VideoPlayer } from "@/ui/VideoPlayer";
|
||
import { motion } from "framer-motion";
|
||
import Link from "next/link";
|
||
import { useState } from "react";
|
||
import { useSwipeable } from "react-swipeable";
|
||
import { StreamingProject } from "./StreamingProject";
|
||
|
||
export function Streaming() {
|
||
const { data: streamingProjects } = useGetProjectsQuery(
|
||
"Удаленная демонстрация"
|
||
);
|
||
|
||
const [isViewportEntered, setIsViewportEntered] = useState(false);
|
||
|
||
const handleOnViewportFeatureEnter = () => {
|
||
if (isViewportEntered) return;
|
||
|
||
setIsViewportEntered(true);
|
||
};
|
||
|
||
const [current, setCurrent] = useState(0);
|
||
|
||
const handlers = useSwipeable({
|
||
onSwipedLeft: () =>
|
||
setCurrent(
|
||
(prev) => (prev + 1) % Math.min(streamingProjects!.length + 1, 4)
|
||
),
|
||
onSwipedRight: () =>
|
||
setCurrent(
|
||
(prev) =>
|
||
(prev + Math.min(streamingProjects!.length, 4)) %
|
||
Math.min(streamingProjects!.length + 1, 4)
|
||
),
|
||
trackMouse: true,
|
||
preventScrollOnSwipe: true,
|
||
touchEventOptions: { passive: false },
|
||
});
|
||
|
||
return (
|
||
<motion.div
|
||
onViewportEnter={handleOnViewportFeatureEnter}
|
||
viewport={{ margin: "-10% 0% 0% 0%", once: true }}
|
||
className="lg:mt-[140px] mt-[100px] lg:space-y-[4.444vw] md:max-lg:space-y-[6.25vw] space-y-[11.111vw]"
|
||
>
|
||
<Title className="max-md:hidden select-none">
|
||
Уникальная технология
|
||
<span className="text-gradient"> удаленной демонстрации</span>{" "}
|
||
дает возможность презентовать объект покупателю из любой точки
|
||
мира
|
||
</Title>
|
||
<Title headerLevel={2} className="md:hidden text-center select-none">
|
||
<span className="text-gradient">Удаленная демонстрация — </span>
|
||
презентуйте объект покупателю из любой точки мира
|
||
</Title>
|
||
<div
|
||
className="lg:grid md:flex grid-cols-4 gap-3 px-5 md:-mx-5 md:overflow-auto [scrollbar-width:none] relative max-md:aspect-[340/344] [transform-style:preserve-3d] items-stretch"
|
||
{...handlers}
|
||
>
|
||
{streamingProjects?.slice(0, 3).map((project, index, { length }) => (
|
||
<StreamingProject
|
||
key={project.id}
|
||
{...project}
|
||
index={index}
|
||
current={current}
|
||
count={length + 1}
|
||
href="/"
|
||
/>
|
||
))}
|
||
<div
|
||
className={`bg-gradient-to-r from-[#FFFFFF14] to-[#FFFFFF00] [background:linear-gradient(to_right,#FFFFFF14,#FFFFFF00)] p-0.5 lg:rounded-[1.111vw] rounded-2xl flex flex-1 justify-center !duration-500 items-center md:min-w-[300px] group max-md:absolute self-stretch max-md:h-full transition-[scale,transform] will-change-[transform,scale] select-none max-md:w-[calc(100%-40px)] max-md:bg-[#0F101199] max-md:[backdrop-filter:blur(40px)] ${
|
||
streamingProjects &&
|
||
(Math.min(streamingProjects!.length + 1, 4) - 1 === current
|
||
? "max-md:[transform:translateZ(40px)]"
|
||
: "max-md:[scale:85%]")
|
||
} ${
|
||
streamingProjects &&
|
||
(Math.min(streamingProjects!.length + 1, 4) - 1 ===
|
||
(current + 1) % Math.min(streamingProjects!.length + 1, 4)
|
||
? "max-md:translate-x-[calc(7.5%+20px)]"
|
||
: Math.min(streamingProjects!.length + 1, 4) - 1 ===
|
||
(current - 1 + Math.min(streamingProjects!.length + 1, 4)) %
|
||
Math.min(streamingProjects!.length + 1, 4)
|
||
? "max-md:translate-x-[calc(-7.5%-20px)]"
|
||
: "")
|
||
}`}
|
||
>
|
||
<div className="md:bg-[#0F1011] h-full w-full lg:rounded-[1.111vw] rounded-2xl flex items-center p-6">
|
||
<div className="flex flex-col items-center space-y-6">
|
||
<p className="heading2 font-medium text-center">
|
||
Расскажем и покажем как это работает на созвоне
|
||
</p>
|
||
<Link
|
||
href={"/form"}
|
||
className="btnm font-medium group-hover:scale-105 duration-500 lg:px-[1.667vw] lg:py-[1.181vw] px-6 py-[17px] transition-transform lg:rounded-[0.833vw] rounded-xl bg-gradient"
|
||
>
|
||
Оставить заявку
|
||
</Link>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<VideoPlayer
|
||
src="/videos/pages/home/streaming.mp4"
|
||
showMutingBtn
|
||
loop
|
||
autoPlay
|
||
muted
|
||
className="lg:apect-[1400/640] max-h-dvh md:max-lg:aspect-[736/480] aspect-[340/600]"
|
||
>
|
||
<p className="absolute font-medium md:bottom-6 md:left-6 bottom-4 left-4 lg:max-w-[40%] md:max-lg:max-w-[80%] accent">
|
||
GRAFF.estate Stream доступен на любых устройствах,
|
||
для демонстрации нужен только интернет
|
||
</p>
|
||
</VideoPlayer>
|
||
</motion.div>
|
||
);
|
||
}
|