0% found this document useful (0 votes)
55 views7 pages

Results

The document is a React component that displays student exam results and analytics using various UI components. It includes functionalities for searching results, viewing detailed results in a dialog, and visualizing score distributions through bar and pie charts. The component manages state for search terms, selected results, and active tabs to enhance user interaction.

Uploaded by

anhphi3405
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
55 views7 pages

Results

The document is a React component that displays student exam results and analytics using various UI components. It includes functionalities for searching results, viewing detailed results in a dialog, and visualizing score distributions through bar and pie charts. The component manages state for search terms, selected results, and active tabs to enhance user interaction.

Uploaded by

anhphi3405
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as TXT, PDF, TXT or read online on Scribd
You are on page 1/ 7

"use client"

import { useState } from "react"


import { Button } from "@/components/ui/button"
import { Input } from "@/components/ui/input"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from
"@/components/ui/card"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from
"@/components/ui/table"
import {
Dialog,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from
"@/components/ui/select"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Search, Download, Eye, BarChart, PieChart } from "lucide-react"
import {
BarChart as RechartsBarChart,
Bar,
XAxis,
YAxis,
CartesianGrid,
Tooltip,
ResponsiveContainer,
PieChart as RechartsPieChart,
Pie,
Cell,
Legend,
} from "recharts"

