import { useState, useEffect } from 'react' export default function FeedbackForm() { const [candidates, setCandidates] = useState([]) const [clients, setClients] = useState([]) const [stats, setStats] = useState(null) const [loading, setLoading] = useState(true) const [submitting, setSubmitting] = useState(false) const [error, setError] = useState('') const [success, setSuccess] = useState('') // Form states const [selectedCandidateId, setSelectedCandidateId] = useState('') const [outcome, setOutcome] = useState('accepted') const [primaryReason, setPrimaryReason] = useState('communication_soft_skills') const [clientNotes, setClientNotes] = useState('') useEffect(() => { loadData() }, []) const loadData = async () => { try { const [candRes, clientRes, statsRes] = await Promise.all([ fetch('/api/candidates'), fetch('/api/clients'), fetch('/api/stats'), ]) const cands = await candRes.json() const clis = await clientRes.json() const st = await statsRes.json() setCandidates(cands) setClients(clis) setStats(st) // Set default selected candidate as the first one that has scores but no feedback const pendingFeedback = cands.filter(c => c.score && !c.feedback) if (pendingFeedback.length > 0) { setSelectedCandidateId(pendingFeedback[0].id) } else { setSelectedCandidateId('') } } catch (err) { console.error(err) setError('Failed to load feedback page data.') } finally { setLoading(false) } } const handleSubmit = async (e) => { e.preventDefault() if (!selectedCandidateId) { setError('Please select a candidate.') return } setSubmitting(true) setError('') setSuccess('') try { const res = await fetch(`/api/candidates/${selectedCandidateId}/feedback`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ outcome, primary_reason: primaryReason, client_notes: clientNotes, }), }) if (!res.ok) { const errData = await res.json() throw new Error(errData.detail || 'Failed to submit feedback.') } setSuccess('Feedback logged successfully!') setClientNotes('') // Reload stats and candidate list await loadData() } catch (err) { console.error(err) setError(err.message || 'Error occurred while logging feedback.') } finally { setSubmitting(false) } } const getClientName = (clientId) => { const client = clients.find(c => c.id === clientId) return client ? client.name : 'Unknown Client' } const getReasonLabel = (reason) => { const mapping = { communication_soft_skills: '💬 Communication & Soft Skills', technical_capability: '💻 Technical Capability', alignment_cultural_vibe: '🤝 Alignment / Cultural Vibe', candidate_declined: '❌ Candidate Declined', } return mapping[reason] || reason } if (loading) { return
All scored candidates have feedback logged. Great job! Go score more candidates to log outcomes.
) : ( )}No candidates registered yet.
) : (| Candidate Name | Client | Vetting Match | Status | Feedback Notes |
|---|---|---|---|---|
| {c.name} | {getClientName(c.client_id)} | {c.score ? ( {Math.round(c.score.overall_match * 100)}% ) : ( Unscored )} | {c.feedback ? ( {c.feedback.outcome === 'accepted' ? '🟢 Accepted' : '🔴 Rejected'} ) : c.score ? ( Scored, Pending Feedback ) : ( Pending Evaluation )} |
{c.feedback ? (
{getReasonLabel(c.feedback.primary_reason)}
{c.feedback.client_notes && (
"{c.feedback.client_notes}"
)}
|