Spaces:
Build error
Build error
| import { useState } from 'react'; | |
| import { Card, CardContent, CardHeader, CardTitle } from './ui/Card'; | |
| import { Button } from './ui/Button'; | |
| import { Shield, CheckCircle, XCircle, AlertTriangle } from 'lucide-react'; | |
| export default function BoardValidator() { | |
| const [technique, setTechnique] = useState({ | |
| name: 'learning_rate', | |
| value: '0.001', | |
| confidence: 0.85, | |
| }); | |
| const [review, setReview] = useState(null); | |
| const [loading, setLoading] = useState(false); | |
| const submitForReview = async () => { | |
| setLoading(true); | |
| try { | |
| const response = await fetch('/api/board/review', { | |
| method: 'POST', | |
| headers: { 'Content-Type': 'application/json' }, | |
| body: JSON.stringify({ technique }), | |
| }); | |
| const data = await response.json(); | |
| setReview(data); | |
| } catch (error) { | |
| console.error('Review failed:', error); | |
| } finally { | |
| setLoading(false); | |
| } | |
| }; | |
| const getVerdictIcon = (verdict) => { | |
| switch (verdict) { | |
| case 'APPROVE': | |
| return <CheckCircle className="w-5 h-5 text-green-500" />; | |
| case 'REJECT': | |
| return <XCircle className="w-5 h-5 text-red-500" />; | |
| default: | |
| return <AlertTriangle className="w-5 h-5 text-yellow-500" />; | |
| } | |
| }; | |
| return ( | |
| <div className="space-y-6"> | |
| <h2 className="text-3xl font-bold text-gray-800">Board Validator</h2> | |
| <Card> | |
| <CardHeader> | |
| <CardTitle className="flex items-center"> | |
| <Shield className="w-6 h-6 mr-2" /> | |
| 5-Entity Board Review | |
| </CardTitle> | |
| </CardHeader> | |
| <CardContent> | |
| <div className="mb-6"> | |
| <label className="block text-sm font-medium mb-2">Technique Name</label> | |
| <input | |
| type="text" | |
| value={technique.name} | |
| onChange={(e) => setTechnique({ ...technique, name: e.target.value })} | |
| className="input-field w-full" | |
| /> | |
| </div> | |
| <div className="mb-6"> | |
| <label className="block text-sm font-medium mb-2">Value</label> | |
| <input | |
| type="text" | |
| value={technique.value} | |
| onChange={(e) => setTechnique({ ...technique, value: e.target.value })} | |
| className="input-field w-full" | |
| /> | |
| </div> | |
| <div className="mb-6"> | |
| <label className="block text-sm font-medium mb-2">Confidence: {technique.confidence}</label> | |
| <input | |
| type="range" | |
| min="0" | |
| max="1" | |
| step="0.05" | |
| value={technique.confidence} | |
| onChange={(e) => setTechnique({ ...technique, confidence: parseFloat(e.target.value) })} | |
| className="w-full" | |
| /> | |
| </div> | |
| <Button onClick={submitForReview} disabled={loading} className="w-full"> | |
| {loading ? 'Reviewing...' : 'Submit for Board Review'} | |
| </Button> | |
| </CardContent> | |
| </Card> | |
| {review && ( | |
| <Card> | |
| <CardHeader> | |
| <CardTitle>Review Results</CardTitle> | |
| </CardHeader> | |
| <CardContent> | |
| <div className="mb-4"> | |
| <div className="flex items-center justify-between mb-2"> | |
| <span className="text-lg font-semibold">Final Score: {review.finalScore.toFixed(2)}</span> | |
| <span className={`px-3 py-1 rounded-full text-sm font-bold ${ | |
| review.finalVerdict === 'APPROVED' | |
| ? 'bg-green-100 text-green-800' | |
| : review.finalVerdict === 'REJECTED' | |
| ? 'bg-red-100 text-red-800' | |
| : 'bg-yellow-100 text-yellow-800' | |
| }`}> | |
| {review.finalVerdict} | |
| </span> | |
| </div> | |
| <div className="text-sm text-gray-600"> | |
| Approvals: {review.approvals} / {review.total} | |
| </div> | |
| </div> | |
| <div className="space-y-4"> | |
| {review.reviews.map((r) => ( | |
| <div key={r.entity} className="border rounded-lg p-4"> | |
| <div className="flex items-center justify-between mb-2"> | |
| <div className="flex items-center"> | |
| {getVerdictIcon(r.verdict)} | |
| <span className="ml-2 font-semibold">{r.entity}</span> | |
| </div> | |
| <span className="text-sm text-gray-600">Score: {r.score.toFixed(2)}</span> | |
| </div> | |
| <p className="text-sm text-gray-700">{r.reasoning}</p> | |
| </div> | |
| ))} | |
| </div> | |
| </CardContent> | |
| </Card> | |
| )} | |
| </div> | |
| ); | |
| } |