NPSWidget
npswidget-1779379671575.tsx
'use client'
import { useState } from 'react'
const REASONS: Record<string, string[]> = {
low: ['Too expensive', 'Hard to find components', 'Quality issues', 'Missing components', 'Poor documentation'],
mid: ['Good but missing features', 'Would recommend with caveats', 'Price could be better', 'More components needed'],
high: ['Amazing quality', 'MCP is incredible', 'Saves hours of work', 'Best UI library I found', 'Recommend to everyone'],
}
export default function NPSWidget() {
const [score, setScore] = useState<number | null>(null)
const [reason, setReason] = useState<string | null>(null)
const [submitted, setSubmitted] = useState(false)
const bucket = score === null ? null : score <= 6 ? 'low' : score <= 8 ? 'mid' : 'high'
const label = bucket === 'high' ? 'Promoter ๐' : bucket === 'mid' ? 'Passive ๐' : 'Detractor ๐'
const labelColor = bucket === 'high' ? '#22c55e' : bucket === 'mid' ? '#f59e0b' : '#ef4444'
if (submitted) return (
<div style={{ padding: 40, background: '#0A0A0A', display: 'flex', alignItems: 'center', justifyContent: 'center', minHeight: 280 }}>
<div style={{ textAlign: 'center' }}>
<div style={{ fontSize: 48, marginBottom: 16 }}>{bucket === 'high' ? '๐' : bucket === 'mid' ? '๐' : '๐ช'}</div>
<div style={{ color: '#F5F5F0', fontSize: 18, fontWeight: 700, marginBottom: 8 }}>Thanks for your feedback!</div>
<div style={{ color: 'rgba(255,255,255,0.4)', fontSize: 13, marginBottom: 20 }}>Your score: <strong style={{ color: labelColor }}>{score}/10 โ {label}</strong></div>
<button onClick={() => { setScore(null); setReason(null); setSubmitted(false) }} style={{ background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.1)', color: '#F5F5F0', borderRadius: 8, padding: '8px 16px', cursor: 'pointer', fontSize: 13 }}>Submit another</button>
</div>
</div>
)
return (
<div style={{ background: '#0A0A0A', padding: 32, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 28, minHeight: 280 }}>
<div style={{ textAlign: 'center' }}>
<div style={{ color: '#F5F5F0', fontSize: 17, fontWeight: 700, marginBottom: 6 }}>How likely are you to recommend Empire UI?</div>
<div style={{ color: 'rgba(255,255,255,0.4)', fontSize: 13 }}>0 = Not at all ยท 10 = Extremely likely</div>
</div>
<div style={{ display: 'flex', gap: 6 }}>
{Array.from({ length: 11 }, (_, i) => {
const color = i <= 6 ? '#ef4444' : i <= 8 ? '#f59e0b' : '#22c55e'
return (
<button key={i} onClick={() => setScore(i)} style={{
width: 38, height: 38, borderRadius: 8, border: '1px solid',
borderColor: score === i ? color : 'rgba(255,255,255,0.1)',
background: score === i ? color + '20' : 'rgba(255,255,255,0.04)',
color: score === i ? color : 'rgba(255,255,255,0.5)', fontWeight: score === i ? 800 : 400,
cursor: 'pointer', fontSize: 14, transition: 'all 0.15s',
}}>{i}</button>
)
})}
</div>
{score !== null && (
<div style={{ width: '100%', maxWidth: 440, animation: 'fadeIn 0.3s ease' }}>
<div style={{ color: labelColor, fontSize: 13, fontWeight: 700, marginBottom: 12, textAlign: 'center' }}>{label}</div>
<div style={{ color: 'rgba(255,255,255,0.5)', fontSize: 13, marginBottom: 10 }}>What's the main reason for your score?</div>
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, marginBottom: 20 }}>
{(REASONS[bucket!] || []).map(r => (
<button key={r} onClick={() => setReason(r)} style={{ background: reason === r ? 'rgba(201,168,76,0.12)' : 'rgba(255,255,255,0.04)', border: '1px solid', borderColor: reason === r ? 'rgba(201,168,76,0.3)' : 'rgba(255,255,255,0.08)', color: reason === r ? '#C9A84C' : 'rgba(255,255,255,0.5)', borderRadius: 20, padding: '5px 12px', cursor: 'pointer', fontSize: 12 }}>{r}</button>
))}
</div>
<button onClick={() => setSubmitted(true)} style={{ width: '100%', background: '#C9A84C', color: '#0A0A0A', border: 'none', borderRadius: 10, padding: '12px', fontWeight: 700, cursor: 'pointer', fontSize: 14 }}>Submit feedback</button>
</div>
)}
<style>{`@keyframes fadeIn { from { opacity:0; transform:translateY(8px) } to { opacity:1; transform:translateY(0) } }`}</style>
</div>
)
}Component info
CategoryFeedback
Frameworkreact
TierFREE
Views0
Copies0
About
Net Promoter Score widget with 0-10 scale, follow-up reason selector, and response analytics