// Sample data
const results = [
{ id: 1, student: "Nguyễn Văn A", class: "10A1", exam: "Kiểm tra 15 phút Toán
10", score: 9.5, date: "15/04/2025" },
{ id: 2, student: "Trần Thị B", class: "10A1", exam: "Kiểm tra 15 phút Toán 10",
score: 8.0, date: "15/04/2025" },
{ id: 3, student: "Lê Văn C", class: "11A2", exam: "Kiểm tra 1 tiết Lý 11",
score: 7.5, date: "14/04/2025" },
{ id: 4, student: "Phạm Thị D", class: "11A2", exam: "Kiểm tra 1 tiết Lý 11",
score: 6.0, date: "14/04/2025" },
{ id: 5, student: "Hoàng Văn E", class: "12A3", exam: "Thi học kỳ Hóa 12", score:
8.5, date: "20/04/2025" },
{ id: 6, student: "Ngô Thị F", class: "12A3", exam: "Thi học kỳ Hóa 12", score:
9.0, date: "20/04/2025" },
{ id: 7, student: "Đỗ Văn G", class: "10A2", exam: "Kiểm tra 45 phút Sinh 10",
score: 7.0, date: "12/04/2025" },
{ id: 8, student: "Vũ Thị H", class: "11A1", exam: "Thi học kỳ Văn 11", score:
8.0, date: "25/04/2025" },
]

const scoreDistribution = [
{ name: "0-4", count: 5 },
{ name: "4-5", count: 10 },
{ name: "5-7", count: 25 },
{ name: "7-8", count: 30 },
{ name: "8-9", count: 20 },
{ name: "9-10", count: 10 },
]

const pieData = [
{ name: "Giỏi (8-10)", value: 30, color: "#4CAF50" },
{ name: "Khá (7-8)", value: 30, color: "#2196F3" },
{ name: "Trung bình (5-7)", value: 25, color: "#FFC107" },
{ name: "Yếu (0-5)", value: 15, color: "#F44336" },
]

export default function Results() {


const [searchTerm, setSearchTerm] = useState("")
const [isViewDialogOpen, setIsViewDialogOpen] = useState(false)
const [selectedResult, setSelectedResult] = useState<any>(null)
const [activeTab, setActiveTab] = useState("results")

const filteredResults = results.filter(


(result) =>
result.student.toLowerCase().includes(searchTerm.toLowerCase()) ||
result.class.toLowerCase().includes(searchTerm.toLowerCase()) ||
result.exam.toLowerCase().includes(searchTerm.toLowerCase()),
)

const handleViewResult = (result: any) => {


setSelectedResult(result)
setIsViewDialogOpen(true)
}

return (
<div className="space-y-6">
<Card>
<CardHeader>
<div className="flex items-center justify-between">
<div>
<CardTitle>Kết quả thi</CardTitle>
<CardDescription>Quản lý và phân tích kết quả thi của học
sinh</CardDescription>
</div>
<Button variant="outline" className="flex items-center gap-1">
<Download className="h-4 w-4" />
Xuất báo cáo
</Button>
</div>
</CardHeader>
<CardContent>
<Tabs defaultValue="results" className="w-full"
onValueChange={setActiveTab}>
<div className="flex justify-between items-center mb-4">
<TabsList>
<TabsTrigger value="results">Kết quả</TabsTrigger>
<TabsTrigger value="analytics">Phân tích</TabsTrigger>
</TabsList>
{activeTab === "results" && (
<div className="relative w-64">
<Search className="absolute left-2 top-2.5 h-4 w-4 text-muted-
foreground" />
<Input
placeholder="Tìm kiếm kết quả..."
className="pl-8"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
/>
</div>
)}
{activeTab === "analytics" && (
<div className="flex gap-2">
<Select defaultValue="all">
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Chọn lớp" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">Tất cả các lớp</SelectItem>
<SelectItem value="10a1">10A1</SelectItem>
<SelectItem value="10a2">10A2</SelectItem>
<SelectItem value="11a1">11A1</SelectItem>
<SelectItem value="11a2">11A2</SelectItem>
<SelectItem value="12a1">12A1</SelectItem>
<SelectItem value="12a2">12A2</SelectItem>
</SelectContent>
</Select>
<Select defaultValue="all">
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Chọn kỳ thi" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all">Tất cả các kỳ thi</SelectItem>
<SelectItem value="exam1">Kiểm tra 15 phút Toán
10</SelectItem>
<SelectItem value="exam2">Kiểm tra 1 tiết Lý 11</SelectItem>
<SelectItem value="exam3">Thi học kỳ Hóa 12</SelectItem>
</SelectContent>
</Select>
</div>
)}
</div>

<TabsContent value="results" className="m-0">


<Table>
<TableHeader>
<TableRow>
<TableHead>Học sinh</TableHead>
<TableHead>Lớp</TableHead>
<TableHead>Đề thi</TableHead>
<TableHead>Điểm số</TableHead>
<TableHead>Ngày thi</TableHead>
<TableHead className="text-right">Thao tác</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{filteredResults.map((result) => (
<TableRow key={result.id}>
<TableCell
className="font-medium">{result.student}</TableCell>
<TableCell>{result.class}</TableCell>
<TableCell>{result.exam}</TableCell>
<TableCell>
<span
className={`px-2 py-1 rounded-full text-xs ${
result.score >= 8
? "bg-green-100 text-green-800"
: result.score >= 7
? "bg-blue-100 text-blue-800"
: result.score >= 5
? "bg-yellow-100 text-yellow-800"
: "bg-red-100 text-red-800"
}`}
>
{result.score.toFixed(1)}
</span>
</TableCell>
<TableCell>{result.date}</TableCell>
<TableCell className="text-right">
<Button variant="outline" size="icon" onClick={() =>
handleViewResult(result)}>
<Eye className="h-4 w-4" />
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</TabsContent>

<TabsContent value="analytics" className="m-0">


<div className="grid md:grid-cols-2 gap-6">
<Card>
<CardHeader className="pb-2">
<div className="flex items-center justify-between">
<div>
<CardTitle className="text-base">Phân bố điểm
số</CardTitle>
<CardDescription>Số lượng học sinh theo thang
điểm</CardDescription>
</div>
<BarChart className="h-4 w-4 text-muted-foreground" />
</div>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<RechartsBarChart data={scoreDistribution}>
<CartesianGrid strokeDasharray="3 3" />
<XAxis dataKey="name" />
<YAxis />
<Tooltip />
<Bar dataKey="count" fill="#8884d8" name="Số học sinh" />
</RechartsBarChart>
</ResponsiveContainer>
</CardContent>
</Card>

<Card>
<CardHeader className="pb-2">
<div className="flex items-center justify-between">
<div>
<CardTitle className="text-base">Phân loại học
lực</CardTitle>
<CardDescription>Tỷ lệ học sinh theo học
lực</CardDescription>
</div>
<PieChart className="h-4 w-4 text-muted-foreground" />
</div>
</CardHeader>
<CardContent>
<ResponsiveContainer width="100%" height={300}>
<RechartsPieChart>
<Pie
data={pieData}
cx="50%"
cy="50%"
labelLine={false}
outerRadius={100}
fill="#8884d8"
dataKey="value"
label={({ name, percent }) => `${name}: ${(percent *
100).toFixed(0)}%`}
>
{pieData.map((entry, index) => (
<Cell key={`cell-${index}`} fill={entry.color} />
))}
</Pie>
<Tooltip />
<Legend />
</RechartsPieChart>
</ResponsiveContainer>
</CardContent>
</Card>
</div>
</TabsContent>
</Tabs>
</CardContent>
</Card>

<Dialog open={isViewDialogOpen} onOpenChange={setIsViewDialogOpen}>


<DialogContent>
{selectedResult && (
<>
<DialogHeader>
<DialogTitle>Chi tiết kết quả thi</DialogTitle>
<DialogDescription>
{selectedResult.exam} - {selectedResult.date}
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
<div className="grid grid-cols-2 gap-4">
<div>
<p className="text-sm text-muted-foreground">Học sinh:</p>
<p className="font-medium">{selectedResult.student}</p>
</div>
<div>
<p className="text-sm text-muted-foreground">Lớp:</p>
<p className="font-medium">{selectedResult.class}</p>
</div>
<div>
<p className="text-sm text-muted-foreground">Điểm số:</p>
<p
className="font-medium">{selectedResult.score.toFixed(1)}/10</p>
</div>
<div>
<p className="text-sm text-muted-foreground">Xếp loại:</p>
<p
className={`font-medium ${
selectedResult.score >= 8
? "text-green-600"
: selectedResult.score >= 7
? "text-blue-600"
: selectedResult.score >= 5
? "text-yellow-600"
: "text-red-600"
}`}
>
{selectedResult.score >= 8
? "Giỏi"
: selectedResult.score >= 7
? "Khá"
: selectedResult.score >= 5
? "Trung bình"
: "Yếu"}
</p>
</div>
</div>

<div className="border rounded-md p-4">


<h3 className="font-medium mb-2">Chi tiết bài làm:</h3>
<div className="space-y-2">
<div className="flex justify-between">
<p>Câu 1:</p>
<p className="text-green-600">1/1 điểm</p>
</div>
<div className="flex justify-between">
<p>Câu 2:</p>
<p className="text-green-600">1/1 điểm</p>
</div>
<div className="flex justify-between">
<p>Câu 3:</p>
<p className="text-red-600">0.5/1 điểm</p>
</div>
<div className="flex justify-between">
<p>Câu 4:</p>
<p className="text-green-600">1/1 điểm</p>
</div>
<div className="flex justify-between">
<p>Câu 5:</p>
<p className="text-green-600">1/1 điểm</p>
</div>
</div>
</div>
</div>
<DialogFooter>
<Button variant="outline">In kết quả</Button>
<Button>Xem bài làm</Button>
</DialogFooter>
</>
)}
</DialogContent>
</Dialog>
</div>
)
}

You might also like