OwnGPT.v2 / client /src /components /FeedbackModal.jsx
parthib07's picture
Upload 199 files
212c959 verified
import { useState } from 'react'
const STAR_HINTS = ['', 'Poor 😞', 'Fair 😐', 'Good πŸ™‚', 'Great 😊', 'Excellent 🀩']
export default function FeedbackModal({ onSubmit, onClose }) {
const [rating, setRating] = useState(0)
const [hover, setHover] = useState(0)
const [cat, setCat] = useState('general')
const [text, setText] = useState('')
const [err, setErr] = useState('')
const [done, setDone] = useState(false)
const [loading, setLoading] = useState(false)
const handleSubmit = async () => {
if (!rating) return setErr('Please select a star rating.')
if (!text.trim()) return setErr('Please write a short message.')
setLoading(true)
try {
await onSubmit({ rating, category: cat, message: text.trim() })
setDone(true)
} catch (e) {
setErr(e.message || 'Failed to submit feedback')
} finally {
setLoading(false)
}
}
if (done) {
return (
<div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
<div className="modal-card" style={{ maxWidth: 440 }}>
<div className="modal-header">
<span className="modal-title">Send Feedback</span>
<button className="modal-close" onClick={onClose}>
<svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<div className="feedback-success">
<div className="feedback-success-icon">πŸŽ‰</div>
<div className="feedback-success-title">Thank you!</div>
<div className="feedback-success-sub">Your feedback has been saved. We read every single one.</div>
<button className="btn btn-primary" onClick={onClose} style={{ marginTop: 10 }}>Close</button>
</div>
</div>
</div>
)
}
return (
<div className="modal-overlay" onClick={e => e.target === e.currentTarget && onClose()}>
<div className="modal-card" style={{ maxWidth: 460 }}>
<div className="modal-header">
<span className="modal-title">Send Feedback</span>
<button className="modal-close" onClick={onClose}>
<svg viewBox="0 0 24 24"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button>
</div>
<div className="modal-body">
<div className="field-label">How would you rate OwnGPT?</div>
<div className="star-row">
{[1,2,3,4,5].map(v => (
<button
key={v}
className={`star-btn ${rating >= v ? 'lit' : ''} ${hover >= v ? 'hover' : ''}`}
onMouseEnter={() => setHover(v)}
onMouseLeave={() => setHover(0)}
onClick={() => setRating(v)}
>
β˜…
</button>
))}
</div>
<div className="star-hint">{STAR_HINTS[hover || rating]}</div>
<div className="field-label" style={{ marginTop: 16 }}>Category</div>
<div className="fcat-row">
<button className={`fcat-btn ${cat === 'general' ? 'active' : ''}`} onClick={() => setCat('general')}>πŸ’¬ General</button>
<button className={`fcat-btn ${cat === 'bug' ? 'active' : ''}`} onClick={() => setCat('bug')}>πŸ› Bug</button>
<button className={`fcat-btn ${cat === 'feature' ? 'active' : ''}`} onClick={() => setCat('feature')}>✨ Feature</button>
<button className={`fcat-btn ${cat === 'other' ? 'active' : ''}`} onClick={() => setCat('other')}>πŸ“Œ Other</button>
</div>
<div className="field-label">Your message</div>
<textarea
className="field-textarea"
placeholder="Tell us what you think..."
value={text}
onChange={e => setText(e.target.value)}
maxLength={2000}
/>
<div className="char-count">{text.length} / 2000</div>
{err && <div className="field-error" style={{ marginTop: 8 }}>{err}</div>}
</div>
<div className="modal-footer">
<button className="btn" onClick={onClose}>Cancel</button>
<button className="btn btn-primary" onClick={handleSubmit} disabled={loading}>
{loading ? 'Sending...' : 'Submit Feedback'}
</button>
</div>
</div>
</div>
)
}