This commit is contained in:
2024-06-05 18:31:02 +05:00
parent 6d8641f934
commit 551eb0964e
5 changed files with 88 additions and 13 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ function ModalContainer() {
if (modal) {
return (
<div
className={`fixed p-8 top-0 left-0 z-10 w-full h-full flex justify-center items-center bg-black bg-opacity-80 overflow-auto transition-opacity`}
className={`fixed p-8 top-0 left-0 z-10 w-full h-full flex justify-center items-center bg-black bg-opacity-80 overflow-hidden transition-opacity`}
>
<div onClick={(e) => e.stopPropagation()} className="cursor-default">
{modal}
+17 -9
View File
@@ -6,8 +6,11 @@ import { useSwipeable } from "react-swipeable";
import ArrowLeftIcon from "./icons/ArrowLeftIcon";
import ArrowRightIcon from "./icons/ArrowRightIcon";
import { reviews } from "../consts/reviews";
import useModalStore from "@stores/useModalStore";
import VideoModal from "./modals/VideoModal";
function Reviews() {
const { setModal } = useModalStore();
const [selectedImageIndex, setSelectedImageIndex] = useState(0);
const imageRefs = reviews.map(() => createRef<HTMLImageElement>());
const [imageWidth, setImageWidth] = useState<number>(0);
@@ -19,11 +22,9 @@ function Reviews() {
trackMouse: true,
});
useEffect(() => {
if (!imageRefs[0].current?.src) return;
const width = imageRefs[0].current.clientWidth;
setImageWidth(width);
}, [imageRefs[0]]);
const onVideoClick = (video: string) => {
setModal(<VideoModal link={video} />);
};
function prev() {
if (selectedImageIndex === 0) return;
@@ -41,6 +42,12 @@ function Reviews() {
setIsEntered(true);
}, [inView]);
useEffect(() => {
if (!imageRefs[0].current?.src) return;
const width = imageRefs[0].current.clientWidth;
setImageWidth(width);
}, [imageRefs[0]]);
return (
<div
ref={ref}
@@ -121,9 +128,10 @@ function Reviews() {
clipPath: `rect(auto auto auto 0)`,
}}
>
{reviews.map((video, index) => (
{reviews.map((review, index) => (
<div
key={video.id}
onClick={() => onVideoClick(review.video)}
key={review.id}
className={`relative aspect-video bg-black transition-transform duration-300 h-full xl:w-auto flex items-center justify-center min-w-[100vw] xl:min-w-0`}
style={{
transform: `translateX(-${
@@ -132,8 +140,8 @@ function Reviews() {
}}
>
<img
src={isEntered ? video.poster : undefined}
alt={video.desc}
src={isEntered ? review.poster : undefined}
alt={review.desc}
ref={imageRefs[index]}
className="aspect-video object-cover w-full h-full select-none pointer-events-none"
/>
+20
View File
@@ -0,0 +1,20 @@
const CrossIcon = () => {
return (
<svg
xmlns="http://www.w3.org/2000/svg"
width="20"
height="20"
fill="none"
viewBox="0 0 20 20"
>
<path
fill="#fff"
fillRule="evenodd"
d="M4.844 4.844a.625.625 0 01.884 0L10 9.116l4.273-4.272a.625.625 0 11.883.884L10.884 10l4.272 4.272a.625.625 0 01-.884.884L10 10.884l-4.272 4.272a.625.625 0 11-.884-.884L9.116 10 4.844 5.728a.625.625 0 010-.884z"
clipRule="evenodd"
></path>
</svg>
);
};
export default CrossIcon;
+47
View File
@@ -0,0 +1,47 @@
import CrossIcon from "@components/icons/CrossIcon";
import useModalStore from "@stores/useModalStore";
interface VideoModalProps {
link: string;
}
const VideoModal = ({ link }: VideoModalProps) => {
const { setModal } = useModalStore();
const handleOnCloseClick = () => {
setModal(null);
};
return (
<div className="w-screen h-screen absolute top-0 left-0 overflow-hidden flex justify-center items-center">
<div className="aspect-video w-full flex items-center justify-center">
<div
className="p-4 rounded-full border border-[#3D425C] absolute top-4 right-4 cursor-pointer"
onClick={handleOnCloseClick}
>
<CrossIcon />
</div>
<iframe
className="h-full aspect-video"
// src="https://youtu.be/j-7wAmdZ1rE"
// src={`${link}`}
src="https://www.youtube.com/embed/lAWF91CPOdY"
// title="Инструмент продаж graff.estate для проекта LIFE RESIDENCE: новый подход к презентации недвижимости"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerPolicy="strict-origin-when-cross-origin"
allowFullScreen
></iframe>
{/* <iframe
width="1280"
height="720"
src="https://www.youtube.com/embed/lAWF91CPOdY"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
referrerPolicy="strict-origin-when-cross-origin"
allowFullScreen
></iframe> */}
</div>
</div>
);
};
export default VideoModal;
+3 -3
View File
@@ -8,7 +8,7 @@ export const reviews: IReview[] = [
position: "Коммерческий директор авторского квартала «Машаров»",
desc: "Эффективность инструмента была подтверждена буквально в первый день после его внедрения. Например, один из клиентов, посетив офис и увидев свою будущую квартиру с помощью интерактивной панели, сразу решил купить недвижимость в этом проекте, отказавшись от других вариантов",
poster: "/images/reviews/1.jpg",
video: "",
video: "https://www.youtube.com/embed/lAWF91CPOdY",
},
{
id: "2",
@@ -17,7 +17,7 @@ export const reviews: IReview[] = [
position: "Ведущий менеджер компании «ЭНКО»",
desc: "Клиенты особенно ценят возможность легко выбрать квартиру с помощью 3D-модель жилого комплекса. Так же инструмент продаж позволяет клиенту увидеть расположение дома, в какое время свет будет попадать в окна, даже зайти в лифт и холл, а также оценить инфраструктуру района и «прочувствовать» его, прогулявшись по двору",
poster: "/images/reviews/2.jpg",
video: "",
video: "https://www.youtube.com/embed/lAWF91CPOdY",
},
{
id: "3",
@@ -26,6 +26,6 @@ export const reviews: IReview[] = [
position: "Ведущий специалист отдела продаж",
desc: "Одним из преимуществ инструмента является возможность посмотреть 3D-модель квартиры с готовым дизайнерским ремонтом и оценить видовые характеристиками, изменяя время суток (день или ночь). Это важно для клиента, так как позволяет реалистично представить, как будет выглядеть будущее жилье.",
poster: "/images/reviews/3.jpg",
video: "",
video: "https://www.youtube.com/embed/-fp1sWzLWyg",
},
];