Files
reui-blocks/blocks/projects15e.tsx
T

198 lines
5.6 KiB
TypeScript

"use client";
import { AudioLines } from "lucide-react";
import type React from "react";
import { useEffect, useRef, useState } from "react";
import {
Carousel,
CarouselContent,
CarouselItem,
CarouselNext,
CarouselPrevious,
} from "@/components/ui/carousel";
import { cn } from "@/lib/utils";
interface VideoSectionProps {
videoSrc: string;
thumbnailSrc: string;
studioName: string;
projectTitle: string;
}
const VideoSection: React.FC<VideoSectionProps> = ({
videoSrc,
thumbnailSrc,
studioName,
projectTitle,
}) => {
const videoRef = useRef<HTMLVideoElement>(null);
const [isHovered, setIsHovered] = useState(false);
useEffect(() => {
if (videoRef.current) {
videoRef.current.pause();
videoRef.current.currentTime = 0;
}
}, []);
useEffect(() => {
if (videoRef.current) {
if (isHovered) {
videoRef.current.play();
} else {
videoRef.current.pause();
videoRef.current.currentTime = 0;
}
}
}, [isHovered]);
const handleMouseEnter = () => {
setIsHovered(true);
};
const handleMouseLeave = () => {
setIsHovered(false);
};
return (
<div
className="group relative h-[60vh] w-full cursor-pointer overflow-hidden md:h-[70vh]"
onMouseEnter={handleMouseEnter}
onMouseLeave={handleMouseLeave}
>
{/* Thumbnail Image */}
<img
src={thumbnailSrc}
alt={projectTitle}
className={`absolute inset-0 h-full w-full object-cover transition-opacity duration-700 ease-in-out ${isHovered ? "opacity-0" : "opacity-100"
}`}
/>
{/* Video */}
<video
ref={videoRef}
className={`absolute inset-0 h-full w-full object-cover transition-opacity duration-700 ease-in-out ${isHovered ? "opacity-100" : "opacity-0"
}`}
muted
loop
playsInline
preload="metadata"
>
<source src={videoSrc} type="video/mp4" />
مرورگر شما از پخش ویدیو پشتیبانی نمی‌کند.
</video>
<div className="absolute inset-0 bg-black/30 transition-all duration-500 group-hover:bg-black/20" />
<div className="absolute inset-0 bottom-12 flex items-end">
<div className="px-6 text-start text-white sm:px-8 md:px-12 lg:px-16 xl:px-20">
<p className="mb-2 text-xs font-medium tracking-wider opacity-80 sm:mb-3 sm:text-sm md:mb-4 md:text-base">
{studioName}
</p>
<h2 className="max-w-md text-2xl font-light tracking-tight sm:text-3xl md:text-4xl lg:max-w-lg">
{projectTitle}
</h2>
</div>
</div>
</div>
);
};
const videoSections = [
{
thumbnailSrc:
"/block-media/shadcnblocks/block/photos/jeremy-bishop-iEjCQtcsVPY-unsplash.jpg",
videoSrc:
"/block-media/shadcnblocks/block/3571264-hd_1280_720_30fps.mp4",
studioName: "مریدیان لبز",
projectTitle: "تعامل‌های اثیری",
},
{
thumbnailSrc:
"/block-media/shadcnblocks/block/photos/carles-rabada-f7UprkNqi08-unsplash.jpg",
videoSrc:
"/block-media/shadcnblocks/block/1448735-hd_1366_720_24fps.mp4",
studioName: "زنیث دیجیتال",
projectTitle: "نکسوس استودیو",
},
{
thumbnailSrc:
"/block-media/shadcnblocks/block/photos/sam-wermut-FiUuNWxnb3k-unsplash.jpg",
videoSrc:
"/block-media/shadcnblocks/block/19348567-hd_1280_720_25fps.mp4",
studioName: "پریزم لبز",
projectTitle: "مرزهای نو",
},
{
thumbnailSrc:
"/block-media/shadcnblocks/block/photos/ines-alvarez-fdez-VjRc6HDXJ5s-unsplash.jpg",
videoSrc:
"/block-media/shadcnblocks/block/9882072-hd_1280_720_30fps.mp4",
studioName: "سمفونی تعامل",
projectTitle: "تعامل‌های روان",
},
];
interface Projects15eProps {
className?: string;
}
const Projects15e = ({ className }: Projects15eProps) => {
return (
<section dir="rtl" lang="fa" className={cn("w-full bg-background", className)}>
{/* Header Section */}
<div className="container py-16">
<div className="text-start text-foreground">
<h1 className="mb-4 text-4xl font-bold tracking-tight sm:text-5xl md:text-6xl lg:mb-8 lg:text-8xl">
کاوش در پروژه‌های ما
</h1>
<div className="flex items-center">
<p className="me-4 text-sm font-medium tracking-wider opacity-80">
کارهای ما
</p>
<div className="opacity-60">
<AudioLines className="h-6 w-6" />
</div>
</div>
</div>
</div>
{/* Full Width Carousel */}
<div className="w-full">
<Carousel
dir="rtl"
opts={{
align: "start",
loop: true,
direction: "rtl",
}}
className="w-full"
>
<CarouselContent className="-ms-2 md:-ms-4">
{videoSections.map((section, index) => (
<CarouselItem
key={index}
className="ps-2 md:basis-4/5 md:ps-4 lg:basis-3/4 xl:basis-2/3"
>
<VideoSection
videoSrc={section.videoSrc}
thumbnailSrc={section.thumbnailSrc}
studioName={section.studioName}
projectTitle={section.projectTitle}
/>
</CarouselItem>
))}
</CarouselContent>
<CarouselPrevious className="start-4 md:start-8" />
<CarouselNext className="end-4 md:end-8" />
</Carousel>
</div>
</section>
);
};
export { Projects15e };