diff --git a/app/api/mahasiswa/profile/route.ts b/app/api/mahasiswa/profile/route.ts index c8e4dfa..7436c9f 100644 --- a/app/api/mahasiswa/profile/route.ts +++ b/app/api/mahasiswa/profile/route.ts @@ -3,19 +3,42 @@ import supabase from '@/lib/db'; import { cookies } from 'next/headers'; import { jwtVerify } from 'jose'; +interface PrestasiMahasiswa { + nama_prestasi: string; + jenis_prestasi: string; + tingkat_prestasi: string; + peringkat: string; + tanggal_prestasi: string; +} + +interface BeasiswaMahasiswa { + nama_beasiswa: string; + sumber_beasiswa: string; + jenis_beasiswa: string; + beasiswa_status: string; +} + interface MahasiswaProfile { - nim: string; + // Data Mahasiswa nama: string; + nim: string; + tahun_angkatan: string; jk: 'Pria' | 'Wanita'; + jenis_pendaftaran: string; + ipk: number | null; agama: string; kabupaten: string; provinsi: string; - jenis_pendaftaran: string; - status_beasiswa: 'YA' | 'TIDAK'; - tahun_angkatan: string; - ipk: number | null; - prestasi: 'YA' | 'TIDAK'; + + // Status Mahasiswa status_kuliah: string; + semester: string; + + // Prestasi Mahasiswa + prestasi: PrestasiMahasiswa[]; + + // Beasiswa Mahasiswa + beasiswa: BeasiswaMahasiswa[]; } export async function GET(request: Request) { @@ -43,17 +66,15 @@ export async function GET(request: Request) { const { data: mahasiswaData, error: mahasiswaError } = await supabase .from('mahasiswa') .select(` - nim, nama, + nim, + tahun_angkatan, jk, + jenis_pendaftaran, + ipk, agama, kabupaten, - provinsi, - jenis_pendaftaran, - status_beasiswa, - tahun_angkatan, - ipk, - prestasi + provinsi `) .eq('nim', nim) .single(); @@ -65,27 +86,58 @@ export async function GET(request: Request) { ); } - // Get status_kuliah separately + // Get status_mahasiswa data const { data: statusData, error: statusError } = await supabase .from('status_mahasiswa') - .select('status_kuliah') + .select('status_kuliah, semester') .eq('nim', nim) .single(); + // Get prestasi_mahasiswa data + const { data: prestasiData, error: prestasiError } = await supabase + .from('prestasi_mahasiswa') + .select(` + nama_prestasi, + jenis_prestasi, + tingkat_prestasi, + peringkat, + tanggal_prestasi + `) + .eq('nim', nim); + + // Get beasiswa_mahasiswa data + const { data: beasiswaData, error: beasiswaError } = await supabase + .from('beasiswa_mahasiswa') + .select(` + nama_beasiswa, + sumber_beasiswa, + jenis_beasiswa, + beasiswa_status + `) + .eq('nim', nim); + // Transform the data to match the expected interface const profile: MahasiswaProfile = { - nim: mahasiswaData.nim, + // Data Mahasiswa nama: mahasiswaData.nama, + nim: mahasiswaData.nim, + tahun_angkatan: mahasiswaData.tahun_angkatan, jk: mahasiswaData.jk, + jenis_pendaftaran: mahasiswaData.jenis_pendaftaran, + ipk: mahasiswaData.ipk, agama: mahasiswaData.agama, kabupaten: mahasiswaData.kabupaten, provinsi: mahasiswaData.provinsi, - jenis_pendaftaran: mahasiswaData.jenis_pendaftaran, - status_beasiswa: mahasiswaData.status_beasiswa, - tahun_angkatan: mahasiswaData.tahun_angkatan, - ipk: mahasiswaData.ipk, - prestasi: mahasiswaData.prestasi, - status_kuliah: statusData?.status_kuliah || '' + + // Status Mahasiswa + status_kuliah: statusData?.status_kuliah || '-', + semester: statusData?.semester || '-', + + // Prestasi Mahasiswa + prestasi: prestasiData || [], + + // Beasiswa Mahasiswa + beasiswa: beasiswaData || [] }; return NextResponse.json(profile); diff --git a/app/api/mahasiswa/tingkat-prestasi/route.ts b/app/api/mahasiswa/tingkat-prestasi/route.ts index 8cc790f..e4feb7c 100644 --- a/app/api/mahasiswa/tingkat-prestasi/route.ts +++ b/app/api/mahasiswa/tingkat-prestasi/route.ts @@ -4,19 +4,44 @@ import supabase from '@/lib/db'; export async function GET(request: Request) { try { const { searchParams } = new URL(request.url); + const tahunAngkatan = searchParams.get('tahunAngkatan'); const jenisPrestasi = searchParams.get('jenisPrestasi'); - const { data, error } = await supabase + // Validate jenisPrestasi parameter (allow null) + if (jenisPrestasi && jenisPrestasi !== 'null' && jenisPrestasi !== 'undefined') { + // Validate against valid enum values only if jenisPrestasi is provided + const validJenisPrestasi = ['Akademik', 'Non-Akademik']; + if (!validJenisPrestasi.includes(jenisPrestasi)) { + return NextResponse.json( + { error: `Invalid jenisPrestasi value. Must be one of: ${validJenisPrestasi.join(', ')}` }, + { status: 400 } + ); + } + } + + // Build query based on parameters + let query = supabase .from('mahasiswa') .select(` tahun_angkatan, - prestasi_mahasiswa!inner( + prestasi_mahasiswa( tingkat_prestasi, jenis_prestasi ) - `) - .eq('prestasi_mahasiswa.jenis_prestasi', jenisPrestasi); + `); + // Add tahun angkatan filter if provided + if (tahunAngkatan && tahunAngkatan !== 'null' && tahunAngkatan !== 'undefined') { + query = query.eq('tahun_angkatan', parseInt(tahunAngkatan)); + } + + // Add jenis prestasi filter if provided + if (jenisPrestasi && jenisPrestasi !== 'null' && jenisPrestasi !== 'undefined') { + query = query.eq('prestasi_mahasiswa.jenis_prestasi', jenisPrestasi); + } + + const { data, error } = await query; + if (error) { console.error('Supabase error:', error); return NextResponse.json( @@ -28,25 +53,39 @@ export async function GET(request: Request) { // Group and count the data in JavaScript const groupedData = data.reduce((acc: any[], row: any) => { const tahunAngkatan = row.tahun_angkatan; - const tingkatPrestasi = row.prestasi_mahasiswa?.tingkat_prestasi; - if (!tahunAngkatan || !tingkatPrestasi) return acc; + // Handle array of prestasi_mahasiswa + const prestasiArray = Array.isArray(row.prestasi_mahasiswa) ? row.prestasi_mahasiswa : [row.prestasi_mahasiswa]; - const existingGroup = acc.find( - (item: any) => - item.tahun_angkatan === tahunAngkatan && - item.tingkat_prestasi === tingkatPrestasi - ); - - if (existingGroup) { - existingGroup.tingkat_mahasiswa_prestasi++; - } else { - acc.push({ - tahun_angkatan: tahunAngkatan, - tingkat_prestasi: tingkatPrestasi, - tingkat_mahasiswa_prestasi: 1 - }); + if (!tahunAngkatan) { + return acc; } + + // Process each prestasi in the array + prestasiArray.forEach((prestasi: any) => { + if (!prestasi || !prestasi.tingkat_prestasi) { + return; + } + + const tingkatPrestasi = prestasi.tingkat_prestasi; + + const existingGroup = acc.find( + (item: any) => + item.tahun_angkatan === tahunAngkatan && + item.tingkat_prestasi === tingkatPrestasi + ); + + if (existingGroup) { + existingGroup.tingkat_mahasiswa_prestasi++; + } else { + const newGroup = { + tahun_angkatan: tahunAngkatan, + tingkat_prestasi: tingkatPrestasi, + tingkat_mahasiswa_prestasi: 1 + }; + acc.push(newGroup); + } + }); return acc; }, []); diff --git a/app/mahasiswa/profile/page.tsx b/app/mahasiswa/profile/page.tsx index 1eeca37..37fc7d1 100644 --- a/app/mahasiswa/profile/page.tsx +++ b/app/mahasiswa/profile/page.tsx @@ -5,22 +5,45 @@ import { useRouter } from 'next/navigation'; import { useToast } from '@/components/ui/use-toast'; import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card'; import { Skeleton } from '@/components/ui/skeleton'; -import { User } from 'lucide-react'; +import { User, Trophy, Award } from 'lucide-react'; import { useTheme } from 'next-themes'; +interface PrestasiMahasiswa { + nama_prestasi: string; + jenis_prestasi: string; + tingkat_prestasi: string; + peringkat: string; + tanggal_prestasi: string; +} + +interface BeasiswaMahasiswa { + nama_beasiswa: string; + sumber_beasiswa: string; + jenis_beasiswa: string; + beasiswa_status: string; +} + interface MahasiswaProfile { - nim: string; + // Data Mahasiswa nama: string; + nim: string; + tahun_angkatan: string; jk: 'Pria' | 'Wanita'; + jenis_pendaftaran: string; + ipk: number | null; agama: string; kabupaten: string; provinsi: string; - jenis_pendaftaran: string; - status_beasiswa: 'YA' | 'TIDAK'; - tahun_angkatan: string; - ipk: number | null; - prestasi: 'YA' | 'TIDAK'; + + // Status Mahasiswa status_kuliah: string; + semester: string; + + // Prestasi Mahasiswa + prestasi: PrestasiMahasiswa[]; + + // Beasiswa Mahasiswa + beasiswa: BeasiswaMahasiswa[]; } export default function ProfilePage() { @@ -72,29 +95,31 @@ export default function ProfilePage() { if (loading) { return ( -
- - - Profil Mahasiswa - - -
- {[...Array(8)].map((_, i) => ( -
- - -
- ))} -
-
-
+
+ {[...Array(3)].map((_, i) => ( + + + + + +
+ {[...Array(8)].map((_, j) => ( +
+ + +
+ ))} +
+
+
+ ))}
); } if (!profile) { return ( -
+
Profil Mahasiswa @@ -115,8 +140,26 @@ export default function ProfilePage() { return Number(ipk).toFixed(2); }; + // Get first prestasi or create empty object + const firstPrestasi = profile.prestasi.length > 0 ? profile.prestasi[0] : { + nama_prestasi: '-', + jenis_prestasi: '-', + tingkat_prestasi: '-', + peringkat: '-', + tanggal_prestasi: '-' + }; + + // Get first beasiswa or create empty object + const firstBeasiswa = profile.beasiswa.length > 0 ? profile.beasiswa[0] : { + nama_beasiswa: '-', + sumber_beasiswa: '-', + jenis_beasiswa: '-', + beasiswa_status: '-' + }; + return ( -
+
+ {/* Data Mahasiswa */}
@@ -124,44 +167,139 @@ export default function ProfilePage() {
- {profile.nama} -

{profile.nim}

+ Data Mahasiswa
-
-
-
Jenis Kelamin
-
{profile.jk}
+
+
+
+
Nama Lengkap
+
{profile.nama}
+
+
+
NIM
+
{profile.nim}
+
+
+
Status Kuliah
+
{profile.status_kuliah}
+
+
+
Semester
+
{profile.semester}
+
+
+
Tahun Angkatan
+
{profile.tahun_angkatan}
+
+
+
Jenis Kelamin
+
{profile.jk}
+
-
-
Agama
-
{profile.agama}
+
+
+
Jenis Pendaftaran
+
{profile.jenis_pendaftaran}
+
+
+
IPK
+
{formatIPK(profile.ipk)}
+
+
+
Agama
+
{profile.agama}
+
+
+
Kabupaten
+
{profile.kabupaten}
+
+
+
Provinsi
+
{profile.provinsi}
+
-
-
Kabupaten
-
{profile.kabupaten}
+
+ + + + {/* Prestasi Mahasiswa */} + + +
+
+
-
-
Provinsi
-
{profile.provinsi}
+
+ Prestasi Mahasiswa
-
-
Jenis Pendaftaran
-
{profile.jenis_pendaftaran}
+
+ + +
+
+
+
Nama Prestasi
+
{firstPrestasi.nama_prestasi}
+
+
+
Jenis Prestasi
+
{firstPrestasi.jenis_prestasi}
+
+
+
Tingkat Prestasi
+
{firstPrestasi.tingkat_prestasi}
+
-
-
Tahun Angkatan
-
{profile.tahun_angkatan}
+
+
+
Peringkat
+
{firstPrestasi.peringkat}
+
+
+
Tanggal Prestasi
+
{firstPrestasi.tanggal_prestasi}
+
-
-
IPK
-
{formatIPK(profile.ipk)}
+
+ + + + {/* Beasiswa Mahasiswa */} + + +
+
+
-
-
Status Kuliah
-
{profile.status_kuliah || '-'}
+
+ Beasiswa Mahasiswa +
+
+ + +
+
+
+
Nama Beasiswa
+
{firstBeasiswa.nama_beasiswa}
+
+
+
Sumber Beasiswa
+
{firstBeasiswa.sumber_beasiswa}
+
+
+
+
+
Jenis Beasiswa
+
{firstBeasiswa.jenis_beasiswa}
+
+
+
Status Beasiswa
+
{firstBeasiswa.beasiswa_status}
+
diff --git a/app/page.tsx b/app/page.tsx index 14cd478..b848205 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -188,10 +188,9 @@ export default function HomePage() { -
{mahasiswaData.total_mahasiswa_aktif_lulus}
+
{mahasiswaData.mahasiswa_aktif}
Aktif: {mahasiswaData.ipk_rata_rata_aktif} - Lulus: {mahasiswaData.ipk_rata_rata_lulus}
diff --git a/components/AsalDaerahPerAngkatanChart.tsx b/components/AsalDaerahPerAngkatanChart.tsx index 9896a8a..a3e1533 100644 --- a/components/AsalDaerahPerAngkatanChart.tsx +++ b/components/AsalDaerahPerAngkatanChart.tsx @@ -227,11 +227,19 @@ export default function AsalDaerahPerAngkatanChart({ tahunAngkatan }: Props) { name: 'Jumlah Mahasiswa', data: jumlah }]); + + // Calculate the maximum value from data + const maxValue = Math.max(...jumlah); + + // Add 10% padding to the maximum value + const xAxisMax = Math.ceil(maxValue * 1.1); + setOptions(prev => ({ ...prev, xaxis: { ...prev.xaxis, categories: kabupaten, + max: xAxisMax }, chart: { ...prev.chart, diff --git a/components/JenisPendaftaranBeasiswaChart.tsx b/components/JenisPendaftaranBeasiswaChart.tsx index 7cd400f..9e02c45 100644 --- a/components/JenisPendaftaranBeasiswaChart.tsx +++ b/components/JenisPendaftaranBeasiswaChart.tsx @@ -203,6 +203,23 @@ export default function JenisPendaftaranBeasiswaChart({ selectedYear, selectedJe const series = processSeriesData(); + // Calculate the maximum value from all series for y-axis padding + const maxValue = Math.max( + ...series.flatMap(s => s.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + + // Update chart options with y-axis max + const updatedChartOptions: ApexOptions = { + ...chartOptions, + yaxis: { + ...chartOptions.yaxis, + max: yAxisMax + } + }; + if (loading) { return ( @@ -251,7 +268,7 @@ export default function JenisPendaftaranBeasiswaChart({ selectedYear, selectedJe
{typeof window !== 'undefined' && series.length > 0 && ( series.data) + ); + + // Add 20% padding to the maximum value + const xAxisMax = Math.ceil(maxValue * 1.1); + setOptions(prev => ({ ...prev, xaxis: { ...prev.xaxis, categories: tahunAngkatan, + max: xAxisMax }, })); } catch (err) { diff --git a/components/JenisPendaftaranLulusChart.tsx b/components/JenisPendaftaranLulusChart.tsx index f0f97ce..6a6cc80 100644 --- a/components/JenisPendaftaranLulusChart.tsx +++ b/components/JenisPendaftaranLulusChart.tsx @@ -200,6 +200,23 @@ export default function JenisPendaftaranLulusChart({ selectedYear }: Props) { const series = processSeriesData(); + // Calculate the maximum value from all series for y-axis padding + const maxValue = Math.max( + ...series.flatMap(s => s.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + + // Update chart options with y-axis max + const updatedChartOptions: ApexOptions = { + ...chartOptions, + yaxis: { + ...chartOptions.yaxis, + max: yAxisMax + } + }; + if (loading) { return ( @@ -248,7 +265,7 @@ export default function JenisPendaftaranLulusChart({ selectedYear }: Props) {
{typeof window !== 'undefined' && series.length > 0 && ( s.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + + // Update chart options with y-axis max + const updatedChartOptions: ApexOptions = { + ...chartOptions, + yaxis: { + ...chartOptions.yaxis, + max: yAxisMax + } + }; + if (loading) { return ( @@ -236,7 +253,7 @@ export default function JenisPendaftaranStatusChart({ selectedYear, selectedStat
{typeof window !== 'undefined' && ( s.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + + // Update chart options with y-axis max + const updatedChartOptions: ApexOptions = { + ...chartOptions, + yaxis: { + ...chartOptions.yaxis, + max: yAxisMax + } + }; + if (loading) { return ( @@ -266,7 +283,7 @@ export default function LulusTepatWaktuChart({ selectedYear }: Props) {
{typeof window !== 'undefined' && series.length > 0 && ( s.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + + // Update chart options with y-axis max + const updatedChartOptions: ApexOptions = { + ...chartOptions, + yaxis: { + ...chartOptions.yaxis, + max: yAxisMax + } + }; + if (loading) { return ( @@ -251,7 +268,7 @@ export default function NamaBeasiswaChart({ selectedYear, selectedJenisBeasiswa
{typeof window !== 'undefined' && series.length > 0 && ( { if (statistikData.length > 0) { + // Calculate the maximum value from all series + const maxValue = Math.max( + ...statistikData.map(item => item.total_mahasiswa), + ...statistikData.map(item => item.pria), + ...statistikData.map(item => item.wanita) + ); + + // Add 50% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + setChartOptions(prev => ({ ...prev, xaxis: { ...prev.xaxis, categories: statistikData.map(item => item.tahun_angkatan) - } + }, + yaxis: [ + { + ...prev.yaxis[0], + max: yAxisMax + } + ] })); } }, [statistikData]); @@ -259,15 +275,15 @@ export default function StatistikMahasiswaChart() { type: 'bar' as const, data: statistikData.map(item => item.pria) }, + { + name: 'Total', + type: 'bar' as const, + data: statistikData.map(item => item.total_mahasiswa) + }, { name: 'Perempuan', type: 'bar' as const, data: statistikData.map(item => item.wanita) - }, - { - name: 'Total', - type: 'line' as const, - data: statistikData.map(item => item.total_mahasiswa) } ]; diff --git a/components/StatusMahasiswaChart.tsx b/components/StatusMahasiswaChart.tsx index ad73b24..48d2bff 100644 --- a/components/StatusMahasiswaChart.tsx +++ b/components/StatusMahasiswaChart.tsx @@ -143,12 +143,25 @@ export default function StatusMahasiswaChart() { })); setSeries(seriesData); + + // Calculate the maximum value from all series + const maxValue = Math.max( + ...seriesData.flatMap(series => series.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + setOptions(prev => ({ ...prev, xaxis: { ...prev.xaxis, categories: tahunAngkatan, }, + yaxis: { + ...prev.yaxis, + max: yAxisMax + } })); } catch (err) { console.error('Error in fetchData:', err); diff --git a/components/StatusMahasiswaFilterChart.tsx b/components/StatusMahasiswaFilterChart.tsx index db7c24c..14faa97 100644 --- a/components/StatusMahasiswaFilterChart.tsx +++ b/components/StatusMahasiswaFilterChart.tsx @@ -190,6 +190,23 @@ export default function StatusMahasiswaFilterChart({ selectedYear, selectedStatu const series = processSeriesData(); console.log('Processed series data:', series); + // Calculate the maximum value from all series for y-axis padding + const maxValue = Math.max( + ...series.flatMap(s => s.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + + // Update chart options with y-axis max + const updatedChartOptions: ApexOptions = { + ...chartOptions, + yaxis: { + ...chartOptions.yaxis, + max: yAxisMax + } + }; + if (loading) { return ( @@ -238,7 +255,7 @@ export default function StatusMahasiswaFilterChart({ selectedYear, selectedStatu
{typeof window !== 'undefined' && ( import('react-apexcharts'), { ssr: false }); interface TingkatPrestasiData { tahun_angkatan: number; - tingkat: string; + tingkat_prestasi: string; tingkat_mahasiswa_prestasi: number; } @@ -67,12 +67,12 @@ export default function TingkatPrestasiChart({ selectedJenisPrestasi }: Props) { if (!data.length) return []; const years = [...new Set(data.map(item => item.tahun_angkatan))].sort(); - const tingkatTypes = [...new Set(data.map(item => item.tingkat))].sort(); + const tingkatTypes = [...new Set(data.map(item => item.tingkat_prestasi))].sort(); return tingkatTypes.map(tingkat => ({ name: tingkat, data: years.map(year => { - const item = data.find(d => d.tahun_angkatan === year && d.tingkat === tingkat); + const item = data.find(d => d.tahun_angkatan === year && d.tingkat_prestasi === tingkat); return item?.tingkat_mahasiswa_prestasi || 0; }) })); @@ -202,6 +202,23 @@ export default function TingkatPrestasiChart({ selectedJenisPrestasi }: Props) { const series = processSeriesData(); + // Calculate the maximum value from all series for y-axis padding + const maxValue = Math.max( + ...series.flatMap(s => s.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + + // Update chart options with y-axis max + const updatedChartOptions: ApexOptions = { + ...chartOptions, + yaxis: { + ...chartOptions.yaxis, + max: yAxisMax + } + }; + if (loading) { return ( @@ -249,7 +266,7 @@ export default function TingkatPrestasiChart({ selectedJenisPrestasi }: Props) {
{typeof window !== 'undefined' && series.length > 0 && ( import('react-apexcharts'), { ssr: false }); interface TingkatPrestasiData { tahun_angkatan: number; - tingkat: string; + tingkat_prestasi: string; tingkat_mahasiswa_prestasi: number; } @@ -52,6 +52,23 @@ export default function TingkatPrestasiPieChart({ selectedYear, selectedJenisPre fetchData(); }, [selectedYear, selectedJenisPrestasi]); + // Process data for series + const processSeriesData = () => { + // Data sudah difilter dari API berdasarkan tahun angkatan dan jenis prestasi + // Langsung gunakan data yang diterima dari API + const tingkat = [...new Set(data.map(item => item.tingkat_prestasi))].sort(); + const jumlahData = tingkat.map(t => { + const item = data.find(d => d.tingkat_prestasi === t); + return item ? item.tingkat_mahasiswa_prestasi : 0; + }); + return { + series: jumlahData, + labels: tingkat + }; + }; + + const { series, labels } = processSeriesData(); + const chartOptions: ApexOptions = { chart: { type: 'pie', @@ -69,7 +86,7 @@ export default function TingkatPrestasiPieChart({ selectedYear, selectedJenisPre } } }, - labels: [], + labels: labels, colors: ['#3B82F6', '#10B981', '#F59E0B', '#EF4444', '#8B5CF6', '#EC4899', '#06B6D4'], legend: { position: 'bottom', @@ -110,23 +127,6 @@ export default function TingkatPrestasiPieChart({ selectedYear, selectedJenisPre } }; - // Process data for series - const processSeriesData = () => { - // Filter data sesuai tahun angkatan - const filtered = data.filter(item => String(item.tahun_angkatan) === String(selectedYear)); - const tingkat = [...new Set(filtered.map(item => item.tingkat))].sort(); - const jumlahData = tingkat.map(t => { - const item = filtered.find(d => d.tingkat === t); - return item ? item.tingkat_mahasiswa_prestasi : 0; - }); - return { - series: jumlahData, - labels: tingkat - }; - }; - - const { series, labels } = processSeriesData(); - if (loading) { return ( @@ -174,7 +174,7 @@ export default function TingkatPrestasiPieChart({ selectedYear, selectedJenisPre
{typeof window !== 'undefined' && ( s.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + + // Update chart options with y-axis max + const updatedChartOptions: ApexOptions = { + ...chartOptions, + yaxis: { + ...chartOptions.yaxis, + max: yAxisMax + } + }; + if (loading) { return ( @@ -263,7 +280,7 @@ export default function TotalBeasiswaChart({ selectedYear, selectedJenisBeasiswa
{typeof window !== 'undefined' && series.length > 0 && ( s.data) + ); + + // Add 20% padding to the maximum value + const yAxisMax = Math.ceil(maxValue * 1.2); + + // Update chart options with y-axis max + const updatedChartOptions: ApexOptions = { + ...chartOptions, + yaxis: { + ...chartOptions.yaxis, + max: yAxisMax + } + }; + if (loading) { return ( @@ -261,7 +278,7 @@ export default function TotalPrestasiChart({ selectedJenisPrestasi }: Props) {
{typeof window !== 'undefined' && series.length > 0 && (