'use client'; import Image from 'next/image'; import React, { useState, useEffect } from 'react'; import { RiTwitterXLine } from 'react-icons/ri'; import { motion, Variants } from 'framer-motion'; type Mode = 'light' | 'dark'; interface Testimonial { image?: string; name?: string; jobtitle?: string; text?: string; audio?: string; social?: string; } interface VoiceTestimonialProps { mode: Mode; testimonials: Testimonial[]; } const WaveVariants = (): Variants[] => { const waveVariants: Variants[] = []; for (let i = 0; i < 30; i++) { waveVariants.push({ initial: { scaleY: 1.5, transition: { duration: 0.5, }, }, animate: { scaleY: [1, Math.random() * 1.2 + 1, 1], transition: { duration: Math.random() * 0.5 + 0.5, repeat: Infinity, ease: 'easeInOut', delay: Math.random() * 0.5, }, }, }); } return waveVariants; }; const waveVariants = WaveVariants(); const VoiceTestimonial: React.FC = ({ mode, testimonials }) => { const [currentPlayingIndex, setCurrentPlayingIndex] = useState(null); const [audioElements, setAudioElements] = useState<(HTMLAudioElement | null)[]>([]); const [showAll, setShowAll] = useState(false); useEffect(() => { const elements: (HTMLAudioElement | null)[] = []; testimonials.forEach((testimonial) => { if (testimonial.audio) { const audio = new Audio(`/audio/${testimonial.audio}`); audio.addEventListener('ended', handleAudioEnded); elements.push(audio); } else { elements.push(null); } }); setAudioElements(elements); return () => { elements.forEach((audio) => { if (audio) { audio.pause(); audio.removeEventListener('ended', handleAudioEnded); } }); }; }, [testimonials]); const handlePlay = (index: number) => { if (currentPlayingIndex !== null && currentPlayingIndex !== index) { stopAudio(currentPlayingIndex); } const audio = audioElements[index]; if (audio) { audio.play().catch((error) => console.error('Audio playback error:', error)); setCurrentPlayingIndex(index); } }; const stopAudio = (index: number) => { const audio = audioElements[index]; if (audio) { audio.pause(); audio.currentTime = 0; setCurrentPlayingIndex(null); } }; const handlePause = (index: number) => { stopAudio(index); }; const handleAudioEnded = () => { setCurrentPlayingIndex(null); }; const handleLoadMore = () => { setShowAll(true); }; const openInNewTab = (url: string) => { const win = window.open(url, '_blank'); if (win) { win.focus(); } }; const shouldShowLoadMore = testimonials.length > 6; // Here you can set the number of testimonials you want to display at a time return (
Read what people are saying Dummy feedback from virtual customers
using our component library.
{shouldShowLoadMore && !showAll &&
} {testimonials.map((testimonial, index) => (
= 6 ? 'testimonial-partially-visible' : '' }`}>
openInNewTab(testimonial.social || '')} className="absolute top-5 right-5">
profile
{testimonial.name} {testimonial.jobtitle}
{testimonial.text}
{currentPlayingIndex !== index ? ( handlePlay(index)}> ) : ( handlePause(index)}> )}
{waveVariants.map((variant, i) => ( ))}
))}
{shouldShowLoadMore && !showAll && (
)}
); }; export default VoiceTestimonial;