'use client'; import { useEffect, useState } from 'react'; import dynamic from 'next/dynamic'; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { useTheme } from "next-themes"; const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface GenderStatistik { tahun_angkatan: number; jk: string; jumlah: number; } interface Props { tahunAngkatan: string; } export default function StatistikPerAngkatanChart({ tahunAngkatan }: Props) { const { theme, systemTheme } = useTheme(); const [statistikData, setStatistikData] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { const fetchData = async () => { try { setLoading(true); setError(null); const response = await fetch(`/api/mahasiswa/gender-per-angkatan?tahun=${tahunAngkatan}`); if (!response.ok) { throw new Error(`Failed to fetch data: ${response.status} ${response.statusText}`); } const result = await response.json(); if (!Array.isArray(result)) { throw new Error('Invalid data format received from server'); } setStatistikData(result); } catch (err) { console.error('Error in fetchData:', err); setError(err instanceof Error ? err.message : 'An error occurred while fetching data'); } finally { setLoading(false); } }; if (tahunAngkatan !== "all") { fetchData(); } }, [tahunAngkatan]); const [chartOptions, setChartOptions] = useState({ chart: { type: 'pie' as const, toolbar: { show: true, tools: { download: true, selection: true, zoom: true, zoomin: true, zoomout: true, pan: true, reset: true } }, background: 'transparent', }, labels: ['Laki-laki', 'Perempuan'], colors: ['#3B82F6', '#EC4899'], legend: { position: 'bottom' as const, fontSize: '14px', markers: { size: 12, strokeWidth: 0 }, itemMargin: { horizontal: 10 }, labels: { colors: '#000', style: { fontSize: '14px', fontFamily: 'Inter, sans-serif', fontWeight: '500' } } }, dataLabels: { enabled: true, formatter: function (val: number, opts: any) { return val.toString(); }, style: { fontSize: '14px', fontFamily: 'Inter, sans-serif', fontWeight: '500' }, offsetY: 0, dropShadow: { enabled: false }, position: 'top' }, tooltip: { theme: 'light', y: { formatter: function (val: number) { return val + " mahasiswa" } } } }); // Update theme when it changes useEffect(() => { const currentTheme = theme === 'system' ? systemTheme : theme; const textColor = currentTheme === 'dark' ? '#fff' : '#000'; const tooltipTheme = currentTheme === 'dark' ? 'dark' : 'light'; setChartOptions(prev => ({ ...prev, chart: { ...prev.chart, background: currentTheme === 'dark' ? '#0F172B' : '#fff', }, legend: { ...prev.legend, labels: { ...prev.legend.labels, colors: textColor, } }, dataLabels: { ...prev.dataLabels, style: { ...prev.dataLabels.style, color: textColor } }, tooltip: { ...prev.tooltip, theme: tooltipTheme } })); }, [theme, systemTheme]); // Update dataLabels formatter when data changes useEffect(() => { if (statistikData.length > 0) { setChartOptions(prev => ({ ...prev, dataLabels: { ...prev.dataLabels, formatter: function (val: number, opts: any) { const total = statistikData.reduce((sum, item) => sum + item.jumlah, 0); const percentage = ((statistikData[opts.seriesIndex]?.jumlah / total) * 100) || 0; return `${percentage.toFixed(0)}%`; } } })); } }, [statistikData]); const chartSeries = statistikData.map(item => item.jumlah); const totalMahasiswa = statistikData.reduce((sum, item) => sum + item.jumlah, 0); if (tahunAngkatan === "all") { return null; } if (loading) { return ( Loading... ); } if (error) { return ( Error: {error} ); } if (statistikData.length === 0) { return ( Tidak ada data yang tersedia ); } return ( Total Mahasiswa Angkatan {tahunAngkatan}
Total Mahasiswa: {totalMahasiswa}
); }