import React, { useState, useEffect, useRef } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; type Testimonial = { image: string; audio: string; text: string; name: string; jobtitle: string; }; type TestimonialsProps = { testimonials: Testimonial[]; }; const TypewriterTestimonial: React.FC = ({ testimonials }) => { const [hoveredIndex, setHoveredIndex] = useState(null); const [audioPlayer, setAudioPlayer] = useState(null); const [hasBeenHovered, setHasBeenHovered] = useState(new Array(testimonials.length).fill(false)); const [typedText, setTypedText] = useState(''); const typewriterRef = useRef(null); const currentTextRef = useRef(''); const handleMouseEnter = (index: number) => { setHoveredIndex(index); const audio = new Audio(`/audio/${testimonials[index].audio}`); audio.play(); setAudioPlayer(audio); setHasBeenHovered(prev => { const updated = [...prev]; updated[index] = true; return updated; }); startTypewriter(testimonials[index].text); }; const handleMouseLeave = () => { if (audioPlayer) { audioPlayer.pause(); audioPlayer.currentTime = 0; } setHoveredIndex(null); setAudioPlayer(null); stopTypewriter(); }; const startTypewriter = (text: string) => { let i = 0; setTypedText(''); currentTextRef.current = text; const type = () => { if (i <= text.length) { setTypedText(text.slice(0, i)); i++; typewriterRef.current = setTimeout(type, 50); } }; type(); }; const stopTypewriter = () => { if (typewriterRef.current) { clearTimeout(typewriterRef.current); } setTypedText(''); currentTextRef.current = ''; }; useEffect(() => { return () => { if (typewriterRef.current) { clearTimeout(typewriterRef.current); } }; }, []); return (
{testimonials.map((testimonial, index) => ( handleMouseEnter(index)} onMouseLeave={handleMouseLeave} whileHover={{ scale: 1.05 }} whileTap={{ scale: 0.95 }} > {hoveredIndex === index && (
{typedText} |

{testimonial.name}

{testimonial.jobtitle}

)}
))}
); }; export default TypewriterTestimonial;