import { NextResponse } from 'next/server'; import supabase from '@/lib/db'; interface MahasiswaTotal { total_mahasiswa: number; mahasiswa_aktif: number; total_lulus: number; pria_lulus: number; wanita_lulus: number; total_berprestasi: number; prestasi_akademik: number; prestasi_non_akademik: number; ipk_rata_rata_aktif: number; ipk_rata_rata_lulus: number; total_mahasiswa_aktif_lulus: number; } interface IPKData { nim: string; mahasiswa: { ipk: number; }; } // Fungsi untuk menangani preflight request (OPTIONS) export async function OPTIONS() { return new NextResponse(null, { status: 200, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', 'Access-Control-Max-Age': '86400', // 24 jam }, }); } export async function GET() { try { // Get total mahasiswa const { count: totalMahasiswa } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }); // Get mahasiswa aktif const { count: mahasiswaAktif } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) .eq('status_kuliah', 'Aktif'); // Get total lulus const { count: totalLulus } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) .eq('status_kuliah', 'Lulus'); // Get pria lulus const { count: priaLulus } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) .eq('status_kuliah', 'Lulus') .eq('jk', 'Pria'); // Get wanita lulus const { count: wanitaLulus } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) .eq('status_kuliah', 'Lulus') .eq('jk', 'Wanita'); // Get total berprestasi const { count: totalBerprestasi } = await supabase .from('prestasi_mahasiswa') .select('*', { count: 'exact', head: true }); // Get prestasi akademik const { count: prestasiAkademik } = await supabase .from('prestasi_mahasiswa') .select('*', { count: 'exact', head: true }) .eq('jenis_prestasi', 'Akademik'); // Get prestasi non-akademik const { count: prestasiNonAkademik } = await supabase .from('prestasi_mahasiswa') .select('*', { count: 'exact', head: true }) .eq('jenis_prestasi', 'Non-Akademik'); // Get total mahasiswa aktif + lulus const { count: totalMahasiswaAktifLulus } = await supabase .from('mahasiswa') .select('*', { count: 'exact', head: true }) .in('status_kuliah', ['Aktif', 'Lulus']); // Get IPK rata-rata aktif const { data: ipkAktifData } = await supabase .from('mahasiswa') .select('ipk') .eq('status_kuliah', 'Aktif') .not('ipk', 'is', null); const ipkRataRataAktif = ipkAktifData && ipkAktifData.length > 0 ? Math.round((ipkAktifData.reduce((sum, item: any) => sum + (item.ipk || 0), 0) / ipkAktifData.length) * 100) / 100 : 0; // Get IPK rata-rata lulus const { data: ipkLulusData } = await supabase .from('mahasiswa') .select('ipk') .eq('status_kuliah', 'Lulus') .not('ipk', 'is', null); const ipkRataRataLulus = ipkLulusData && ipkLulusData.length > 0 ? Math.round((ipkLulusData.reduce((sum, item: any) => sum + (item.ipk || 0), 0) / ipkLulusData.length) * 100) / 100 : 0; const results: MahasiswaTotal = { total_mahasiswa: totalMahasiswa || 0, mahasiswa_aktif: mahasiswaAktif || 0, total_lulus: totalLulus || 0, pria_lulus: priaLulus || 0, wanita_lulus: wanitaLulus || 0, total_berprestasi: totalBerprestasi || 0, prestasi_akademik: prestasiAkademik || 0, prestasi_non_akademik: prestasiNonAkademik || 0, ipk_rata_rata_aktif: ipkRataRataAktif, ipk_rata_rata_lulus: ipkRataRataLulus, total_mahasiswa_aktif_lulus: totalMahasiswaAktifLulus || 0, }; // Menambahkan header cache dan CORS return NextResponse.json(results, { headers: { 'Cache-Control': 'public, max-age=60, stale-while-revalidate=30', 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, }); } catch (error) { console.error('Error fetching total mahasiswa:', error); return NextResponse.json( { error: 'Failed to fetch total mahasiswa' }, { status: 500, headers: { 'Access-Control-Allow-Origin': '*', 'Access-Control-Allow-Methods': 'GET, OPTIONS', 'Access-Control-Allow-Headers': 'Content-Type, Authorization', }, } ); } }