'use client'; import React, { useCallback, useEffect, useRef, useState } from 'react'; import Autoplay from 'embla-carousel-autoplay'; import useEmblaCarousel from 'embla-carousel-react'; import { Card } from '@documenso/ui/primitives/card'; import { Thumb } from './thumb'; type SlideType = { label: string; imageSrc: string; type: 'image' | 'video'; }; type CarouselPropType = { slides: SlideType[]; }; const SLIDES = [ { label: 'Signing Process', type: 'video', src: '/signing.mp4', }, { label: 'Templates/Fields', type: 'video', src: '/signing.mp4', }, { label: 'Zapier', type: 'video', src: '/signing.mp4', }, { label: 'Webhooks', type: 'video', src: '/signing.mp4', }, { label: 'API', type: 'video', src: '/signing.mp4', }, { label: 'Teams', type: 'video', src: '/signing.mp4', }, { label: 'Profile', type: 'video', src: '/signing.mp4', }, ]; export const Carousel = () => { const slides = SLIDES; const [_isPlaying, setIsPlaying] = useState(false); const [selectedIndex, setSelectedIndex] = useState(0); const [emblaRef, emblaApi] = useEmblaCarousel({ loop: true }, [ Autoplay({ playOnInit: true, delay: 5000 }), ]); const [emblaThumbsRef, emblaThumbsApi] = useEmblaCarousel( { loop: true, containScroll: 'keepSnaps', dragFree: true, }, [Autoplay({ playOnInit: true, delay: 5000 })], ); const onThumbClick = useCallback( (index: number) => { if (!emblaApi || !emblaThumbsApi) return; emblaApi.scrollTo(index); }, [emblaApi, emblaThumbsApi], ); const onSelect = useCallback(() => { if (!emblaApi || !emblaThumbsApi) return; setSelectedIndex(emblaApi.selectedScrollSnap()); emblaThumbsApi.scrollTo(emblaApi.selectedScrollSnap()); }, [emblaApi, emblaThumbsApi, setSelectedIndex]); const videoRefs = useRef<(HTMLVideoElement | null)[]>([]); useEffect(() => { const observer = new IntersectionObserver( (entries) => { entries.forEach((entry) => { if (entry.isIntersecting) { const video = entry.target as HTMLVideoElement; video .play() .catch((error) => console.log('Error attempting to play the video:', error)); } else { const video = entry.target as HTMLVideoElement; video.pause(); } }); }, { threshold: 0.5, }, ); videoRefs.current.forEach((video) => { if (video) { observer.observe(video); } }); return () => { observer.disconnect(); }; }, [slides]); useEffect(() => { if (!emblaApi) return; onSelect(); emblaApi.on('select', onSelect).on('reInit', onSelect); }, [emblaApi, onSelect]); useEffect(() => { const autoplay = emblaApi?.plugins()?.autoplay; if (!autoplay) return; setIsPlaying(autoplay.isPlaying()); emblaApi .on('autoplay:play', () => setIsPlaying(true)) .on('autoplay:stop', () => setIsPlaying(false)) .on('reInit', () => setIsPlaying(autoplay.isPlaying())); }, [emblaApi]); return ( <>
{slides.map((slide, index) => (
{slide.type === 'video' && ( )}
))}
{slides.map((slide, index) => ( onThumbClick(index)} selected={index === selectedIndex} index={index} label={slide.label} /> ))}
); };