Spaces:
Running
Running
import React, { useState, useEffect } from 'react'; | |
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card'; | |
import { Button } from '@/components/ui/button'; | |
import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer } from 'recharts'; | |
import { Upload, RefreshCw, Users, BarChart2, ThumbsUp, Database } from 'lucide-react'; | |
import { Alert, AlertDescription } from '@/components/ui/alert'; | |
const AdminDashboard = () => { | |
const [stats, setStats] = useState({ | |
accuracy: 95.5, | |
interactions: 1234, | |
satisfaction: 98, | |
lastUpdate: new Date().toLocaleString(), | |
averageResponseTime: 0.5, | |
totalQuestions: 3500 | |
}); | |
const [learningData, setLearningData] = useState([ | |
{ date: '2024-01', accuracy: 90 }, | |
{ date: '2024-02', accuracy: 92 }, | |
{ date: '2024-03', accuracy: 94 }, | |
{ date: '2024-04', accuracy: 95.5 } | |
]); | |
const [isUpdating, setIsUpdating] = useState(false); | |
const [updateStatus, setUpdateStatus] = useState(null); | |
const updateKnowledgeBase = async () => { | |
setIsUpdating(true); | |
setUpdateStatus('درحال بهروزرسانی پایگاه دانش...'); | |
try { | |
// ارسال درخواست بهروزرسانی به سرور | |
const response = await fetch('/api/update-knowledge-base', { | |
method: 'POST', | |
headers: { | |
'Content-Type': 'application/json', | |
} | |
}); | |
if (response.ok) { | |
setUpdateStatus('بهروزرسانی با موفقیت انجام شد'); | |
setStats(prev => ({ | |
...prev, | |
lastUpdate: new Date().toLocaleString() | |
})); | |
} else { | |
throw new Error('خطا در بهروزرسانی'); | |
} | |
} catch (error) { | |
setUpdateStatus('خطا در بهروزرسانی پایگاه دانش'); | |
} finally { | |
setIsUpdating(false); | |
// پاک کردن پیام وضعیت بعد از 3 ثانیه | |
setTimeout(() => setUpdateStatus(null), 3000); | |
} | |
}; | |
const handleFileUpload = async (event) => { | |
const file = event.target.files[0]; | |
if (!file) return; | |
const formData = new FormData(); | |
formData.append('file', file); | |
try { | |
const response = await fetch('/api/upload-document', { | |
method: 'POST', | |
body: formData | |
}); | |
if (response.ok) { | |
setUpdateStatus('فایل با موفقیت آپلود شد'); | |
} else { | |
throw new Error('خطا در آپلود فایل'); | |
} | |
} catch (error) { | |
setUpdateStatus('خطا در آپلود فایل'); | |
} | |
}; | |
return ( | |
<div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 p-8 rtl"> | |
<div className="max-w-6xl mx-auto space-y-8"> | |
{/* Header */} | |
<div className="text-center"> | |
<h1 className="text-4xl font-bold text-gray-800 mb-4">پنل مدیریت</h1> | |
<p className="text-gray-600">آخرین بهروزرسانی: {stats.lastUpdate}</p> | |
</div> | |
{/* Status Alert */} | |
{updateStatus && ( | |
<Alert className="bg-white/30 backdrop-blur-lg"> | |
<AlertDescription>{updateStatus}</AlertDescription> | |
</Alert> | |
)} | |
{/* Stats Cards */} | |
<div className="grid md:grid-cols-3 gap-6"> | |
{/* Response Time Card */} | |
<div className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)] transition-all duration-300 hover:shadow-[8px_8px_25px_rgba(0,0,0,0.12),-8px_-8px_25px_rgba(255,255,255,0.9)] hover:transform hover:-translate-y-1"> | |
<div className="flex items-center justify-between"> | |
<BarChart2 className="text-blue-500" size={24} /> | |
<h3 className="text-lg font-semibold text-gray-700">زمان پاسخدهی</h3> | |
</div> | |
<p className="text-3xl font-bold text-blue-600 mt-4">{stats.averageResponseTime}s</p> | |
</div> | |
{/* Questions Card */} | |
<div className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)] transition-all duration-300 hover:shadow-[8px_8px_25px_rgba(0,0,0,0.12),-8px_-8px_25px_rgba(255,255,255,0.9)] hover:transform hover:-translate-y-1"> | |
<div className="flex items-center justify-between"> | |
<Users className="text-green-500" size={24} /> | |
<h3 className="text-lg font-semibold text-gray-700">تعداد سوالات</h3> | |
</div> | |
<p className="text-3xl font-bold text-green-600 mt-4">{stats.totalQuestions}</p> | |
</div> | |
{/* Accuracy Card */} | |
<div className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)] transition-all duration-300 hover:shadow-[8px_8px_25px_rgba(0,0,0,0.12),-8px_-8px_25px_rgba(255,255,255,0.9)] hover:transform hover:-translate-y-1"> | |
<div className="flex items-center justify-between"> | |
<ThumbsUp className="text-purple-500" size={24} /> | |
<h3 className="text-lg font-semibold text-gray-700">دقت پاسخگویی</h3> | |
</div> | |
<p className="text-3xl font-bold text-purple-600 mt-4">{stats.accuracy}%</p> | |
</div> | |
</div> | |
{/* Chart Section */} | |
<Card className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)]"> | |
<CardHeader> | |
<CardTitle>روند یادگیری</CardTitle> | |
</CardHeader> | |
<CardContent> | |
<div className="h-64"> | |
<ResponsiveContainer width="100%" height="100%"> | |
<LineChart data={learningData}> | |
<CartesianGrid strokeDasharray="3 3" /> | |
<XAxis dataKey="date" /> | |
<YAxis domain={[80, 100]} /> | |
<Tooltip /> | |
<Line | |
type="monotone" | |
dataKey="accuracy" | |
stroke="#4F46E5" | |
strokeWidth={2} | |
dot={{ fill: '#4F46E5' }} | |
/> | |
</LineChart> | |
</ResponsiveContainer> | |
</div> | |
</CardContent> | |
</Card> | |
{/* Actions Section */} | |
<div className="grid md:grid-cols-2 gap-6"> | |
{/* Update Knowledge Base Button */} | |
<Button | |
onClick={updateKnowledgeBase} | |
disabled={isUpdating} | |
className="bg-gradient-to-r from-blue-500 to-indigo-600 text-white rounded-xl p-4 flex items-center justify-center gap-2 shadow-[5px_5px_20px_rgba(0,0,0,0.1)] transition-all duration-300 hover:shadow-[8px_8px_25px_rgba(0,0,0,0.12)] hover:transform hover:-translate-y-1" | |
> | |
<Database className={`w-5 h-5 ${isUpdating ? 'animate-spin' : ''}`} /> | |
{isUpdating ? 'در حال بهروزرسانی...' : 'بهروزرسانی پایگاه دانش'} | |
</Button> | |
{/* File Upload Section */} | |
<div className="bg-white/30 backdrop-blur-lg rounded-2xl p-6 shadow-[5px_5px_20px_rgba(0,0,0,0.1),-5px_-5px_20px_rgba(255,255,255,0.8)]"> | |
<div className="flex items-center justify-center w-full"> | |
<label className="flex flex-col items-center justify-center w-full h-32 border-2 border-dashed rounded-xl border-gray-300 cursor-pointer bg-white/50 hover:bg-white/70 transition-all duration-300"> | |
<div className="flex flex-col items-center justify-center pt-5 pb-6"> | |
<Upload className="w-8 h-8 text-gray-500 mb-2" /> | |
<p className="text-sm text-gray-500">برای آپلود فایل کلیک کنید</p> | |
</div> | |
<input | |
type="file" | |
className="hidden" | |
onChange={handleFileUpload} | |
accept=".txt,.pdf,.docx" | |
/> | |
</label> | |
</div> | |
</div> | |
</div> | |
</div> | |
</div> | |
); | |
}; | |
export default AdminDashboard; |