TestimonialCarousel
testimonialcarousel-1779378817337.tsx
'use client'
import { useState, useEffect } from 'react'
const TESTIMONIALS = [
{ name: 'Sarah Chen', role: 'Lead Designer @ Vercel', avatar: 'SC', rating: 5, text: 'Empire UI completely transformed our design workflow. The components are production-ready and the code quality is exceptional. We shipped our dashboard 3x faster.' },
{ name: 'Marcus Williams', role: 'CTO @ Linear', avatar: 'MW', rating: 5, text: 'The MCP integration is brilliant. I can ask Claude for a component and it returns working code instantly. This is the future of UI development.' },
{ name: 'Priya Patel', role: 'Senior Engineer @ Stripe', avatar: 'PP', rating: 5, text: 'I was skeptical about AI-generated UI at first, but Empire UI proved me wrong. Every component is thoughtfully designed and handles edge cases properly.' },
{ name: 'Alex Kowalski', role: 'Founder @ Lemon Squeezy', avatar: 'AK', rating: 5, text: 'Saved us weeks of frontend work. The dark-mode first approach is perfect for our SaaS product. Highly recommend to any team that values speed and quality.' },
]
export default function TestimonialCarousel() {
const [idx, setIdx] = useState(0)
const [prev, setPrev] = useState(0)
const [dir, setDir] = useState(1)
useEffect(() => {
const t = setInterval(() => go(1), 4000)
return () => clearInterval(t)
}, [idx])
function go(d: number) {
setPrev(idx)
setDir(d)
setIdx(i => (i + d + TESTIMONIALS.length) % TESTIMONIALS.length)
}
const t = TESTIMONIALS[idx]
const colors = ['#C9A84C', '#6366f1', '#22c55e', '#f97316']
return (
<div style={{ background: '#0A0A0A', padding: 40, display: 'flex', flexDirection: 'column', alignItems: 'center', minHeight: 320 }}>
<div style={{ maxWidth: 560, width: '100%' }}>
<div style={{ display: 'flex', justifyContent: 'center', marginBottom: 32, gap: 4 }}>
{'★★★★★'.split('').map((s, i) => <span key={i} style={{ color: '#C9A84C', fontSize: 18 }}>★</span>)}
</div>
<div key={idx} style={{ textAlign: 'center', animation: 'fadeIn 0.4s ease' }}>
<p style={{ color: '#F5F5F0', fontSize: 18, lineHeight: 1.7, fontStyle: 'italic', marginBottom: 32 }}>
"{t.text}"
</p>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 14 }}>
<div style={{ width: 44, height: 44, borderRadius: '50%', background: colors[idx], display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#0A0A0A', fontWeight: 800, fontSize: 14 }}>
{t.avatar}
</div>
<div style={{ textAlign: 'left' }}>
<div style={{ color: '#F5F5F0', fontWeight: 700, fontSize: 14 }}>{t.name}</div>
<div style={{ color: 'rgba(255,255,255,0.45)', fontSize: 12 }}>{t.role}</div>
</div>
</div>
</div>
<div style={{ display: 'flex', justifyContent: 'center', gap: 8, marginTop: 32, alignItems: 'center' }}>
<button onClick={() => go(-1)} style={{ background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.1)', color: '#F5F5F0', borderRadius: '50%', width: 32, height: 32, cursor: 'pointer', fontSize: 14 }}>←</button>
{TESTIMONIALS.map((_, i) => (
<button key={i} onClick={() => { setDir(i > idx ? 1 : -1); setIdx(i) }}
style={{ width: i === idx ? 24 : 8, height: 8, borderRadius: 4, border: 'none', cursor: 'pointer', background: i === idx ? '#C9A84C' : 'rgba(255,255,255,0.2)', transition: 'all 0.3s' }} />
))}
<button onClick={() => go(1)} style={{ background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.1)', color: '#F5F5F0', borderRadius: '50%', width: 32, height: 32, cursor: 'pointer', fontSize: 14 }}>→</button>
</div>
</div>
<style>{`@keyframes fadeIn { from { opacity: 0; transform: translateY(8px) } to { opacity: 1; transform: translateY(0) } }`}</style>
</div>
)
}Component info
CategoryTestimonials
Frameworkreact
TierFREE
Views0
Copies0
About
Auto-playing testimonial carousel with star ratings, avatars, and slide indicators