Files
graff.estate-nextjs/src/components/VideoSliderMobile.tsx
T
2024-03-18 13:38:16 +05:00

167 lines
7.1 KiB
TypeScript

/* eslint-disable react-hooks/rules-of-hooks */
/* eslint-disable react-hooks/exhaustive-deps */
import { motion } from "framer-motion";
import { useEffect, useRef, useState } from "react";
import ArrowLeftIcon from "./icons/ArrowLeftIcon";
import ArrowRightIcon from "./icons/ArrowRightIcon";
import { useSwipeable } from "react-swipeable";
function VideoSliderMobile() {
const [items] = useState<any[]>([
{
title: "Виртуальный тур по жилому комплексу",
desc: "Клиент лично оценит угол инсоляции, малые архитектурные формы и ландшафт, перемещаясь по комплексу с помощью тапа.",
video: "/videos/features/virtual_tour.mp4",
},
{
title: "Вся инфрастуктура на одном экране",
desc: "Возможность оценить инфраструктуру района покажет важные для клиента точки интереса и время, за которое он сможет до них дойти.",
video: "/videos/features/nks_infra.mp4",
},
{
title: "Конфигуратор интерьера",
desc: "Клиент может свободно выбирать мебель и дизайн с помощью конфигуратора интерьера. Возможно выбрать стиль всей квартиры или изменить отдельные детали.",
video: "/videos/features/uralsky.mp4",
},
{
title: "Параметрический поиск квартир",
desc: "Фильтр позволит отметить конкретные преимущества, определить количество комнат, желаемый этаж, цену, и получить выборку подходящих вариантов.",
video: "/videos/features/parametric.mp4",
},
{
title: "Любой рендер за несколько секунд",
desc: "Когда для рекламы вам понадобится любой объект с любого ракурса, просто сделайте фотографию внутри презентации.",
video: "/videos/features/render.mp4",
},
{
title: "Формирование вишлиста",
desc: "Клиент может добавить варианты квартир в избранное, сравнить их между собой по основным параметрам и выбрать свою будущую квартиру.",
video: "/videos/features/wish.mp4",
},
{
title: "Интеграция с CRM-системой",
desc: "Приложение передает информацию о клиенте в CRM-систему застройщика и получает актуальную информацию по ценам и статусам квартир.",
video: "/videos/features/integra_crm.mp4",
},
{
title: "Отправка коммерческого предложения",
desc: "Коммерческое предложение с выбранными квартирами может быть отправлено клиенту на почту или распечатано и отдано лично в руки.",
video: "/videos/features/send.mp4",
},
// {
// title: "Интерактивная инсоляция",
// desc: "Функция позволяет в режиме реального времени увидеть уровень освещенности выбранной квартиры, а если вы изучаете экстерьер жилого комплекса – функция покажет архитектурную подсветку.",
// video: "",
// },
// {
// title: "Подбор квартир на генплане",
// desc: "Сделать генплан удобным инструментом выбора квартиры поможет подсветка выбранных квартир прямо на фасаде Жилого комплекса.",
// video: "",
// },
]);
const [activeIndex, setActiveIndex] = useState<number>(0);
const videoRefs = items.map(() => useRef<HTMLVideoElement>(null));
const handlers = useSwipeable({
onSwiped: (e) => {
if (e.dir === "Left") {
handleClickNext();
}
if (e.dir === "Right") {
handleClickPrev();
}
},
});
function handleClickPrev() {
if (activeIndex === 0) {
setActiveIndex(items.length - 1);
return;
}
setActiveIndex((prev) => prev - 1);
}
function handleClickNext() {
if (activeIndex === items.length - 1) {
setActiveIndex(0);
return;
}
setActiveIndex((prev) => prev + 1);
}
useEffect(() => {
items.forEach((_, index) => {
if (activeIndex === index) {
videoRefs[index].current?.play();
} else {
videoRefs[index].current?.pause();
}
});
}, [activeIndex]);
return (
<div
{...handlers}
className="xl:hidden flex flex-col sm:gap-6 gap-4 border-b border-[#3D425C] pb-5"
>
<div
// ref={videosContainerRef}
className={`relative flex sm:gap-[88px] items-start transition-all duration-500`}
style={{ left: `-${activeIndex * 100}%` }}
>
{items.map((item, index) => (
<motion.video
key={index}
ref={videoRefs[index]}
src={item.video}
muted
loop
playsInline
preload="metadata"
className={`relative aspect-video transition-all duration-500 sm:w-[calc(100%-88px)] ${
index !== activeIndex
? "sm:scale-[70%] scale-[80%] sm:-translate-y-[15%] -translate-y-[10%] sm:-translate-x-[calc(15%+88px-12px)] -translate-x-[calc(10%-8px)]"
: ""
}`}
/>
))}
</div>
<div className="flex justify-between sm:gap-[30px] gap-3 sm:h-auto h-[168px]">
<div className="flex flex-col gap-3">
<p className="text-xl font-gilroy font-medium">
{items[activeIndex].title}
</p>
<p className="text-sm">{items[activeIndex].desc}</p>
</div>
<div className="relative flex flex-col items-center gap-4">
<div className="sm:absolute -top-[64px]">
<p className="sm:text-2xl text-xl font-gilroy font-medium">
{activeIndex + 1}/{items.length}
</p>
</div>
<div className="flex flex-col gap-2 self-end">
<button
onClick={handleClickNext}
className="sm:p-4 p-2 border border-[#3D425C] rounded-full outline-none"
>
<ArrowRightIcon />
</button>
<button
onClick={handleClickPrev}
className="sm:p-4 p-2 border border-[#3D425C] rounded-full outline-none"
>
<ArrowLeftIcon />
</button>
</div>
</div>
</div>
</div>
);
}
export default VideoSliderMobile;