revisi nih boz
This commit is contained in:
155
components/chartstable/tabeljumlahmahasiswa.tsx
Normal file
155
components/chartstable/tabeljumlahmahasiswa.tsx
Normal file
@@ -0,0 +1,155 @@
|
||||
'use client';
|
||||
|
||||
import { useEffect, useState } from 'react';
|
||||
import {
|
||||
Table,
|
||||
TableBody,
|
||||
TableCell,
|
||||
TableHead,
|
||||
TableHeader,
|
||||
TableRow
|
||||
} from "@/components/ui/table";
|
||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||
import { Loader2 } from "lucide-react";
|
||||
|
||||
interface MahasiswaStatistik {
|
||||
tahun_angkatan: number;
|
||||
total_mahasiswa: number;
|
||||
pria: number;
|
||||
wanita: number;
|
||||
}
|
||||
|
||||
export default function TabelJumlahMahasiswa() {
|
||||
const [statistikData, setStatistikData] = useState<MahasiswaStatistik[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
const fetchData = async () => {
|
||||
try {
|
||||
const statistikResponse = await fetch('/api/mahasiswa/statistik', {
|
||||
cache: 'no-store',
|
||||
});
|
||||
|
||||
if (!statistikResponse.ok) {
|
||||
throw new Error('Failed to fetch statistik data');
|
||||
}
|
||||
|
||||
const statistikData = await statistikResponse.json();
|
||||
setStatistikData(statistikData);
|
||||
} catch (err) {
|
||||
setError(err instanceof Error ? err.message : 'Terjadi kesalahan');
|
||||
console.error('Error fetching data:', err);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
fetchData();
|
||||
}, []);
|
||||
|
||||
// Hitung total keseluruhan
|
||||
const grandTotal = {
|
||||
total_mahasiswa: statistikData.reduce((sum, item) => sum + item.total_mahasiswa, 0),
|
||||
pria: statistikData.reduce((sum, item) => sum + item.pria, 0),
|
||||
wanita: statistikData.reduce((sum, item) => sum + item.wanita, 0),
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<Card className="bg-white dark:bg-slate-900 shadow-lg">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-xl font-bold dark:text-white">
|
||||
<div className="flex items-center gap-2">
|
||||
<Loader2 className="h-5 w-5 animate-spin" />
|
||||
Loading...
|
||||
</div>
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
if (error) {
|
||||
return (
|
||||
<Card className="bg-white dark:bg-slate-900 shadow-lg">
|
||||
<CardHeader>
|
||||
<CardTitle className="text-xl font-bold text-red-500 dark:text-red-400">
|
||||
Error: {error}
|
||||
</CardTitle>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Card className="bg-white dark:bg-slate-900 shadow-lg">
|
||||
<CardContent>
|
||||
<div className="border rounded-md overflow-hidden">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="bg-gray-50 dark:bg-slate-800">
|
||||
<TableHead className="font-semibold text-center">Tahun Angkatan</TableHead>
|
||||
<TableHead className="font-semibold text-center">Laki-laki</TableHead>
|
||||
<TableHead className="font-semibold text-center">Perempuan</TableHead>
|
||||
<TableHead className="font-semibold text-center">Total</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{statistikData.length === 0 ? (
|
||||
<TableRow>
|
||||
<TableCell colSpan={4} className="text-center py-8 text-muted-foreground">
|
||||
Tidak ada data yang tersedia
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
) : (
|
||||
<>
|
||||
{statistikData.map((item, index) => (
|
||||
<TableRow
|
||||
key={item.tahun_angkatan}
|
||||
className={index % 2 === 0 ? "bg-white dark:bg-slate-900" : "bg-gray-50/50 dark:bg-slate-800/50"}
|
||||
>
|
||||
<TableCell className="text-center font-medium dark:text-white">
|
||||
{item.tahun_angkatan}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<div className="font-medium dark:text-white">{item.pria}</div>
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<div className="font-medium dark:text-white">{item.wanita}</div>
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<div className="font-semibold dark:text-white">
|
||||
{item.total_mahasiswa}
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
|
||||
{/* Total Row */}
|
||||
<TableRow className="bg-blue-50 dark:bg-blue-900/20 border-t-2 border-blue-200 dark:border-blue-700 dark:text-white">
|
||||
<TableCell className="text-center font-bold">
|
||||
TOTAL
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<div className="font-bold dark:text-white">{grandTotal.pria}</div>
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<div className="font-bold dark:text-white">{grandTotal.wanita}</div>
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<div className="font-bold text-lg">
|
||||
{grandTotal.total_mahasiswa}
|
||||
</div>
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
</>
|
||||
)}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</div>
|
||||
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user