'use client'; import { useEffect, useState } from 'react'; import dynamic from 'next/dynamic'; import { ApexOptions } from 'apexcharts'; import { useTheme } from 'next-themes'; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; // Dynamically import ApexCharts to avoid SSR issues const Chart = dynamic(() => import('react-apexcharts'), { ssr: false }); interface AsalDaerahData { kabupaten: string; jumlah: number; } interface Props { tahunAngkatan: string; } export default function AsalDaerahPerAngkatanChart({ tahunAngkatan }: Props) { const { theme } = useTheme(); const [mounted, setMounted] = useState(false); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [data, setData] = useState([]); const [series, setSeries] = useState([{ name: 'Jumlah Mahasiswa', data: [] }]); const [options, setOptions] = useState({ chart: { type: 'bar', stacked: false, toolbar: { show: true, tools: { download: true, selection: true, zoom: true, zoomin: true, zoomout: true, pan: true, reset: true, customIcons: [] }, export: { csv: { filename: `asal-daerah-angkatan`, columnDelimiter: ',', headerCategory: 'Asal Daerah', headerValue: 'Jumlah Mahasiswa' } }, }, }, plotOptions: { bar: { horizontal: true, columnWidth: '85%', distributed: false, barHeight: '90%', dataLabels: { position: 'top' } } }, dataLabels: { enabled: true, formatter: function (val: number) { return val.toString(); }, style: { fontSize: '14px', colors: [theme === 'dark' ? '#fff' : '#000'] }, offsetX: 10, }, stroke: { show: true, width: 1, colors: [theme === 'dark' ? '#374151' : '#E5E7EB'], }, xaxis: { categories: [], title: { text: 'Jumlah Mahasiswa', style: { fontSize: '14px', fontWeight: 'bold', color: theme === 'dark' ? '#fff' : '#000' } }, labels: { style: { fontSize: '12px', colors: theme === 'dark' ? '#fff' : '#000' } } }, yaxis: { title: { text: 'Kabupaten', style: { fontSize: '14px', fontWeight: 'bold', color: theme === 'dark' ? '#fff' : '#000' } }, labels: { style: { fontSize: '14px', colors: theme === 'dark' ? '#fff' : '#000' }, maxWidth: 200, }, }, grid: { padding: { top: 0, right: 0, bottom: 0, left: 0 } }, fill: { opacity: 1, }, colors: ['#3B82F6'], // Blue color for bars tooltip: { theme: theme === 'dark' ? 'dark' : 'light', y: { formatter: function (val: number) { return val + " mahasiswa"; } } } }); // Update theme when it changes useEffect(() => { setOptions(prev => ({ ...prev, chart: { ...prev.chart, background: theme === 'dark' ? '#0F172B' : '#fff', }, dataLabels: { ...prev.dataLabels, style: { ...prev.dataLabels?.style, colors: [theme === 'dark' ? '#fff' : '#000'] } }, xaxis: { ...prev.xaxis, title: { ...prev.xaxis?.title, style: { ...prev.xaxis?.title?.style, color: theme === 'dark' ? '#fff' : '#000' } }, labels: { ...prev.xaxis?.labels, style: { ...prev.xaxis?.labels?.style, colors: theme === 'dark' ? '#fff' : '#000' } } }, yaxis: { ...prev.yaxis, title: { ...(Array.isArray(prev.yaxis) ? prev.yaxis[0]?.title : prev.yaxis?.title), style: { ...(Array.isArray(prev.yaxis) ? prev.yaxis[0]?.title?.style : prev.yaxis?.title?.style), color: theme === 'dark' ? '#fff' : '#000' } }, labels: { ...(Array.isArray(prev.yaxis) ? prev.yaxis[0]?.labels : prev.yaxis?.labels), style: { ...(Array.isArray(prev.yaxis) ? prev.yaxis[0]?.labels?.style : prev.yaxis?.labels?.style), colors: theme === 'dark' ? '#fff' : '#000' } } }, tooltip: { ...prev.tooltip, theme: theme === 'dark' ? 'dark' : 'light' } })); }, [theme]); useEffect(() => { setMounted(true); }, []); useEffect(() => { const fetchData = async () => { try { setLoading(true); setError(null); const response = await fetch(`/api/mahasiswa/asal-daerah-angkatan?tahun_angkatan=${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'); } setData(result); // Process data for chart const kabupaten = result.map(item => item.kabupaten); const jumlah = result.map(item => item.jumlah); setSeries([{ name: 'Jumlah Mahasiswa', data: jumlah }]); setOptions(prev => ({ ...prev, xaxis: { ...prev.xaxis, categories: kabupaten, }, chart: { ...prev.chart, toolbar: { ...prev.chart?.toolbar, export: { ...prev.chart?.toolbar?.export, csv: { ...prev.chart?.toolbar?.export?.csv, filename: `asal-daerah-angkatan-${tahunAngkatan}`, } } } } })); } 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) { fetchData(); } }, [tahunAngkatan]); if (!mounted) { return null; } if (loading) { return ( Loading... ); } if (error) { return ( Error: {error} ); } if (data.length === 0) { return ( Tidak ada data yang tersedia ); } // Calculate dynamic height based on number of kabupaten const calculateHeight = () => { const minHeight = 100; const barHeight = 15; // Height per bar in pixels const padding = 50; // Extra space for title, legend, etc. const dynamicHeight = Math.max(minHeight, (data.length * barHeight) + padding); return `${dynamicHeight}px`; }; return ( Asal Daerah Mahasiswa Angkatan {tahunAngkatan}
); }