Spaces:
Running
Running
import React, { useState, useEffect } from 'react'; | |
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, Legend } from 'recharts'; | |
import { Upload, RefreshCw, Database, FileText, Settings } from 'lucide-react'; | |
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; | |
import { Alert, AlertDescription } from '@/components/ui/alert'; | |
import { Button } from '@/components/ui/button'; | |
const AdminDashboard = () => { | |
// Sample data for learning chart | |
const [learningData, setLearningData] = useState([]); | |
const [isUpdating, setIsUpdating] = useState(false); | |
const [chatHistory, setChatHistory] = useState([]); | |
const [message, setMessage] = useState(''); | |
const [stats, setStats] = useState({}); | |
const [plotData, setPlotData] = useState([]); | |
const handleKnowledgeUpdate = () => { | |
setIsUpdating(true); | |
// Simulate update | |
setTimeout(() => setIsUpdating(false), 2000); | |
}; | |
const handleChatSubmit = async () => { | |
const response = await fetch('http://localhost:7860/api/chat', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json' | |
}, | |
body: JSON.stringify({ message, history: chatHistory }) | |
}); | |
const data = await response.json(); | |
setChatHistory(data.history); | |
setMessage(''); | |
}; | |
const handleFileUpload = async (file) => { | |
const formData = new FormData(); | |
formData.append('file', file); | |
const response = await fetch('http://localhost:7860/api/upload', { | |
method: 'POST', | |
body: formData | |
}); | |
const data = await response.json(); | |
alert(data.message); | |
}; | |
const handleShowStats = async () => { | |
const response = await fetch('http://localhost:7860/api/stats'); | |
const data = await response.json(); | |
setStats(data.stats); | |
setPlotData(data.plot); | |
}; | |
useEffect(() => { | |
// Fetch initial learning data | |
const fetchLearningData = async () => { | |
const response = await fetch('http://localhost:7860/api/learning_data'); | |
const data = await response.json(); | |
setLearningData(data); | |
}; | |
fetchLearningData(); | |
}, []); | |
return ( | |
<div className="p-6 max-w-7xl mx-auto space-y-6"> | |
{/* Header */} | |
<div className="flex justify-between items-center"> | |
<h1 className="text-3xl font-bold">Admin Dashboard</h1> | |
<Button | |
onClick={handleKnowledgeUpdate} | |
className="bg-blue-600 hover:bg-blue-700" | |
disabled={isUpdating} | |
> | |
<RefreshCw className={`w-4 h-4 mr-2 ${isUpdating ? 'animate-spin' : ''}`} /> | |
Update Knowledge Base | |
</Button> | |
</div> | |
{/* Statistics Cards */} | |
<div className="grid grid-cols-1 md:grid-cols-3 gap-4"> | |
<Card> | |
<CardContent className="pt-6"> | |
<div className="text-2xl font-bold">{stats.average_response_time || '89%'}</div> | |
<div className="text-sm text-gray-500">Current Learning Rate</div> | |
</CardContent> | |
</Card> | |
<Card> | |
<CardContent className="pt-6"> | |
<div className="text-2xl font-bold">{stats.total_interactions || '1,234'}</div> | |
<div className="text-sm text-gray-500">Number of Answered Questions</div> | |
</CardContent> | |
</Card> | |
<Card> | |
<CardContent className="pt-6"> | |
<div className="text-2xl font-bold">{stats.user_satisfaction || '95%'}</div> | |
<div className="text-sm text-gray-500">User Satisfaction</div> | |
</CardContent> | |
</Card> | |
</div> | |
{/* Learning Chart */} | |
<Card> | |
<CardHeader> | |
<CardTitle>Learning Rate Trend</CardTitle> | |
</CardHeader> | |
<CardContent> | |
<div className="h-[400px] w-full"> | |
<LineChart | |
width={800} | |
height={400} | |
data={plotData} | |
margin={{ top: 5, right: 30, left: 20, bottom: 5 }} | |
> | |
<CartesianGrid strokeDasharray="3 3" /> | |
<XAxis dataKey="date" /> | |
<YAxis /> | |
<Tooltip /> | |
<Legend /> | |
<Line | |
type="monotone" | |
dataKey="rate" | |
stroke="#2563eb" | |
name="Learning Rate" | |
strokeWidth={2} | |
/> | |
</LineChart> | |
</div> | |
</CardContent> | |
</Card> | |
{/* Operation Buttons */} | |
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<Button className="h-24 text-lg justify-start p-6" variant="outline"> | |
<FileText className="w-6 h-6 mr-4" /> | |
Manage Files | |
</Button> | |
<Button className="h-24 text-lg justify-start p-6" variant="outline"> | |
<Settings className="w-6 h-6 mr-4" /> | |
Learning Settings | |
</Button> | |
</div> | |
{/* Alerts and Announcements */} | |
<Alert> | |
<AlertDescription> | |
Last knowledge base update: Yesterday at 15:30 | |
</AlertDescription> | |
</Alert> | |
{/* Chat */} | |
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<Card> | |
<CardHeader> | |
<CardTitle>Chat</CardTitle> | |
</CardHeader> | |
<CardContent> | |
<div className="h-[400px] w-full overflow-y-auto"> | |
{chatHistory.map((msg, index) => ( | |
<div key={index} className="p-2 border-b"> | |
{msg} | |
</div> | |
))} | |
</div> | |
<div className="flex mt-4"> | |
<input | |
type="text" | |
className="flex-grow p-2 border rounded-l" | |
value={message} | |
onChange={(e) => setMessage(e.target.value)} | |
onKeyPress={(e) => e.key === 'Enter' && handleChatSubmit()} | |
/> | |
<button | |
className="p-2 bg-blue-600 text-white rounded-r" | |
onClick={handleChatSubmit} | |
> | |
Send | |
</button> | |
</div> | |
</CardContent> | |
</Card> | |
</div> | |
{/* Upload Documents */} | |
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<Card> | |
<CardHeader> | |
<CardTitle>Upload Documents</CardTitle> | |
</CardHeader> | |
<CardContent> | |
<input type="file" onChange={(e) => handleFileUpload(e.target.files[0])} /> | |
</CardContent> | |
</Card> | |
</div> | |
{/* Statistics */} | |
<div className="grid grid-cols-1 md:grid-cols-2 gap-4"> | |
<Card> | |
<CardHeader> | |
<CardTitle>Statistics</CardTitle> | |
</CardHeader> | |
<CardContent> | |
<button className="p-2 bg-blue-600 text-white rounded" onClick={handleShowStats}> | |
Show Stats | |
</button> | |
<div className="mt-4"> | |
<pre>{JSON.stringify(stats, null, 2)}</pre> | |
</div> | |
</CardContent> | |
</Card> | |
</div> | |
</div> | |
); | |
}; | |
export default AdminDashboard; | |